GameMaker引擎游戏汉化(一)

最近沉迷于一款GameMaker引擎制作的游戏Circadian Dice,发行于Steam平台。游戏本身并没有中文,因此决定上手汉化一下。

GameMaker引擎
  • GameMaker是Yoyogames公司开发的一款2D游戏引擎。它拥有直观的图形界面和灵活的编程功能,使得游戏制作变得相对简单和直观。许多游戏制作爱好者和中小型独立游戏制作者,都利用GameMaker来创建自己的2D游戏作品。但由于其资源打包方式,制作的游戏对于汉化非常不友好。
  • GameMaker引擎按时间顺序分为GM8(GameMaker8.0)、GMS(GameMaker:Studio)和GMS2(GameMaker:Studio 2)三个版本,最新的GMS2在2022版本后重新更名为GameMaker。Circadian Dice是使用GameMaker 2023.1.0开发制作的,因此本篇文档所有内容均基于GameMaker 2023.1.0版本。
相关工具
  • UndertaleModTool(UTMT)
    一个专为GameMaker游戏爱好者设计的强大模组制作工具。它允许用户读取游戏的数据文件,还提供了对游戏内部数据的全面编辑功能。支持GMS1.4和GMS2,支持引擎数据版本 13-17。
    用于游戏资源解包和重新打包。
  • GameMaker
    引擎本体。
  • Ida64
    静态反汇编。
  • Cheat Engine
    动态反汇编。
  • UltraEdit
    二进制文件编辑。
解包资源
  • GameMaker游戏主要包含两个文件,exe程序和data.win,data.win即是打包的资源文件。
    使用UTMT打开游戏目录下data.win,打开时提示游戏使用YYC(YoYo Compiler),脚本被编译到可执行文件中,这也是游戏汉化困难的主要原因之一。

  • UTMT打开data.win后可以看见里面包括了图片、字体等资源,也包括脚本和文本,不过YYC模式下,脚本和文本只有名称,没有具体内容。

在这里插入图片描述

YYC模式
  • YYC是GameMaker提供的一种编译模式,可以提高程序运行效率。YYC模式下,生成的data.win中只包含资源(assets),而脚本和字符串被嵌入可执行文件中,所以汉化没法通过只修改data.win来完成,必须要编辑exe程序。
  • YYC模式本质上是GameMaker将GML(GameMaker Language)解释成C++代码后,再利用VS编译工具进行编译生成程序。

用GameMaker写个测试程序来了解一下GML中的字符串通过YYC编译生成的C++中间代码。
GameMaker中创建一个空白工程,然后Room1的初始化代码中加入一条语句test = “Hello World”,使用YYC模式编译生成。
生成完毕后,GameMaker会在临时目录生成一个C++工程,用VS打开生成的C++工程,在gml_Room_Room1_Create.gml.cpp文件中可以看见YYC编译生成C++中间代码。

#include "pch.hpp"
extern YYVAR g_Script_gml_Room_Room1_Create;
#ifndef __YYNODEFS
const char g_pString1_FB6412F6_s[] = {
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x00,                              // Hello World.
};
const YYRValue g_pString1_FB6412F6(g_pString1_FB6412F6_s, true);
#else
extern const char g_pString1_FB6412F6_s[];
extern const YYRValue g_pString1_FB6412F6;
#endif // __YYNODEFS

void gml_Room_Room1_Create( CInstance* pSelf, CInstance* pOther );
#ifndef __YYNODEFS
void gml_Room_Room1_Create( CInstance* pSelf, CInstance* pOther )
{
YY_STACKTRACE_FUNC_ENTRY( "gml_Room_Room1_Create", 0 );
YYGML_array_set_owner( (int64)(intptr_t)pSelf );


YY_STACKTRACE_LINE(1);
YYRValue* sWself_test = &((CInstanceBase*)pSelf)->GetYYVarRefL(kVARID_self_test); /* set ContextID to 1 */
(*sWself_test)=g_pString1_FB6412F6;
;
}
#endif
  • 很明显,字符串Hello World被存放到一个以0x00结尾的字节数组中(即C语言字符串存储格式),那意味着只要替换程序文件中对应数组内容就可以更改该字符串。
替换文本
  • 尝试替换游戏标题界面左下角版本号的文本 “Version 3.2.01”

在这里插入图片描述

用UltraEdit打开Circadian Dice.exe,搜索字符串“Version 3.2.01”。

00acc7e0h: 56 65 72 73 69 6F 6E 20 33 2E 30 2E 30 31 00 00 ; Version 3.0.01..
  • 可以看到,这就是一个存储对应字符串的字节数组,以0x00结尾,与前面C++中间代码相一致。

尝试改成"Hello World",不足位用0x00填充。

00acc7e0h: 48 65 6C 6C 6F 20 57 6F 72 6C 64 00 00 00 00 00 ; Hello World.....

保存后重新打开游戏程序,标题界面左下角版本号的文本更改成功。

在这里插入图片描述

总结
  • 是不是很简单?exe程序中搜索文本,然后替换,完成!
  • 别急,才刚上路,换成中文试试。
  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值