跳至正文

让你的Mod变得”国际化” – 模组本地化指南

前言

传统情况下,TMod创建文本的方式一般为硬编码或使用.lang文件,而前者不利于翻译的进行,后者的普及率较低。在最近的更新中,tModLoader提供了以hjson支持国际化的方式,让Mod的翻译与多语言支持变得更加便捷。然而,这方面的指南较为稀缺,因此我编写了这篇教程,希望能够有所帮助。

hjson文件

基础

tModLoader使用hjson文件存储翻译文本。hjson的格式与json基本相同,但是有一些区别:

  1. hjson不需要在项间添加逗号。
  2. hjson不需要在字符串两端添加引号。
  3. hjson可以使用注释。
  4. hjson支持以 ”’ 包裹的多行字符串。
  5. hjson不需要在最外层添加大括号。

例如,对于

{
    "Root": {
           "First": {
            "A": "一",
            "B": "Two Second"
        },
        "The Second": {
            "C":"Three\nThird"
        }
    }
}

的json,在hjson中可以写为

Root:{
    First: {
        A: 一 //单行注释
        B: Two Second  # 还是单行注释
    }
    /*
        多行
        注释
    */
    "The Second": {
        C:
        '''
        Three
        Third
        '''
    }
}

更全面的介绍请参照这里

另外,上述结构的树状结构为

额外语法

此外,tModLoader中的hjson还支持颜色与引用。

如果需要编写彩色文本,可以使用 [c/16位颜色代码:字符串] 的格式。例如,

普通文本[c/FF0000:红色文本]普通文本

这样的文本会显示为

普通文本红色文本普通文本


引用的语法为 {$路径} 。例如,在上述例子中,{$Root.First.B} 相当于 Two Second

引用的效果可以随着自动改变。例如,如果一个名叫Mods.MyMod.Common.Key的项在en-US.hjson中为 English ,在zn-Hans.hjson中为 中文 ,那么,当语言选择为中文时 {$Mods.MyMod.Common.Key} 将会显示为 中文 ,而在选择英文时将会显示为English

因此,为了减少自己与翻译者的重复操作,建议尽可能多地使用引用。

在Mod中使用语言文本

注意: 此章节适用于1.4.0.1~1.4.3.6的tModLoader, tML在1.4.4采用了不同的方法, 参见Wiki的本地化指南

目录结构

在制作Mod时,语言文本需要放置在 Mod根目录\Localization 中,文件名为 语言代码.hjson

例如,名叫 MyMod 的Mod中,中文语言文件的路径为 MyMod\Localization\zh_Hans.hjson

文件结构

在hjson文件中,最外的两层结构是ModsMODID (MODID换为自己的) 。

Mods: {
    MODID: {
        
    }
}

自动使用

tModLoader会自动注册一些常用的文本,这意味着在使用时不需要添加额外代码。

默认情况下,tModLoader会自动注册ItemName, ItemTooltip, BuffName, BuffDescription, ProjectileName, NPCName, MapObject, Prefix等,它们均在hjson文件的第三层。

其中的子项应均为字符串,键为对应的类名,值为需显示的文本。

例如,注册Mod名叫 MyMod ,类名叫 MyItem , 显示为 我的物品 的物品的方式如下:

Mods: {
    MyMod: {
        ItemName: {
            MyItem: 我的物品
        }
  }
}

此时,需保证 MyItem 类中 SetStaticDefaults 方法里没有 DisplayName.SetDefault ,否则将无法使用默认引用。

此外,tModLoader还会自动注册其它的一些文本。若需要知道更全面的内容,可以查阅这里

使用Terraria的原生方法

如果要在tModLoader没有自动注册的地方使用语言文本,则需要手动使用。在简单的情境中,Terraria提供了原生的调用方法。

对于字符串常量,只需将原始的字符串替换为 Language.GetTextValue(路径) 即可。(这个方法在Terraria.Localization内)

路径的第一层为 Mods ,用 . 分割。

例如,对于上述例子,若不希望使用tModLoader的自动注册功能,可以将

DisplayName.SetDefault("我的物品");

修改为

DisplayName.SetDefault(Language.GetTextValue("Mods.MyItem.ItemName.MyItem"));

这个方式可以对任意字符串生效。

tModLoader提供的方法

tModLoader额外提供了 LocalizationLoader 类与 ModTranslation 类以更灵活地创建语言文本。这两个类均在Terraria.ModLoader中。

这两个类的目的并非更改调用语言文本的方式,而是提供动态创建语言文本的方式。因此,在调用语言文本时,仍需要使用Terraria的内置方法。

LocalizationLoader

这个类提供了GetOrCreateTranslationAddTranslation方法,用于创建与使用ModTranslation对象。

其中,第一个有两个重载:

    GetOrCreateTranslation (Mod mod, string key)

    GetOrCreateTranslation (string key)

前者相当于将key替换为Mods.{mod.Name}.{key}.

例如,对上述例子,使用前者时为

    GetOrCreateTranslation(MyMod,"ItemName.MyItem")

后者则为

    GetOrCreateTranslation("Mods.MyMod.ItemName.MyItem")

这个方法返回一个ModTranslation对象。

第二个只有 AddTranslation(ModTranslation translation) 一个形式,作用是注册该对象,以便后续使用。

ModTranslation

这个类用于加载与修改语言文本,较为常用的方法为

    AddTranslation(GameCulture culture,String value)

    GetTranslation(GameCulture culture)

其中,GameCulture为一个集合类,在Terraria.Localization中。可使用对应语言的编号(int类型)或名称(String类型)替换。

前者没有返回值,后者会返回一个String对象。这两个方法的用法均十分明显,在这里不再赘述。

此外,它还有 SetDefault(string value)GetDefault() 方法,相当于上述两个方法中culture设置为英文。

常用使用方法

在使用时,一般将两个类搭配使用。

  1. 首先,使用GetOrCreateTranslation创建ModTranslation对象。
  2. 然后,调用(与Language.GetTextValue搭配)或修改(使用AddTranslation方法)该对象。
  3. 最后,如果进行修改,需要使用LocalizationLoader.AddTranslation方法注册。

例如,仍对于上述例子,在修改时为:

ModTranslation t = LocalizationLoader.GetOrCreateTranslation(MyMod, "ItemName.MyItem");
t.AddTranslation((int)GameCulture.CultureName.Chinese, "新的名称");
LocalizationLoader.AddTranslation(t);

在调用时为

ModTranslation t = LocalizationLoader.GetOrCreateTranslation(MyMod, "ItemName.MyItem");
String str=Language.GetTextValue(t.GetTranslation((int)GameCulture.CultureName.Chinese));
//使用str

可能会遇到的问题

有时,在更新语言文件并再次生成后,游戏内的文本并没有更新。这时候,只需重新生成一次即可解决。

值得注意的时,中文的语言文件并非zh-CN.hjson,而是zh-Hans.hjson

后记

与Minecraft Mod中方便的多语言支持相比,Terraria Mod的国际化长久以来都是一个问题。目前,汉化者Mod仍未更新到1.4(很有可能不会更新),很多Mod都仅有一个语言,或者硬编码了多个语言;在支持hjson后,逐渐出现了许多汉化Mod,才缓解了这一问题。虽然在自己的Mod中支持国际化无法直接促进Mod的汉化,但无论时从让自己的Mod更加完善,还是提高hjson的使用率上看,这对tMod的发展都是有益的。

发表回复