先说明基础情况,我现在的电脑是澳洲买的行货,所以出厂预装的就是英文系统,默认字符集也是ANSI

然后运行某国产游戏的时候,我遇到了这样的显示

稍有常识的人都会看出,这是一个典型的字符集不同导致的文本解码异常,也就是俗称的锟斤拷问题
但是这个游戏是有英语的,我们试着切换到英语看看会发生什么

大部分文本显示正常了,但还是存在少量的方块,说明该游戏即使是英语该游戏也用到了不同字符集的字符,导致在英文系统上显示异常

该游戏使用kirikiri2引擎,查阅源码可知该引擎支持手动指定编码集
グラフィック:フォントキャラセット;フォントを生成する際に指定されるキャラセットの設定です。[cr][cr]デフォルトではSHIFTJIS_CHARSETが設定されています。ラテン文字のフォントが正常に表示されない場合など、DEFAULT_CHARSETに設定を切り替えることで表示が可能になることがあります。|fontcharset|select,0;ANSI_CHARSET,1;DEFAULT_CHARSET,2;SYMBOL_CHARSET,77;MAC_CHARSET,*128;SHIFTJIS_CHARSET,129;HANGEUL_CHARSET,130;JOHAB_CHARSET,134;GB2313_CHARSET,136;CHINESEBIG5_CHARSET,161;GREEK_CHARSET,162;TURKISH_CHARSET,177;HEBREW_CHARSET,178;ARABIC _CHARSET,186;BALTIC_CHARSET,204;RUSSIAN_CHARSET,222;THAI_CHARSET,238;EE_CHARSET,255;OEM_CHARSET
指定中文编码的指令为-fontcharset=136,尝试在powershell中如此启动游戏,文本显示正常了

那么我们试着把这行指令加入到steam的启动参数

却不能解决乱码问题

这是为什么呢?查阅steamdb,发现游戏默认启动指令就带有一个错误的改写编码集的指令。为什么说他是错误的呢,因为这个指令显然是误解了kirikiri2文档的人写出来的,翻阅源码可知kirikiri2解析启动指令的时候只能识别对应的key值而不能识别其说明值,DEFAULT_CHARSET对应值是2,所以写2才有用。并且DEFAULT_CHARSET本来就是kirikiri2的默认值,所以这个值如设,就算指令写对了也是屁用没有一点

而更糟糕的事情在于,kirikiri2接收到多个相同switch的指令时,取前者值,这就导致我们通过steam添加启动指令时实际传递的指令是 -fontcharset=DEFAULT_CHARSET -fontcharset=136,在取前值情况下,等于后加的指令白加了
所以为了让我们能通过steam便捷的使用目标指令启动游戏,我们有几个方案:修改该游戏steam启动配置文件的启动指令(但我不是开发者,我也不能黑进steam,无法实现),修改该游戏steam本地配置文件缓存的启动指令(每次清除下载缓存都会重置,且steam近日更新了vdf格式还没有可用的开源解析器,也几乎不可行),用%command%花活动态改写启动指令(非常可行)
%command%指令是steam启动指令里的一个特殊变量,如果存在该变量,那么steam执行时会把这个变量替换成原本的默认启动指令,该变量允许我们倒转exe路径到我们自定义启动方式的后面,最初添加该特性主要为了解决linux平台设置各种环境变量的烦恼
例如游戏原本启动指令是"D:/qinlili.exe -run",若设置自定义启动指令为"cmd /c %command% &pause",cmd /c D:/qinlili.exe -run &pause",这极大地丰富了我们自定义启动指令的操作空间
那么我们梳理一下需求,现在steam的默认启动指令是D:\PATH_TO\leaflet.exe -fontcharset=DEFAULT_CHARSET,我们想要的目标指令是D:\PATH_TO\leaflet.exe -fontcharset=136。并且我不想引入任何第三方依赖,要完全使用系统组件实现,怎么办?
不难注意到,powershell可以很轻松的完成这个任务,并且powershell是系统内置组件
易得如下启动指令,获取原始指令中错误字符集位置并裁剪,然后附加上正确的指令,其中反斜杠是为了解决steam对引号的处理
powershell -Command Start-Process -FilePath \"%command%\".Substring(0,\"%command%\".IndexOf(\"-fontcharset\")) -ArgumentList \"-fontcharset=136\"
启动游戏,问题完美解决

其实对于很多小团队制作的多语言游戏,都会存在这种因为字符集导致失败国际化的情况,归根到底问题出在缺少测试上。因为国内大多数电脑预装的都是单语言windows,大多数国内团队都不会测试英文系统下的实际运行情况,都是中文系统下游戏内英文能显示了就ok撒花了,根本没考虑到不同语言系统默认字符集不同。最终造成这种好像国际化了但实际上外国友人还是玩不了的问题。这个问题也不仅仅存在于国产游戏,我也有在其他非英文国家团队的游戏里见到这样的问题
所以要总结本文的话,我只想说一句话,少一些俺寻思,多一些脚踏实地的测试,测试永远是最有效的发现问题的办法。