[多版本] 从简单到硬编码汉化,可翻译文本的实现教程。适于新手,也适于整合包作者。 - [CrT]CraftTweaker - MC百科
本地化
此部分内容讲述什么是本地化,如果你已了解过相关内容,可直接跳过
也许你听说过汉化国外模组,汉化国外整合包。而汉化中很重要的部分就是翻译资源(assets)中的语言(lang)文件,把其中的非中文内容翻译成属于我们的所熟悉的中文。这个过程我们可以称作“本地化”。对应的语言文件我们可以称作“本地化文件”。
MC语言文本的本地化文件以“json”作为数据交换格式,因此文件以“.json”为结尾。
以我的世界原版的en_us.json文件为例:
{ ……(省略一堆内容) "item.minecraft.apple": "Apple", ……(省略一堆内容)}"item.minectaft:apple"是“翻译键”,表示苹果这个物品的显示名称。
后面的"Apple"是翻译键所对应的“值”,表示苹果这个物品在游戏中显示为“Apple”。
无论是翻译键还是值,它们都由英文双引号或者英文单引号包起来。 两个组合在一起,中间加个英文冒号我们称作“键值对”。若干个键值对(包括那些被省略的内容)组合在一起,中间用英文逗号隔开,最外边用一对花括弧包起来,就构成了我们的语言文本的本地化文件。
美式英语有他们的语言本地化文件,我们简体中文也有我们的语言本地化文件zh_cn.json。这是因为不同地区使用不同的语言,对应的文本就存储在名称不同的本地化文件中。实际游戏中,系统会根据我们所选的语言,在与语言相匹配的本地化文件中寻找翻译键,然后将值显示出来。如果找不到要显示的翻译键,就会选择美式英语en_us.json文件中翻译键所对的值来显示。如果仍然找不到,就会显示直接显示翻译键。
这便是实现可翻译文本最核心的地方。
药剂环重铸模组的 美式英语本地化文件(左) 和 简体中文本地化文件(右)
资源包
此部分内容讲述如何用资源包实现汉化,如果你已了解过相关内容,可直接跳过
现在已经了解什么叫本地化,那么我们可以开始尝试使用资源包来实现汉化。资源包的结构以及制作流程在这里不会过多讲述。如果你想了解更多的细节,可以在模组百科、MCwiki、B站等上看,有很多优质的教程。这里给出MCwiki上的资源包制作教程。这里我们只讲述有关语言文本的部分。
首先,本地化文件应该放在这个地方:
<你的资源包> → assets(资源) → <命名空间>(例如minecraft,表示我的世界原版资源存放的地方) → lang(语言) → <本地化文件>(表示存储语言文本的文件)
本地化文件的名称我们就取作zh_cn.json,这就是我们简体中文的本地化文件。当然,以实现多语言为目的,意味着你应该创建多个语言对应的本地化文件。你可以用你电脑自带的记事本进行编辑。里面可以写上:
{ "item.minecraft.apple": "苹果物品的本地化示例"}这里只是一个例子,实际上,你应该写上那些还没翻译而只有英文的键值对,因为你是要实现汉化,而不是实现乱改物品显示名称,尽管确实可以实现。然后把你的资源包放进你游戏版本文件夹的resourcepacks文件夹里面,接着重新加载资源包。然后苹果物品的名称就会显示为“苹果物品的本地化示例”。
那么如何在游戏中获取只有英文文本的键值对呢?如果你装了JEI物品管理器模组,你可以尝试找到这个文件:
<游戏版本文件夹> → config(配置) → jeiintegration-client.toml(表示JEI客户端配置)
JEI客户端配置文件内容
同样可以用你电脑自带的记事本进行编辑,底下的有个translationKeyTooltipMode,等于号后面改成"enabled"。重启游戏之后物品上就会显示键值对。
不过这只适于物品的汉化,其他部分最好选择找到对应的模组文件(以“.jar”结尾),以压缩包的形式打开,然后同样找到:
<模组文件> → assets → <模组命名空间> → lang → <本地化文件>
通过对比en_us.json和zh_cn.json两个文件,我们就可以知道哪些键值对是未汉化的。许多模组其实是没有zh_cn.json文件的,这意味着如果你想要汉化,你就需要翻译en_us.json文件中所有的键值对,然后写进zh_cn.json文件中。
如果你嫌弃电脑自带的记事本不好用,你可以安装VS Code这一轻量的文本编辑器,可以提高汉化时的体验感。
CraftTweaker
有了前面的铺垫,我们总算可以开始开启今天真正的主题了
硬编码汉化
好吧,也许你会发现有些时候,即使你把en_us.json中所有能够翻译的键值对全部都翻译成了中文,装进了汉化资源包并且在游戏中启用了汉化资源包,也仍然会有一些物品的提示框还是英文的。通常来说,这是因为这部分文字是被“硬编码”进了游戏中,而非通过翻译键进行显示。通俗地讲,就是文字被写死在程序里面了,因而而无法仅通过资源包来本地化。
这个时候怎么办呢?我们可以请出一位从MC1.6.4奋战到至今仍顽强不屈的资深修改模组——CraftTweaker(曾名MineTweaker)。它允许我们使用ZenScript(一种编程语言)来编写代码,从而修改游戏中物品的提示框(tooltip)。
不会敲代码也没关系,跟着本教程的步骤走,你也能学会。
例子:更多熔炉中的链接器汉化
这里以汉化更多熔炉中的熔炉配置链接器为例子,,具体步骤如下:
1、安装CraftTweaker模组并启动游戏。
2、在游戏里面找到我们想要翻译的物品。
更多熔炉模组中,熔炉配置链接器提示框中的部分文本被硬编码为英文
3、然后在聊天框中输入命令/ct hand,接着鼠标点击复制来获取这个物品。
/ct hand
注意!看清楚你复制的,应该是物品,不是方块,也不是方块状态,更不是什么标签!
4、在游戏版本文件夹中的scripts(脚本)文件夹里面,新建文本文件,名字你随便取。最后要把文件末尾的“.txt”修改为“.zs”。用记事本(或者前面说的VSCode)打开。
5、在里面粘贴你复制到的<物品>,然后在它加上“.removeTooltip( "文字" );”,这样会删掉物品提示框包含“文字”的那一行文本。以图中的物品为例:
6、再写几行代码“<物品>.addTooltip( "文字" );”,这样就可以为物品提示框添加新的文本。仍以图中的物品为例:
7、保存.zs文件,然后在游戏中输入命令进行重载。
/reload
游戏重载后,熔炉配置链接器提示框中的文本变为了中文
8、这里有一个需要注意的点。如果这个物品是有耐久的,你需要在<物品>的后面再加上“ .anyDamage()”、,表示忽略物品的耐久。不然物品稍微掉一点耐久,描述就又变回去了。你应该像这样做:
这个汉化方法参考至模组百科中的另一篇教程《关于模组武器道具描述的汉化》,里面讲的内容更多更详细。这里只展示出其中的核心,有很多细节在那篇教程中有讲,如果此教程你看不懂,也可以去看上面这个。
有细心的同学应该发现了,这提示框文本不还是写死在代码里面吗?没错,我们刚才所做的,其实就是用硬编码的中文文本,强行替换了原本硬编码的英文文本,是在“用魔法打败魔法”。我们实际上并没有从根源上解决问题。
可翻译文本
彻底解决硬编码问题,关键在于把硬编码改成翻译键
警告:接下来的部分涉及到大量CraftTweaker的语法知识。如果你未接触过相关的知识,你会感到一头雾水。因此请尽量尝试理解教程中的知识,或是学习模组百科上的基础教程《可能最全!1.12.2 CrT 基础合集》。如果你有问题,可以留言进行提问。
尽管我们最终的结果仍然是硬编码中文,但我们确实有办法删除物品中硬编码的文本 。只是我们没有将硬编码文本替换成可以用资源包本地化的文本。那我们有办法获取资源包的本地化文本吗?
有的兄弟,有的,办法就是我们在前文所学到的翻译键,把我们的硬编码中文换成翻译键就可以了。
听上去很简单,但实际上有个很大的问题。不同版本的CraftTweaker模组,它所提供的“方法”不同,编者很难教会大家所有版本的。因此编者只总结了目前主流版本的1.12.2、1.16.5、1.18.2、1.20.1。
例子:暮色森林的禁用拆解提示
下面先以编者所用的版本1.18.2为例子,讲解具体的代码实现,在结尾放上其他版本所使用的“方法”。编者这边启用了暮色森林的拆解台的禁用拆解功能,想为拆解台提示框添加可以本地化的文本。
在拆解台界面中,查看拆解台物品,其提示框中没有额外的文本
1、我们先要在脚本文件(以.zs结尾的文件,可在旧文件中添加代码,或新建一个)的开头加上下面这句代码。
//导入可翻译组件类,里面包含了通过翻译键获取语言文本的“方法”import crafttweaker.api.text.TranslatableComponent;注释中提到的“类”(class)是CraftTweaker模组为我们提供的一个大类别,里面有很多有用的“方法”(Method)可以给我们使用。前面所用到的“.addTooltip( "文字" )”就是<物品>类中所具有的方法。而可翻译组件类的方法,需要我们在脚本(.zs)文件的开头进行“导入”(import),之后才可以使用。
2、接着我们加行代码,要用到“new TranslatableComponent("<翻译键>")”来获取翻译键。
//创建一个可翻译组件,存进comp变量中var comp = new TranslatableComponent("container.uncrafting_table.disabled");下面的代码中,“var …… = ……”是一个定义变量的语句,它会创建一个叫做“变量”的东西,帮我们存储等号右边省略号的内容。等号左边省略号是变量的名称。你可以随便取,保证它是一个用字母、数字、下划线组成的英文单词就行。而“container.uncrafting_table.disabled”是暮色森林本地化文件中自带的一个翻译键,简体中文下对应的值是“拆解功能不可用!”。你可以换成任何翻译键,包括你自己无中生有的翻译键,只要它存在于模组资源中的本地化文件里,或者存在于你制作的汉化资源包中的本地化文件里。
“new TranslatableComponent("<翻译键>")”的这整个我们称作“构造函数”,其中“new”表示新的。这整句就表示,根据指定的翻译键来创建一个新的可翻译组件。
3、最后我们再加几行代码,要用到“<可翻译文本组件>.getString()”方法,这里再次使用了定义变量,提示框文本的添加方式在前文也有讲过:
var text = comp.getString(); //把可翻译组件转换成文本,存进text变量中
4、最后记得在游戏中输入命令/reload进行重载:
/reload
使用/reload进行重载之后,拆解台提示框中出现了额外的文本
5、如果你熟悉CraftTweaker的语法规则,你就会明白,变量是不必要的。它只是为了代码的可读性。如果你不理解变量是什么,你完全可以直接用上述提到的“方法”,替换所有出现的变量。这与上面的代码等价。就像这样:
import crafttweaker.api.text.TranslatableComponent; //可翻译组件类,包含通过翻译键获取语言文本的“方法”
多版本总结
以上就是1.18.2版本,用CraftTweaker添加翻译键的办法来实现可翻译文本。对于其他主流版本,会用到不同的类和及其构造函数、方法、属性(你可以理解为类里面的变量,修改方式也和变量相同,前面也有提到,用等于号接要存储的内容)。它们叫法不同,用法不太相同,但是实现逻辑是差不多的。这里我把可能会用到的内容以及链接都一起列在这里(只是可能,实际上可能用不到,或者会用到这里没有的。看你选择):
MC版本导入类构造函数、方法、属性功能1.20.1import crafttweaker.api.text.content.type.TranslatableContents;TranslatableContents.empty( );创建一个<可翻译内容><可翻译内容>.key<可翻译内容>中存储着键的属性import crafttweaker.api.text.Component;Component.keybind(<键名>);用键名创建一个<组件><组件>.contents<组件>中存储着可翻译内容的属性<组件>.getString( )将<组件>转换成文本1.18.2import crafttweaker.api.text.TranslatableComponent;new TranslatableComponent("<翻译键>")用翻译键创建一个<可翻译组件> <可翻译组件>.getString( )将<可翻译组件>转换成文本1.16.5import crafttweaker.api.util.text.MCTextComponent;MCTextComponent.createTranslationTextComponent("<翻译键>")用翻译键创建一个
如果到目前为止,你已经理解并成功在游戏中给物品提示框添加了文本。那么恭喜你,你已经学会了如何实现可翻译文本。事实上,可翻译文本不仅可以用在提示框文本上。理论上说,游戏中那些物品、方块、实体、容器、进度、字幕、JEI物品管理器、WTHIT( 或Jade )高亮物品提示等等能出现文本的地方,你应该都可以用上可翻译文本。
链接总结
在这里再次列出所有引用过的教程,以及其他可能有用的教程。编者也是从这些教程一点点学习到的,希望对你有所帮助:
MCwiki上的资源包制作教程《教程:制作资源包》
MCwiki上的语言资源包教程《教程:制作资源包/语言和文本》
模组百科上的硬编码汉化教程《关于模组武器道具描述的汉化》
模组百科上的CraftTweaker基础语法教程《可能最全!1.12.2 CrT 基础合集》
CraftTweaker的1.12.2官方文档《Home - CraftTweaker Documentation》
CraftTweaker的1.18.2官方文档《Home - CraftTweaker Documentation》
可翻译文本的意义
有同学可能会问,可翻译文本有什么意义呢?我直接汉化不好吗?
直接汉化当然没问题。但如果在海内外发布整合包,一般来说,文本只有中文是不够的。对于整合包作者而言,有时并非要实现硬编码汉化,而是要为某个物品、某个事件、某个进度添加额外的信息。但为多门语言写专门的代码,是非常消耗精力的;而对于本地化团队(包括国内的汉化团队和国外的本地化团队)来说,将这些硬编码信息本地化,是比将物品名称本地化困难得多的,大概率也要像同学们解决硬编码汉化一样。
如果在制作整合包的时候,我们就将硬编码文本改成可翻译的文本,就可以在后期省下非常多的力气。如果我们想要修改文本,也不用专门扒开代码来修改。对于不懂代码的本地化团队来说,也能较轻松地实现本地化,岂不两全其美?