langfile格式
OpenTTD 开发文档
外部链接

OpenTTD GitHub
为 OpenTTD 贡献代码 - 准则
OpenTTD Doxygen

通用参考

代码风格(en)
编译OpenTTD(en)
调试(en)
添加设置(en)
Add a squirrel function
Understanding the SaveGame handler
Bumping the savegame version
发布 OpenTTD(en)

语言和字符串

风格指南(en)
langfile 格式
使用 OpenTTD 字符串(en)
特殊字符串列表(en)

窗口系统

窗口系统的使用(en)
Colour codes that exist in OpenTTD
添加文本框(en)
Understanding the widget focus system
GUI风格指南(en)

多人游戏

OpenTTD TCP 协议(en)
OpenTTD UDP 协议(en)
不同步问题的调试(en)
服务器管理端口开发(en)

游戏内控制台

控制台窗口
控制台命令
控制台变量
Using console scripting
Adding functions/commands to the console
Adding variables to the console
控制台开发纪事(en)

Content APIs (mod 开发框架)

图形相关(NewGRF)
AI 框架 (NoAI)
GameScript 框架(NoGO)
Social Integration

其他引用

Map array (landscape grid)
车辆(en)
寻路(en)
Train acceleration
Sound IDs

Contents

概述

请注意该内容属于开发指南的一部分。要简单的将 OpenTTD 翻译为其他语言,使用线上翻译工具

编译lang文件

/File/en/Outdated content.png
过时信息
此页面的部分内容已经过时。由于游戏内容的更新,部分内容的描述可能不再准确,请及时对此页面内容进行更新。
该内容指向了一个包含过时信息的链接(给出的strgen下载链接已经不可用)

OpenTTD 在 GitHub 的文档中提供了一个 lang文件编译指南(en)

/File/en/UnderConstructionOrange.png
尚未完成
请注意,此页面的内容尚不完全,因为仍在撰写中。

2024-12-17更新:

  1. 截至 2024 年 12 月 17 日,要将 openTTD 的语言文件编译成 .lng 文件,需要使用源码中包含的 strgen 工具。
  2. 要使用 strgen 工具,首先要在电脑上搭建 OpenTTD 的编译环境(C++)后单独编译 strgen,可以参考 OpenTTD GitHub 编译文档

这是在Windows环境下的过程:

  1. 安装 C++(可以下个 Visual Studio 2022 社区版)、CMake 和 vcpkg
  2. 配置好环境变量,确保命令行能够识别 cmake、vcpkg 等命令。

总体设计

langfile 中,每一行就是一个词条。

词条可以是一个 comment, 是一个pragma 或是一个 translation.

如果你使用在线翻译工具,你只能看到翻译。

编码统一为 UTF-8。

注释

