Difference between revisions of "NML:Language files"
Andythenorth (talk | contribs) |
|||
(18 intermediate revisions by 8 users not shown) | |||
Line 37: | Line 37: | ||
!Example |
!Example |
||
|- |
|- |
||
− | | ||empty tag, written as {} is used to create a newline |
+ | | ||empty tag, written as {} is used to create a newline || |
|- |
|- |
||
− | |NBSP || non-breaking space |
+ | |NBSP || non-breaking space || |
|- |
|- |
||
− | |{ || Display a left curly bracket. You write this as {{}. If you'd include it without surrounding it by { and } it'd be seen as the start of a tag and the rest of the string would be read as name of the tag. |
+ | |{ || Display a left curly bracket. You write this as {{}. If you'd include it without surrounding it by { and } it'd be seen as the start of a tag and the rest of the string would be read as name of the tag. || |
|- |
|- |
||
− | |COPYRIGHT || copyright symbol || © |
+ | |COPYRIGHT || copyright symbol || © |
|- |
|- |
||
− | |TRAIN || display train symbol |
+ | |TRAIN || display train symbol || |
|- |
|- |
||
− | |LORRY || display lorry symbol |
+ | |LORRY || display lorry symbol || |
|- |
|- |
||
− | |BUS || display bus symbol |
+ | |BUS || display bus symbol || |
|- |
|- |
||
− | |PLANE || display plane symbol |
+ | |PLANE || display plane symbol || |
|- |
|- |
||
− | |SHIP || display ship symbol |
+ | |SHIP || display ship symbol || |
|- |
|- |
||
− | |TINYFONT || switch to small font |
+ | |TINYFONT || switch to small font || |
|- |
|- |
||
− | |BIGFONT || switch to big font |
+ | |BIGFONT || switch to big font || |
|- |
|- |
||
− | |BLUE || switch to blue text |
+ | |BLUE || switch to blue text || <div style="background:#3890E8;width:2em;"> </div> |
|- |
|- |
||
− | |SILVER || switch to silver text |
+ | |SILVER || switch to silver text || <div style="background:#C8C8C8;width:2em;"> </div> |
|- |
|- |
||
− | |GOLD || switch to golden text |
+ | |GOLD || switch to golden text || <div style="background:#FCC000;width:2em;"> </div> |
|- |
|- |
||
− | |RED || switch to red text |
+ | |RED || switch to red text || <div style="background:#FC0000;width:2em;"> </div> |
|- |
|- |
||
− | |PURPLE || switch to purple text |
+ | |PURPLE || switch to purple text || <div style="background:#A888E0;width:2em;"> </div> |
|- |
|- |
||
− | |LTBROWN || switch to light brown text |
+ | |LTBROWN || switch to light brown text || <div style="background:#B0B084;width:2em;"> </div> |
|- |
|- |
||
− | |ORANGE || switch to orange text |
+ | |ORANGE || switch to orange text || <div style="background:#FCB030;width:2em;"> </div> |
|- |
|- |
||
− | |GREEN || switch to green text |
+ | |GREEN || switch to green text || <div style="background:#90E05C;width:2em;"> </div> |
|- |
|- |
||
− | |YELLOW || switch to yellow text |
+ | |YELLOW || switch to yellow text || <div style="background:#FCF880;width:2em;"> </div> |
|- |
|- |
||
− | |DKGREEN || switch to dark green text |
+ | |DKGREEN || switch to dark green text || <div style="background:#B4CC7C;width:2em;"> </div> |
|- |
|- |
||
− | |CREAM || switch to cream-coloured text |
+ | |CREAM || switch to cream-coloured text || <div style="background:#D49480;width:2em;"> </div> |
|- |
|- |
||
− | |BROWN || switch to brown text |
+ | |BROWN || switch to brown text || <div style="background:#A46040;width:2em;"> </div> |
|- |
|- |
||
− | |WHITE || switch to white text |
+ | |WHITE || switch to white text || <div style="background:#FCFCFC;width:2em;"> </div> |
|- |
|- |
||
− | |LTBLUE || switch to light blue text |
+ | |LTBLUE || switch to light blue text || <div style="background:#80C4FC;width:2em;"> </div> |
|- |
|- |
||
− | |GRAY || switch to gray text |
+ | |GRAY || switch to gray text || <div style="background:#626562;width:2em;"> </div> |
|- |
|- |
||
− | |DKBLUE || switch to dark blue text |
+ | |DKBLUE || switch to dark blue text || <div style="background:#8484A4;width:2em;"> </div> |
|- |
|- |
||
− | |BLACK || switch to black text |
+ | |BLACK || switch to black text || <div style="background:#101010;width:2em;"> </div> |
+ | |- |
||
+ | |PUSH_COLOUR || {{ottdp|1.10|no}} Push current colour onto colour stack. Use this if you need to switch colour and restore later || |
||
+ | |- |
||
+ | |POP_COLOUR || {{ottdp|1.10|no}} Pop last colour from colour stack. Use this to restore previous colour || |
||
|} |
|} |
||
+ | == String parameters == |
||
The above tags can be used in almost all strings. There are also a number of tags that need an argument they'll read from the textstack. The textstack is only available for certain callbacks an properties. |
The above tags can be used in almost all strings. There are also a number of tags that need an argument they'll read from the textstack. The textstack is only available for certain callbacks an properties. |
||
{| |
{| |
||
Line 111: | Line 116: | ||
|VELOCITY || velocity in proper units || 2 || 35 km/h |
|VELOCITY || velocity in proper units || 2 || 35 km/h |
||
|- |
|- |
||
− | |VOLUME || volume in proper units || 2 || 29,000 |
+ | |VOLUME || volume in proper units || 2 || 29,000 litres |
+ | |- |
||
+ | |VOLUME_SHORT || volume in proper units in short form || 2 || 29,000l |
||
|- |
|- |
||
|POWER || power in proper units || 2 || 2,030 kW |
|POWER || power in proper units || 2 || 2,030 kW |
||
|- |
|- |
||
− | |WEIGHT || weight in proper units || 2 |
+ | |WEIGHT || weight in proper units || 2 || 5 tonnes |
+ | |- |
||
+ | |WEIGHT_SHORT || weight in proper units in short form || 2 || 5t |
||
+ | |- |
||
+ | |CARGO_LONG || {{ottdp|1.4|no|ottdrev=r26244}} cargo amount in proper units || 4 (2 + 2)<ref name="cargoamount">First (lower) 2 bytes for cargo type, second (higher) 2 bytes for cargo amount.</ref> || 10 bags of mail |
||
+ | |- |
||
+ | |CARGO_SHORT || {{ottdp|1.4|no|ottdrev=r26244}} cargo amount in proper units in short form || 4 (2 + 2)<ref name="cargoamount"/> || 10 bags |
||
+ | |- |
||
+ | |CARGO_TINY || {{ottdp|1.4|no|ottdrev=r26244}} cargo amount in proper units in tiny form (only unit conversion) || 4 (2 + 2)<ref name="cargoamount"/> || 10 |
||
+ | |- |
||
+ | |CARGO_NAME || {{ottdp|1.7|no|ottdrev=r27706}} cargo name || 2 || Coal |
||
|- |
|- |
||
|HEX || hexadecimal presentation || 4 || F0 3D D4 33 |
|HEX || hexadecimal presentation || 4 || F0 3D D4 33 |
||
Line 131: | Line 148: | ||
|POP_WORD || Remove 2 bytes from the top of the stack || 2 |
|POP_WORD || Remove 2 bytes from the top of the stack || 2 |
||
|- |
|- |
||
− | | |
+ | |STATION || Station name of station with given ID || 2 |
+ | |- |
||
+ | |FORCE || {{ottdp|14.0|no}} force in proper units || 4 || 1,000 kN |
||
|} |
|} |
||
+ | <references/> |
||
In case you don't want to use the first 2 (or 4) bytes from the stack but rather another variable, you can prefix the tag name with the number, like {1:COMMA} to use the second (indexing starts at 0) argument from the stack. You can also use this in translations that require a different order, for example (in english.lng): |
In case you don't want to use the first 2 (or 4) bytes from the stack but rather another variable, you can prefix the tag name with the number, like {1:COMMA} to use the second (indexing starts at 0) argument from the stack. You can also use this in translations that require a different order, for example (in english.lng): |
||
Line 140: | Line 160: | ||
And the same string in dutch.lng: |
And the same string in dutch.lng: |
||
− | STR_SOME_STRING |
+ | STR_SOME_STRING :{1:CURRENCY} is de prijs van {0:COMMA} items. |
+ | |||
+ | The string parameters itself are assigned in units of dwords (4 bytes), starting with temporary storage 256, up to 259 or 261. Thus if you use parameters which are not of dword size (e.g. strings or word-sized numbers), you have to construct the text stack via bit arithmetic: |
||
+ | <pre class=example> |
||
+ | switch(FEAT_INDUSTRIES, SELF, extra_text_switch, [ |
||
+ | STORE_TEMP( |
||
+ | ( (LOAD_PERM(var_supply_efficiency_factor) == 1) * string(STR_EXTRA_PRIMARY_EFFICIENT1) ) + |
||
+ | ( (LOAD_PERM(var_supply_efficiency_factor) == 2) * string(STR_EXTRA_PRIMARY_EFFICIENT2) ) + |
||
+ | ( (LOAD_PERM(var_supply_efficiency_factor) == 3) * string(STR_EXTRA_PRIMARY_EFFICIENT3) ) + |
||
+ | ( (LOAD_PERM(var_supply_efficiency_factor) == 4) * string(STR_EXTRA_PRIMARY_EFFICIENT4) ) | |
||
+ | LOAD_PERM(var_supply_requirement) << 16, |
||
+ | 256 |
||
+ | ), |
||
+ | return string(STR_EXTRA_PRIMARY); |
||
+ | } |
||
+ | </pre> |
||
+ | |||
+ | for a language file which reads |
||
+ | <pre class=example> |
||
+ | STR_EXTRA_PRIMARY_EFFICIENT1 :{YELLOW}very efficient{BLACK}ly |
||
+ | STR_EXTRA_PRIMARY_EFFICIENT2 :{YELLOW}efficient{BLACK}ly |
||
+ | STR_EXTRA_PRIMARY_EFFICIENT3 :in a {YELLOW}normal{BLACK} way |
||
+ | STR_EXTRA_PRIMARY_EFFICIENT4 :{YELLOW}wasteful{BLACK}ly |
||
+ | STR_EXTRA_PRIMARY :{BLACK}This industry needs {YELLOW}supplies{BLACK}.{}They use them {STRING}{}{}Monthly demand: {YELLOW}{UNSIGNED_WORD} crate{P "" s} of engineering supplies{BLACK}. |
||
+ | </pre> |
||
== Defining cases == |
== Defining cases == |
||
Line 158: | Line 202: | ||
STR_CARGO_PLURAL_PASSENGERS.t :utast |
STR_CARGO_PLURAL_PASSENGERS.t :utast |
||
</pre> |
</pre> |
||
+ | |||
+ | In case the name of a case changes in the OpenTTD language file, your language file will have to follow that change. To keep compatible with older OpenTTD versions you can use the ##map_case pragma, like this: |
||
+ | <pre class=example>##map_case t t_old</pre> |
||
== Defining genders == |
== Defining genders == |
||
Line 182: | Line 229: | ||
STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} akzeptiert kein{G "en" "e" "" "e"} {STRING} mehr. |
STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} akzeptiert kein{G "en" "e" "" "e"} {STRING} mehr. |
||
</pre> |
</pre> |
||
+ | |||
+ | In case the name of a gender changes in the OpenTTD language file, your language file will have to follow that change. To keep compatible with older OpenTTD versions you can use the ##map_gender pragma, like this: |
||
+ | <pre class=example>##gender m f |
||
+ | ##map_gender m male |
||
+ | ##map_gender f female</pre> |
||
== LanguageIDs == |
== LanguageIDs == |
||
+ | {{:language_IDs}} |
||
− | Valid language IDs are listed in the table below. The cases, genders and number of plural forms is only given as reference. Authorative are the definitions in OpenTTD's language file for each language. |
||
− | |||
− | {| class="t" |
||
− | ! ID |
||
− | ! language |
||
− | ! cases |
||
− | ! genders |
||
− | ! plurals |
||
− | |- |
||
− | | 00 |
||
− | | American |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 01 |
||
− | | English |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 02 |
||
− | | German |
||
− | | |
||
− | | m w n p |
||
− | | |
||
− | |- |
||
− | | 03 |
||
− | | French |
||
− | | |
||
− | | m m2 f |
||
− | | 2 |
||
− | |- |
||
− | | 04 |
||
− | | Spanish |
||
− | | |
||
− | | m f |
||
− | | |
||
− | |- |
||
− | | 05 |
||
− | | Esperanto |
||
− | | |
||
− | | n |
||
− | | |
||
− | |- |
||
− | | 06 |
||
− | | Ido |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 07 |
||
− | | Russian |
||
− | | m f n p nom gen dat acc abl pre |
||
− | | m f n p |
||
− | | 6 |
||
− | |- |
||
− | | 08 |
||
− | | Irish |
||
− | | |
||
− | | |
||
− | | 4 |
||
− | |- |
||
− | | 09 |
||
− | | Maltese |
||
− | | |
||
− | | |
||
− | | 12 |
||
− | |- |
||
− | | 0A |
||
− | | Tamil |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 0B |
||
− | | Chuvash |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 0C |
||
− | | Chinese (Traditional) |
||
− | | |
||
− | | |
||
− | | 1 |
||
− | |- |
||
− | | 0D |
||
− | | Serbian |
||
− | | nom big gen dat aku vok lok ins |
||
− | | muški ženski srednji |
||
− | | 6 |
||
− | |- |
||
− | | 0E |
||
− | | Norwegian (Nynorsk) |
||
− | | small |
||
− | | masculine feminine neuter |
||
− | | |
||
− | |- |
||
− | | 0F |
||
− | | Welsh |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 10 |
||
− | | Belarusian |
||
− | | m f n p nom gen dat acc abl pre |
||
− | | m f n p |
||
− | | 6 |
||
− | |- |
||
− | | 11 |
||
− | | Marathi |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 12 |
||
− | | Faroese |
||
− | | |
||
− | | m f n |
||
− | | |
||
− | |- |
||
− | | 14 |
||
− | | Arabic (Egypt) |
||
− | | |
||
− | | |
||
− | | 1 |
||
− | |- |
||
− | | 15 |
||
− | | Czech |
||
− | | nom gen dat acc voc loc ins big small |
||
− | | m f n map mnp fp np |
||
− | | 10 |
||
− | |- |
||
− | | 16 |
||
− | | Slovak |
||
− | | g |
||
− | | m z s |
||
− | | 10 |
||
− | |- |
||
− | | 18 |
||
− | | Bulgarian |
||
− | | m f n p |
||
− | | m f n p |
||
− | | |
||
− | |- |
||
− | | 1B |
||
− | | Afrikaans |
||
− | | |
||
− | | male |
||
− | | |
||
− | |- |
||
− | | 1E |
||
− | | Greek |
||
− | | subs date geniki |
||
− | | m f n |
||
− | | 2 |
||
− | |- |
||
− | | 1F |
||
− | | Dutch |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 21 |
||
− | | Basque |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 22 |
||
− | | Catalan |
||
− | | |
||
− | | Masculin Femenin |
||
− | | |
||
− | |- |
||
− | | 23 |
||
− | | Luxembourgish |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 24 |
||
− | | Hungarian |
||
− | | t ba |
||
− | | |
||
− | | 2 |
||
− | |- |
||
− | | 26 |
||
− | | Macedonian |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 27 |
||
− | | Italian |
||
− | | ms mp fs fp |
||
− | | m ma f |
||
− | | |
||
− | |- |
||
− | | 28 |
||
− | | Romanian |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 29 |
||
− | | Icelandic |
||
− | | |
||
− | | karlkyn kvenkyn hvorugkyn |
||
− | | |
||
− | |- |
||
− | | 2A |
||
− | | Latvian |
||
− | | kas |
||
− | | m f |
||
− | | 3 |
||
− | |- |
||
− | | 2B |
||
− | | Lithuanian |
||
− | | kas ko kam ka kuo kur kreip |
||
− | | vyr mot |
||
− | | 5 |
||
− | |- |
||
− | | 2C |
||
− | | Slovenian |
||
− | | r d t |
||
− | | |
||
− | | 8 |
||
− | |- |
||
− | | 2D |
||
− | | Danish |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 2E |
||
− | | Swedish |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 2F |
||
− | | Norwegian (Bokmal) |
||
− | | small |
||
− | | masculine feminine neuter |
||
− | | |
||
− | |- |
||
− | | 30 |
||
− | | Polish |
||
− | | d c b n m w |
||
− | | m f n |
||
− | | 7 |
||
− | |- |
||
− | | 31 |
||
− | | Galician |
||
− | | |
||
− | | m f n |
||
− | | |
||
− | |- |
||
− | | 32 |
||
− | | Frisian |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 33 |
||
− | | Ukrainian |
||
− | | r d z |
||
− | | m f s mn |
||
− | | 6 |
||
− | |- |
||
− | | 34 |
||
− | | Estonian |
||
− | | g in sü |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 35 |
||
− | | Finnish |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 36 |
||
− | | Portuguese |
||
− | | |
||
− | | n m f mp fp |
||
− | | |
||
− | |- |
||
− | | 37 |
||
− | | Brazilian Portuguese |
||
− | | |
||
− | | m f |
||
− | | 2 |
||
− | |- |
||
− | | 38 |
||
− | | Croatian |
||
− | | nom gen dat aku vok lok ins |
||
− | | male female middle |
||
− | | 6 |
||
− | |- |
||
− | | 39 |
||
− | | Japanese |
||
− | | |
||
− | | |
||
− | | 1 |
||
− | |- |
||
− | | 3A |
||
− | | Korean |
||
− | | |
||
− | | m f |
||
− | | 11 |
||
− | |- |
||
− | | 3C |
||
− | | Malay |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 3E |
||
− | | Turkish |
||
− | | tamlanan |
||
− | | |
||
− | | 1 |
||
− | |- |
||
− | | 42 |
||
− | | Thai |
||
− | | |
||
− | | |
||
− | | 1 |
||
− | |- |
||
− | | 54 |
||
− | | Vietnamese |
||
− | | |
||
− | | |
||
− | | 1 |
||
− | |- |
||
− | | 56 |
||
− | | Chinese (Simplified) |
||
− | | |
||
− | | |
||
− | | 1 |
||
− | |- |
||
− | | 5A |
||
− | | Indonesian |
||
− | | |
||
− | | |
||
− | | 1 |
||
− | |- |
||
− | | 5C |
||
− | | Urdu |
||
− | | |
||
− | | m f |
||
− | | |
||
− | |- |
||
− | | 61 |
||
− | | Hebrew |
||
− | | singular plural gen |
||
− | | m f |
||
− | | |
||
− | |- |
||
− | | 62 |
||
− | | Persian |
||
− | | |
||
− | | |
||
− | | |
||
− | |} |
||
− | In case a language is not in this list, |
+ | In case a language is not in this list, edit the shared [[language_IDs|master language list]] in the NewGRF Specs. This master list is always leading. NFO language ID 7F has no meaning in NML (set --default-lang instead) and setting bit 8 will break your language file. |
Latest revision as of 07:21, 10 September 2023
Vehicles, Stations, Canals, Bridges, Towns, Houses, Industries (Tiles), Cargos, Airports+Tiles, Objects, Railtypes, Roadtypes, Tramtypes, Terrain
No subpages in this chapter.
Introduction
Language files are usually found in the lang
sub-folder of the project, but the place NML looks for the language files can be changed via command line parameter to any directory desired:
nmlc -l path/to/lang-dir path/to/nml-source-file.nml nmlc --lang-dir=path/to/lang-dir path/to/nml-source-file.nml
Language files MUST have the extension .lng
The language files themselves follow a certain structure:
##grflangid <number> <string-name> :<text> <string-name> :<text> ...
where the first line must give the language code for the language this file describes (see below). The following lines each describe a string. The translated string follows immediately the colon. An NML project has exactly one fallback language, by default this is english.lng. You can change this with the command line parameter --default-lang. Example for a valid language file:
##grflangid 0x01 STR_GRF_NAME :{TITLE} 0.1.0 - {VERSION} STR_GRF_DESCRIPTION :{TITLE} contains pimped ground tiles. STR_NAME_MYVEHICLE :General Robotics Anti-Grav UFO Mark X
String codes
Strings may contain a number of special string codes which control how the string is being printed or which values to insert into the string. Custom replacements can be stored in the plain text file custom_tags.txt
(for example a newgrf version which is written by your build script). In the case above the custom_tags.txt
could, for example read
VERSION :alpha-r88 TITLE :Example NewGRF
Additionally to custom-defined tags, NML comes with a number of default tags:
String parameters
The above tags can be used in almost all strings. There are also a number of tags that need an argument they'll read from the textstack. The textstack is only available for certain callbacks an properties.
Tag | Meaning | Size (number of bytes read from stack) | Example |
---|---|---|---|
COMMA | signed number with decimal separator between 1000's. | 4 | |
SIGNED_WORD | signed number with decimal separator between 1000's. | 2 | |
UNSIGNED_WORD | unsigned number with decimal separator between 1000's. | 2 | |
CURRENCY | money in proper currency units | 4 | 24,492 € |
VELOCITY | velocity in proper units | 2 | 35 km/h |
VOLUME | volume in proper units | 2 | 29,000 litres |
VOLUME_SHORT | volume in proper units in short form | 2 | 29,000l |
POWER | power in proper units | 2 | 2,030 kW |
WEIGHT | weight in proper units | 2 | 5 tonnes |
WEIGHT_SHORT | weight in proper units in short form | 2 | 5t |
CARGO_LONG | 1.4 cargo amount in proper units | 4 (2 + 2)[1] | 10 bags of mail |
CARGO_SHORT | 1.4 cargo amount in proper units in short form | 4 (2 + 2)[1] | 10 bags |
CARGO_TINY | 1.4 cargo amount in proper units in tiny form (only unit conversion) | 4 (2 + 2)[1] | 10 |
CARGO_NAME | 1.7 cargo name | 2 | Coal |
HEX | hexadecimal presentation | 4 | F0 3D D4 33 |
STRING | include other string | 2 | |
DATE1920_LONG | days since 1920 as long date | 2 | 12 August 1935 |
DATE1920_SHORT | days since 1920 as short date | 2 | 12 Aug 1935 |
DATE_LONG | days since 0 as long date | 4 | 12 August 1610 |
DATE_SHORT | days since 0 as short date | 4 | 12 Aug 3049 |
POP_WORD | Remove 2 bytes from the top of the stack | 2 | |
STATION | Station name of station with given ID | 2 | |
FORCE | 14.0 force in proper units | 4 | 1,000 kN |
In case you don't want to use the first 2 (or 4) bytes from the stack but rather another variable, you can prefix the tag name with the number, like {1:COMMA} to use the second (indexing starts at 0) argument from the stack. You can also use this in translations that require a different order, for example (in english.lng):
STR_SOME_STRING :{COMMA} items cost {CURRENCY}
And the same string in dutch.lng:
STR_SOME_STRING :{1:CURRENCY} is de prijs van {0:COMMA} items.
The string parameters itself are assigned in units of dwords (4 bytes), starting with temporary storage 256, up to 259 or 261. Thus if you use parameters which are not of dword size (e.g. strings or word-sized numbers), you have to construct the text stack via bit arithmetic:
switch(FEAT_INDUSTRIES, SELF, extra_text_switch, [ STORE_TEMP( ( (LOAD_PERM(var_supply_efficiency_factor) == 1) * string(STR_EXTRA_PRIMARY_EFFICIENT1) ) + ( (LOAD_PERM(var_supply_efficiency_factor) == 2) * string(STR_EXTRA_PRIMARY_EFFICIENT2) ) + ( (LOAD_PERM(var_supply_efficiency_factor) == 3) * string(STR_EXTRA_PRIMARY_EFFICIENT3) ) + ( (LOAD_PERM(var_supply_efficiency_factor) == 4) * string(STR_EXTRA_PRIMARY_EFFICIENT4) ) | LOAD_PERM(var_supply_requirement) << 16, 256 ), return string(STR_EXTRA_PRIMARY); }
for a language file which reads
STR_EXTRA_PRIMARY_EFFICIENT1 :{YELLOW}very efficient{BLACK}ly STR_EXTRA_PRIMARY_EFFICIENT2 :{YELLOW}efficient{BLACK}ly STR_EXTRA_PRIMARY_EFFICIENT3 :in a {YELLOW}normal{BLACK} way STR_EXTRA_PRIMARY_EFFICIENT4 :{YELLOW}wasteful{BLACK}ly STR_EXTRA_PRIMARY :{BLACK}This industry needs {YELLOW}supplies{BLACK}.{}They use them {STRING}{}{}Monthly demand: {YELLOW}{UNSIGNED_WORD} crate{P "" s} of engineering supplies{BLACK}.
Defining cases
Similar to OpenTTD's language files, NML can also make use of cases, genders and plural forms. In order to utilize them, they have to be defined in the language file's header and have to match the definition as used in OpenTTD's language files:
##case pragma STR_NAME :Utas STR_NAME.pragma :utast
e.g. for Hungarian you'd have
##case t ba STR_CARGO_PLURAL_PASSENGERS :Utas STR_CARGO_PLURAL_PASSENGERS.t :utast
In case the name of a case changes in the OpenTTD language file, your language file will have to follow that change. To keep compatible with older OpenTTD versions you can use the ##map_case pragma, like this:
##map_case t t_old
Defining genders
Genders just like cases are defined in the header of the language file and have to match the definition as found within OpenTTD's language files. The gender of a word or expression is declared within the string's text itself by a tag of the form {G=gendername}
:
##gender pragma STR_NAME :{G=gendername}String which requires gender 'gendername'
where the string with the defined gender then will trigger the correct usage in a string which includes it and which has to take provisions to show the proper gender:
STR_OTHER :Some text {G gender1 gender2 ...} {STRING}
for example in German
##gender m w n p STR_CARGO_NAME_BAUXITE :{G=n}Bauxit
which then will be used with the correct gender by a string which includes it:
STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} akzeptiert kein{G "en" "e" "" "e"} {STRING} mehr.
In case the name of a gender changes in the OpenTTD language file, your language file will have to follow that change. To keep compatible with older OpenTTD versions you can use the ##map_gender pragma, like this:
##gender m f ##map_gender m male ##map_gender f female
LanguageIDs
Currently, the scheme is to use international phone codes as language IDs, unless they're out of range. When creating a new translation for OpenTTD pick a number vaguely related in some way. Or something else.
Valid language IDs are listed in the table below. The cases, genders and the type of plural form is only given as reference. Authorative are the definitions in OpenTTD's language file for each language. A complete list of these exact definitions is available here (generated page).
In case a language is not in this list, edit the shared master language list in the NewGRF Specs. This master list is always leading. NFO language ID 7F has no meaning in NML (set --default-lang instead) and setting bit 8 will break your language file.ID | language | cases | genders | plural form |
---|---|---|---|---|
00 | English (US) | |||
01 | English (GB) | |||
02 | German | m w n p | ||
03 | French | m m2 f | 2 | |
04 | Spanish | m f | ||
05 | Esperanto | n | ||
06 | Ido | |||
07 | Russian | m f n p nom gen dat acc abl pre | m f n p | 6 |
08 | Irish | 4 | ||
09 | Maltese | 12 | ||
0A | Tamil | |||
0B | Chuvash | |||
0C | Chinese (Traditional) | 1 | ||
0D | Serbian | nom big gen dat aku vok lok ins | muški ženski srednji | 6 |
0E | Norwegian (Nynorsk) | small | masculine feminine neuter | |
0F | Welsh | |||
10 | Belarusian | m f n p nom gen dat acc abl pre | m f n p | 6 |
11 | Marathi | |||
12 | Faroese | m f n | ||
13 | Scottish Gaelic | dat gen nom voc | m f | 13 |
14 | Arabic (Egypt) | 1 | ||
15 | Czech | nom gen dat acc voc loc ins big small | m f n map mnp fp np | 10 |
16 | Slovak | g | m z s | 10 |
17 | Hindi | |||
18 | Bulgarian | m f n p | m f n p | |
1B | Afrikaans | male | ||
1E | Greek | subs date geniki | m f n | 2 |
1F | Dutch | |||
21 | Basque | |||
22 | Catalan | Masculin Femenin | ||
23 | Luxembourgish | |||
24 | Hungarian | t ba | 2 | |
26 | Macedonian | |||
27 | Italian | ms mp fs fp | m ma f | |
28 | Romanian | |||
29 | Icelandic | karlkyn kvenkyn hvorugkyn | ||
2A | Latvian | kas | m f | 3 |
2B | Lithuanian | kas ko kam ka kuo kur kreip | vyr mot | 5 |
2C | Slovenian | r d t | 8 | |
2D | Danish | |||
2E | Swedish | |||
2F | Norwegian (Bokmal) | small | masculine feminine neuter | |
30 | Polish | d c b n m w | m f n | 7 |
31 | Galician | m f n | ||
32 | Frisian | |||
33 | Ukrainian | r d z | m f s mn | 6 |
34 | Estonian | g in sü | ||
35 | Finnish | |||
36 | Portuguese | n m f mp fp | ||
37 | Brazilian Portuguese | m f | 2 | |
38 | Croatian | nom gen dat aku vok lok ins | male female middle | 6 |
39 | Japanese | 1 | ||
3A | Korean | m f | 11 | |
3C | Malay | |||
3D | English (AU) | |||
3E | Turkish | tamlanan | 1 | |
42 | Thai | 1 | ||
54 | Vietnamese | 1 | ||
55 | Mexican Spanish | m f | 0 | |
56 | Chinese (Simplified) | 1 | ||
5A | Indonesian | 1 | ||
5C | Urdu | m f | ||
61 | Hebrew | singular plural gen | m f | |
62 | Persian | |||
66 | Latin | gen acc abl dat | m f n mp fp np |