Difference between revisions of "NML:Language files"
Planetmaker (talk | contribs) (→LanguageIDs: document cases, genders and plural forms of some languages) |
Andythenorth (talk | contribs) |
||
(21 intermediate revisions by 8 users not shown) | |||
Line 33: | Line 33: | ||
Additionally to custom-defined tags, NML comes with a number of default tags: |
Additionally to custom-defined tags, NML comes with a number of default tags: |
||
{| |
{| |
||
− | !Tag |
+ | !width="150pt"|Tag |
− | !Meaning |
+ | !width="600pt"|Meaning |
!Example |
!Example |
||
|- |
|- |
||
+ | | ||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. || |
||
− | |TINYFONT || switch to small font |
||
|- |
|- |
||
− | | |
+ | |COPYRIGHT || copyright symbol || © |
|- |
|- |
||
− | | |
+ | |TRAIN || display train symbol || |
|- |
|- |
||
− | | |
+ | |LORRY || display lorry symbol || |
|- |
|- |
||
− | | |
+ | |BUS || display bus symbol || |
|- |
|- |
||
− | | |
+ | |PLANE || display plane symbol || |
|- |
|- |
||
− | | |
+ | |SHIP || display ship symbol || |
|- |
|- |
||
+ | |TINYFONT || switch to small font || |
||
− | |CURRENCY || display variable (2 bytes): money in proper currency units|| 24,492 € |
||
|- |
|- |
||
− | | |
+ | |BIGFONT || switch to big font || |
|- |
|- |
||
+ | |BLUE || switch to blue text || <div style="background:#3890E8;width:2em;"> </div> |
||
− | |DATE1920_LONG || display variable (2 bytes): days since 1920 as long date || 12 August 1935 |
||
|- |
|- |
||
+ | |SILVER || switch to silver text || <div style="background:#C8C8C8;width:2em;"> </div> |
||
− | |DATE1920_SHORT|| display variable (2 bytes): days since 1920 as short date || 12 Aug 1935 |
||
|- |
|- |
||
+ | |GOLD || switch to golden text || <div style="background:#FCC000;width:2em;"> </div> |
||
− | |VELOCITY || display variable (2 bytes): velocity in proper units || 35 km/h |
||
|- |
|- |
||
+ | |RED || switch to red text || <div style="background:#FC0000;width:2em;"> </div> |
||
− | |POP_WORD || |
||
|- |
|- |
||
+ | |PURPLE || switch to purple text || <div style="background:#A888E0;width:2em;"> </div> |
||
− | |ROTATE || |
||
|- |
|- |
||
+ | |LTBROWN || switch to light brown text || <div style="background:#B0B084;width:2em;"> </div> |
||
− | |VOLUME || display variable (2 bytes): volume in proper units || 29,000 l |
||
|- |
|- |
||
+ | |ORANGE || switch to orange text || <div style="background:#FCB030;width:2em;"> </div> |
||
− | |CURRENCY_QWORD|| display variable (8 bytes): money in proper currency units|| 4,402,204,201€ |
||
|- |
|- |
||
+ | |GREEN || switch to green text || <div style="background:#90E05C;width:2em;"> </div> |
||
− | |PUSH_WORD || |
||
|- |
|- |
||
+ | |YELLOW || switch to yellow text || <div style="background:#FCF880;width:2em;"> </div> |
||
− | |UNPRINT || |
||
|- |
|- |
||
+ | |DKGREEN || switch to dark green text || <div style="background:#B4CC7C;width:2em;"> </div> |
||
− | |BYTE_HEX || display variable (1 byte): hexadecimal presentation || F0 |
||
|- |
|- |
||
+ | |CREAM || switch to cream-coloured text || <div style="background:#D49480;width:2em;"> </div> |
||
− | |WORD_HEX || display variable (2 bytes): hexadecimal presentation || F0 3D |
||
|- |
|- |
||
+ | |BROWN || switch to brown text || <div style="background:#A46040;width:2em;"> </div> |
||
− | |DWORD_HEX || display variable (4 bytes): hexadecimal presentation || F0 3D D4 33 |
||
|- |
|- |
||
+ | |WHITE || switch to white text || <div style="background:#FCFCFC;width:2em;"> </div> |
||
− | |QWORD_HEX || display variable (8 bytes): hexadecimal presentation || 4F 4D 4D 33 49 32 FF A3 |
||
|- |
|- |
||
+ | |LTBLUE || switch to light blue text || <div style="background:#80C4FC;width:2em;"> </div> |
||
− | |WORD_S_TONNES || display variable (2 bytes): weight in tons || 42t |
||
|- |
|- |
||
+ | |GRAY || switch to gray text || <div style="background:#626562;width:2em;"> </div> |
||
− | |DATE_LONG || display variable (2 bytes): days since 0 as long date || 12 August 1610 |
||
|- |
|- |
||
+ | |DKBLUE || switch to dark blue text || <div style="background:#8484A4;width:2em;"> </div> |
||
− | |DATE_SHORT || display variable (2 bytes): days since 0 as short date || 12 Aug 3049 |
||
|- |
|- |
||
+ | |BLACK || switch to black text || <div style="background:#101010;width:2em;"> </div> |
||
− | |POWER || display variable (2 bytes): power in proper units || 2,030 kW |
||
|- |
|- |
||
+ | |PUSH_COLOUR || {{ottdp|1.10|no}} Push current colour onto colour stack. Use this if you need to switch colour and restore later || |
||
− | |BLUE || switch to blue text |
||
|- |
|- |
||
+ | |POP_COLOUR || {{ottdp|1.10|no}} Pop last colour from colour stack. Use this to restore previous colour || |
||
− | |SILVER || switch to silver text |
||
+ | |} |
||
+ | |||
+ | == 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. |
||
+ | {| |
||
+ | !width="150pt"|Tag |
||
+ | !width="600pt"|Meaning |
||
+ | !Size (number of bytes read from stack) |
||
+ | !Example |
||
|- |
|- |
||
+ | |COMMA || signed number with decimal separator between 1000's. || 4 |
||
− | |GOLD || switch to golden text |
||
|- |
|- |
||
+ | |SIGNED_WORD || signed number with decimal separator between 1000's. || 2 |
||
− | |RED || switch to red text |
||
|- |
|- |
||
+ | |UNSIGNED_WORD || unsigned number with decimal separator between 1000's. || 2 |
||
− | |PURPLE || switch to purple text |
||
|- |
|- |
||
+ | |CURRENCY || money in proper currency units || 4 || 24,492 € |
||
− | |LTBROWN || switch to light brown text |
||
|- |
|- |
||
+ | |VELOCITY || velocity in proper units || 2 || 35 km/h |
||
− | |ORANGE || switch to orange text |
||
|- |
|- |
||
+ | |VOLUME || volume in proper units || 2 || 29,000 litres |
||
− | |GREEN || switch to green text |
||
|- |
|- |
||
+ | |VOLUME_SHORT || volume in proper units in short form || 2 || 29,000l |
||
− | |YELLOW || switch to yellow text |
||
|- |
|- |
||
+ | |POWER || power in proper units || 2 || 2,030 kW |
||
− | |DKGREEN || switch to dark green text |
||
|- |
|- |
||
+ | |WEIGHT || weight in proper units || 2 || 5 tonnes |
||
− | |CREAM || switch to cream-coloured text |
||
|- |
|- |
||
+ | |WEIGHT_SHORT || weight in proper units in short form || 2 || 5t |
||
− | |BROWN || switch to brown text |
||
|- |
|- |
||
+ | |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 |
||
− | |WHITE || switch to white text |
||
|- |
|- |
||
+ | |CARGO_SHORT || {{ottdp|1.4|no|ottdrev=r26244}} cargo amount in proper units in short form || 4 (2 + 2)<ref name="cargoamount"/> || 10 bags |
||
− | |LTBLUE || switch to light blue text |
||
|- |
|- |
||
+ | |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 |
||
− | |GRAY || switch to gray text |
||
|- |
|- |
||
+ | |CARGO_NAME || {{ottdp|1.7|no|ottdrev=r27706}} cargo name || 2 || Coal |
||
− | |DKBLUE || switch to dark blue text |
||
|- |
|- |
||
+ | |HEX || hexadecimal presentation || 4 || F0 3D D4 33 |
||
− | |BLACK || switch to black text |
||
|- |
|- |
||
+ | |STRING || include other string || 2 |
||
− | |TRAIN || display train symbol |
||
|- |
|- |
||
+ | |DATE1920_LONG || days since 1920 as long date || 2 || 12 August 1935 |
||
− | |LORRY || display lorry symbol |
||
|- |
|- |
||
+ | |DATE1920_SHORT|| days since 1920 as short date || 2 || 12 Aug 1935 |
||
− | |BUS || display bus symbol |
||
|- |
|- |
||
+ | |DATE_LONG || days since 0 as long date || 4 || 12 August 1610 |
||
− | |PLANE || display plane symbol |
||
|- |
|- |
||
+ | |DATE_SHORT || days since 0 as short date || 4 || 12 Aug 3049 |
||
− | |SHIP || display ship symbol |
||
+ | |- |
||
+ | |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): |
||
+ | |||
+ | 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: |
||
+ | <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 154: | 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 178: | 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. |
||
− | |||
− | {| 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 |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 35 |
||
− | | Finnish |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 36 |
||
− | | Portuguese |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 37 |
||
− | | Brazilian Portuguese |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 38 |
||
− | | Croatian |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 39 |
||
− | | Japanese |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 3A |
||
− | | Korean |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 3C |
||
− | | Malay |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 3E |
||
− | | Turkish |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 42 |
||
− | | Thai |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 54 |
||
− | | Vietnamese |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 56 |
||
− | | Chinese (Simplified) |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 5A |
||
− | | Indonesian |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 5C |
||
− | | Urdu |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 61 |
||
− | | Hebrew |
||
− | | |
||
− | | |
||
− | | |
||
− | |- |
||
− | | 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 |