注释以一个及两个以上的井号(#)或半角分号(;)开头。除了注释内容以外,空白行也会被忽略。

# 内容忽略
#### 会忽略这行
;这行也会被忽略

预处理指令(Pragmas)

预处理指令以两个井号(#)开头。下面的列表给出了所有可用的预处理指令:

名称 功能
name 名称 语言名称的英文形式
ownname 名称 语言名称的母语形式
isocode 具体代码 语言的 ISO 代码 (比如 zh_CN)
plural 数字 复数形式的类型 (代码在后面列出)
gender 最多 8 种单词阴阳性名称 定义可使用的单词阴阳性列表
case 最多50种格名称 定义可使用的格(语言学的格,比如主格、所有格之类的)
textdir ltr 或 rtl 文本排列顺序 (ltr就是"从左到右",而rtl就是"从右到左",如希伯来语或阿拉伯语)
digitsep 符号 非货币数字的分隔符,也叫"千位分隔符thousand separator"
digitsepcur 符号 用于表示货币数字的分隔符
decimalsep 符号 表示小数的分隔符
winlangid 十六进制数 Microsoft Windows® 使用的语言标识符
grflangid 十六进制数 GRF 使用的语言标识符
id 十六进制数 下一个字符串id,以十六进制数开头

复数类型表

下表列出了有关如何形成复数的允许的代码值:

代码值 描述
用途
0 两种形式,只有 1 使用单数形式
Danish, Dutch, English, German, Norwegian, Swedish, Estonian, Finnish, Greek, Hebrew, Italian, Portuguese, Spanish, Esperanto
1 只有一种形式
Hungarian, Japanese, Turkish, Chinese
2 两种形式,0 和 1 使用单数形式
French, Brazilian Portuguese
3 三种形式,0为特殊格
Latvian
4 Three forms, special case for one and two
Gaelige (Irish)
5 Three forms, special case for numbers ending in 1[2-9]
Lithuanian
6 Three forms, special cases for numbers ending in 1 and 2, 3, 4, except those ending in 1[1-4]
Croatian, Czech, Russian, Slovak, Ukrainian
7 Three forms, special case for one and numbers ending in 2, 3, or 4, except those ending in 1[2-4]
Polish
8 Four forms, special case for one and all numbers ending in 02, 03, or 04
Slovanian
11 Two forms, special case for all ending 0, 1, 3, 6, 7, 8. This is not an actual plural but to implement korean postpositions
Korean

示例

基准语言文件english.txt的开头包含下列预处理指令:

##name English (UK)
##ownname English (UK)
##isocode en_GB
##plural 0
##textdir ltr
;...
##id 0x0000

翻译

翻译由键和译文组成。用冒号隔开(:)。

键只能包含大写字母、数字和下划线(_)。每个键都以"STR_"开头,后面接单个或多个描述性词语。

STR_MAPSIZE
STR_000F_PASSENGERS
STR_SORT_BY_DATE
STR_0196_SHOW_LAND_OWNERS_ON_MAP

译文

译文中使用大括号 {},表示插入特殊指令,这些指令会被 strgen 编译时或显示在屏幕上时被替换。For a full list of commands is available at Special Strings. Besides

{STRINGx}

and

{RAW_STRING}

it is recommended to leave those special strings untouched by default. The special commands may substitute values or other strings at where the Special Strings are placed. Translators may have influence on the sequence of these replacements to allow a fluent language.

更改语序

Parameter replacements can be made swappable too. This will allow one parameter that is usually at position 0 (as in : the first one ) in the translated string to be used in fact at position 1, thus swapping place with no 1.

举个例子: STR_INDUSTRY_PROD_GOUP。

在英文中,译文为"{BLACK}{BIGFONT}{STRING} production at {INDUSTRY} increases {COMMA}%!"

在芬兰文中,译文则变为"{BLACK}{BIGFONT}{1:INDUSTRY} tuottaa {0:STRING} {2:COMMA}{NBSP}% entistä enemmän!"

/File/en/Klipper.png
To Do
Finish and correct this

每一个键后面可以加上点(.)然后接格后缀。格必须在文件开头使用预处理指令 ##case 进行定义。

在下面的捷克语文件中,你将明白如何定义格。捷克语有 7 种格,and there is an extra "case" for capitalizing cargo name in the Subsidies dialog.

##case nom gen dat acc voc loc ins big
STR_0011_MAIL                      :pošta
STR_0011_MAIL.big                  :Pošta
STR_0011_MAIL.gen                  :pošty

The generic usage of cases is to append a period and the case name to the STRING command. In the paragraph "Dotace dopravy {STRING.gen} z{NBSP}{STRING} do {STRING} nebude dále nabízena." a genitive case is necessary.

STR_202E_OFFER_OF_SUBSIDY_EXPIRED  :{BLACK}{BIGFONT}Nabídka dotace přepravy vypršela:{}{}Dotace dopravy {STRING.gen} z{NBSP}{STRING} do {STRING} nebude dále nabízena.
STR_2027_FROM_TO                   :{ORANGE}{STRING.big} z {STRING} do {STRING}

Plural form

Introduction

In most languages singular and plural forms are a bit different. Every word may be divided into two parts - one part does not change in both singular and plural form, but the second part differs in singular and plural. Let's call them core and suffix.

Let's take basic example in English language, which is basic because it has two forms: singular and plural.

There is "1 train", but there are "2 trains".

Now, let's divide this word into part that does not change and part that changes:

Writing the string

As I said before, there are two forms in English language.

The basic structure for plural form in English is

core{P suffix1 suffix2}

where suffix1 is suffix for signular and suffix2 is suffix for plural.

Keep in mind, that plural forms work only if there is proper parameter in the string.

{COMMA} and {NUM}, along with other numeric params work well in determining plural form.

Let's make a string that displays number of lamps in the room. Form of "lamp" would depend on supplied amount via {NUM} parameter.

Example

STR_SENTENCE : I have {NUM} lamp{P "" s}

Do you see the core? Yes, it is the word lamp.

Later you see {P. This is the indicator that suffixes will come next.

"" means there is no suffix. OpenTTD needs to know that - If there is no suffix, just write two quotation marks. So this is the first suffix, which will be used when {NUM} is equal to 1

s is the second suffix. This one will be displayed when {NUM} is bigger than 1.

Let's proceed to more advanced plural forms. Let's take mouse. Its plural form is mice.

First of all, imagine the sentence with different parameters.

When you are ready, you can write the string.

STR_SENTENCE : Mum, there {P 0 is are} {NUM} m{P ouse ice} in the room!

As you may have noticed, the first {P contains an extra number before the suffixes. This is used to specify which parameter should be used to determine the plural form. When no number is given, the previous parameter is used, but in this case there is no previous parameter, that's why we need to specify it.

/File/en/Klipper.png
To Do
check if it is not wrong

Mind that the singluar (1) is special in this plural definition. The plural form is used for all numbers >1 but also for 0. (Mum, there are 0 mice in the room).

String as number

If the argument that affects a plural form is given as {STRING} then you need to use a special parameter for {P:

Flat area around industries: {ORANGE}{STRING} tile{P 0:1 "" s}

OpenTTD usage

Now you understand basics of plural forms. Let's take some example from English translation.

STR_QUANTITY_LIVESTOCK : {COMMA} item{P "" s} of livestock

This text is being displayed at stations when there is livestock cargo awaiting.

As you can see, {COMMA} parameter is given. Thanks to that parameter, we can change form of item. Let's see how the string would change when we change supplied parameter.

Now let's take a look at string without given parameter.

STR_WAGONS : Wagons

No plural form may be applied here. Wagon{P "" s} will not work here.

Why? Because there is no parameter given.

You can just leave this string as it is.

Other plural types

Find your language on List of plural-types table below. Languages are being groupped depending on behaviour of words with different amounts.

Suffixes are being ordered ascending, with any other number at end:

Let's take Polish language and invent some dummy string

STR_CARS : {NUM} aut{P o a ""}

Now take a look at description above, and guess how would the string look for {NUM} equal to 1, 2, 5, 13, 23, 38?

Genders

Introduction

Some languages feature genders. Each noun (like factory, calculator, dragon) has its gender. Adjectives (green, new, beautiful) and sometimes verbs (to fall, to eat) are being affected by gender.

First of all, think of your language's gender. Then, open the Web Translator 2, go to "Manage" page of your language and check the dropdown list of genders. If there are no genders yet, hit "+" button and supply short forms of your genders (m f n for male female neutral is good).

When you've done this, think of strings in OpenTTD that may require genders. News report that new industry is being founded is good, because industry is a noun and some words in the string should change depending on gender.

Writing the string

To set string's gender, insert {G=*} tag before first word of the string, where * is name of the gender you sent before.

In the string that may change depending on genders, use {G suffix1 suffix2 suffix3} structure, where each suffix corresponds to the right gender (gender order is in the "Manage" section of your language, in the dropdown list)

Example

I'll use The Latin language in examples, because it is well-known, and of course, uses genders.

Latin language has three genders, we will call them m, f and n.

Let's guess some nouns we will use in examples.

Let's take some adjective and find its core and suffixes:

magnus, magna, magnum - large (male, female, neutral)

As you can see, magn is the core, and suffixes are us, a and um respectively for male, female and neutral gender.

And this is how would the example string work:

STR_WELL : {G=m}Puteus
STR_FACTORY : {G=f}Officina
STR_SQUARE : {G=n}Forum
STR_IS_BIG : {STRING} magn{G us a um} est

Do you imagine how will the result look like? Here is the answer:

Again, as with plural form, if there is no suffix, write "". Use always as many suffixes as there are genders.

/File/en/Klipper.png
To Do
How about the order of the suffixes? Do you have to use the same order as defined in the pragma?

Advanced use

{G...} tag bases on gender of {STRING} after the tag. However, if you need to change suffix of a word which is after {STRING} (before tag), you have to write ID of string you want to retrieve gender from. This may sound clumsy, so let's take a look at example:

{BLACK}{BIGFONT}Now{G y a e} {STRING} został{G "" a o} posadzon{G y a e} blisko {TOWN}!

Second and third {G...} will not work, because there is no {STRING} after them to get gender from.

We want to retrieve gender from first (and the only one) {STRING} tag. First tag has ID=0, second tag has ID=1 and so on. Here is how to do that:

{BLACK}{BIGFONT}Now{G y a e} {STRING} został{G 0 "" a o} posadzon{G 0 y a e} blisko {TOWN}!

Adding IDs resolved the problem. The string works as expected.

What if there are more {STRING}s? (

/File/en/Klipper.png
To Do
I'm not sure, please verify this

) In the following example we use two genders: male and female

Mis{G ter s} {STRING} is shocked by h{G 0 is er} grand{G 2 son daughter} who flamed mis{G ter s} {STRING} yesterday. The bad {G boy girl}'s name is {STRING}

Now I'll explain why some {G...}'s have numbers and other do not:

/File/en/Klipper.png
To Do
this section may be clumsy, feel free to improve it