Line 15: |
Line 15: |
| |- | | |- |
| | <samp>ID</samp> | | | <samp>ID</samp> |
− | | A unique identifier for your language. This isn't shown in-game. The recommended format is <code><your name>.<mod name></code>, with no spaces or special characters. | + | | A [[Modding:Common data field types#Unique string ID|unique string ID]] for your language. This isn't shown in-game. |
| |- | | |- |
| | <samp>LanguageCode</samp> | | | <samp>LanguageCode</samp> |
Line 43: |
Line 43: |
| * <code>[DAY_OF_WEEK]</code>: the abbreviated day of week as returned by <code>Game1.shortDayDisplayNameFromDayOfSeason</code> (like <samp>Mon</samp> for Monday). | | * <code>[DAY_OF_WEEK]</code>: the abbreviated day of week as returned by <code>Game1.shortDayDisplayNameFromDayOfSeason</code> (like <samp>Mon</samp> for Monday). |
| * <code>[DAY_OF_MONTH]</code>: the numerical day of the month. | | * <code>[DAY_OF_MONTH]</code>: the numerical day of the month. |
− | |-
| |
− | | <samp>UseLatinFont</samp>
| |
− | | Whether the language uses the game's default fonts. If set to <samp>false</samp>, you must set the <samp>FontFile</samp> field.
| |
− | |-
| |
− | | <samp>FontFile</samp>
| |
− | | ''(optional)'' The asset name for the font file to use (if <samp>UseLatinFont</samp> is <samp>false</samp>). See [[#Custom font|''custom font'']] below.
| |
− | |-
| |
− | | <samp>FontPixelZoom</samp>
| |
− | | ''(optional)'' A factor by while to multiply the font size.
| |
| |- | | |- |
| | <samp>FontApplyYOffset</samp> | | | <samp>FontApplyYOffset</samp> |
− | | ''(optional)'' Whether to shift the font up by four pixels (multiplied by the <samp>FontPixelZoom</samp>), to better align languages with larger characters like Chinese and Japanese. | + | | ''(optional)'' Whether to shift the font up by four pixels (multiplied by the <samp>FontPixelZoom</samp>), to better align languages with larger characters like Chinese and Japanese. Default false. |
| |- | | |- |
| | <samp>NumberComma</samp> | | | <samp>NumberComma</samp> |
− | | ''(optional)'' The string to use as the thousands separator (''e.g.,'' <code>","</code> for <code>5,000,000</code>). Defaults to a comma. | + | | ''(optional)'' The string to use as the thousands separator (like <code>","</code> for <code>5,000,000</code>). Defaults to a comma. |
| |- | | |- |
| | <samp>SmallFontLineSpacing</samp> | | | <samp>SmallFontLineSpacing</samp> |
Line 66: |
Line 57: |
| | | |
| Specifically, this affects the <samp>Strings\StringsFromCSFiles:SocialPage.cs.11635</samp> translation ("''(Single)''"). When enabled, it can contain male and female translations separated by <code>/</code>, like the vanilla Portuguese translation: "''(solteiro)/(solteira)''". | | Specifically, this affects the <samp>Strings\StringsFromCSFiles:SocialPage.cs.11635</samp> translation ("''(Single)''"). When enabled, it can contain male and female translations separated by <code>/</code>, like the vanilla Portuguese translation: "''(solteiro)/(solteira)''". |
| + | |- |
| + | | ''custom font fields'' |
| + | | See ''[[#Add a custom font|add a custom font]]'' below. |
| |} | | |} |
| | | |
| ===Example=== | | ===Example=== |
− | This Content Patcher pack would add Esperanto to the game. '''You should change <samp>Pathoschild.Esperanto</samp> to your mod's actual ID.''' | + | This Content Patcher pack would add Esperanto to the game. (<code><nowiki>{{ModId}}</nowiki></code> is a token, which will be replaced with your mod ID automatically.) |
| {{#tag:syntaxhighlight| | | {{#tag:syntaxhighlight| |
| { | | { |
− | "Format": "{{Content Patcher version}}", | + | "Format": "{{Content Patcher version}}",<nowiki> |
| "Changes": [ | | "Changes": [ |
| // define language | | // define language |
Line 79: |
Line 73: |
| "Target": "Data/AdditionalLanguages", | | "Target": "Data/AdditionalLanguages", |
| "Entries": { | | "Entries": { |
− | "Pathoschild.Esperanto": { // for technical reasons, you need to specify the ID here *and* in the "ID" field | + | "{{ModId}}_Esperanto": { // for technical reasons, you need to specify the ID here *and* in the "ID" field |
− | "ID": "Pathoschild.Esperanto", | + | "ID": "{{ModId}}_Esperanto", |
| "LanguageCode": "eo", | | "LanguageCode": "eo", |
− | "ButtonTexture": "Mods/Pathoschild.Esperanto/Button", | + | "ButtonTexture": "Mods/{{ModId}}/Button", |
| "UseLatinFont": true, | | "UseLatinFont": true, |
| "TimeFormat": "[HOURS_24_00]:[MINUTES]", | | "TimeFormat": "[HOURS_24_00]:[MINUTES]", |
Line 94: |
Line 88: |
| { | | { |
| "Action": "Load", | | "Action": "Load", |
− | "Target": "Mods/Pathoschild.Esperanto/Button", | + | "Target": "Mods/{{ModId}}/Button", |
| "FromFile": "assets/button.png" | | "FromFile": "assets/button.png" |
| } | | } |
| ] | | ] |
− | }|lang=javascript}} | + | }</nowiki>|lang=javascript}} |
| | | |
| Once the language is defined, you can add translations to the game by patching game assets like usual, and use the language code you specified above. For example: | | Once the language is defined, you can add translations to the game by patching game assets like usual, and use the language code you specified above. For example: |
Line 116: |
Line 110: |
| </syntaxhighlight> | | </syntaxhighlight> |
| | | |
− | ==Custom font== | + | ==Add a custom font== |
− | If you set <samp>UseLatinFont: false</samp> in the language data, you can provide your own Bitmap font with the <samp>FontFile</samp> field. This lets you map arbitrary Unicode characters to sprites in your font texture. You can [[Modding:Editing XNB files#Unpack game files|unpack your game's <samp>Content</samp> folder]] and look at the Chinese, Japanese, Korean, and Russian fonts in the <samp>Fonts</samp> folder for examples of how this looks in practice.
| + | You can provide your own Bitmap font for your custom language, which maps arbitrary Unicode characters to sprites in your font texture. You can [[Modding:Editing XNB files#Unpack game files|unpack your game's <samp>Content</samp> folder]] and look at the Chinese, Japanese, Korean, and Russian fonts in the <samp>Fonts</samp> folder for examples of how this looks in practice. |
| + | |
| + | ===Data format=== |
| + | To enable a custom font, add these three extra fields to [[#Add a custom language|your <samp>Data/AdditionalLanguages</samp> entry]]: |
| + | |
| + | {| class="wikitable" |
| + | |- |
| + | ! field |
| + | ! description |
| + | |- |
| + | | <samp>UseLatinFont</samp> |
| + | | Whether the language uses the game's default fonts. '''Set to <samp>false</samp>''' to enable a custom font. |
| + | |- |
| + | | <samp>FontFile</samp> |
| + | | The asset name for your <samp>.fnt</samp> font data file (see [[#Font files|''font files'']] below). This must be the asset's name in the game's <samp>Content</samp> folder, not the file path in your content pack; see [[#Example 2|the example below]]. |
| + | |- |
| + | | <samp>FontPixelZoom</samp> |
| + | | A factor by which to multiply the font size. The recommended baseline is 1.5, but you can adjust it to make your text smaller or bigger in-game. |
| + | |} |
| | | |
| ===Font files=== | | ===Font files=== |
| + | Note: if your language has a TrueType font available, you can use the [https://www.angelcode.com/products/bmfont/ Bitmap font generator] to generate these files from it. |
| + | |
| ; Font data | | ; Font data |
− | : Each font must have a text (XML) file with the <tt>.fnt</tt> extension which describes the font. | + | : Each font must have a text (XML) file with the <samp>.fnt</samp> extension which describes the font. |
| | | |
| : For example, here's the <samp>Content/Fonts/Japanese.fnt</samp> file (with most of the characters stripped out for brevity): | | : For example, here's the <samp>Content/Fonts/Japanese.fnt</samp> file (with most of the characters stripped out for brevity): |
Line 192: |
Line 206: |
| : <div style="display: inline-block; background:#000;">[[File:Modding - example font texture.png|300px]]</div> | | : <div style="display: inline-block; background:#000;">[[File:Modding - example font texture.png|300px]]</div> |
| | | |
− | ===Provide the font files=== | + | ===Example=== |
| If you're using [[Modding:Content Patcher|Content Patcher]], your content pack should look something like this with the files described above: | | If you're using [[Modding:Content Patcher|Content Patcher]], your content pack should look something like this with the files described above: |
| <pre> | | <pre> |
Line 203: |
Line 217: |
| </pre> | | </pre> |
| | | |
− | Now you just need to make them available through the game's <samp>Content/Fonts</samp> folder. Make sure the target for the <samp>.fnt</samp> file matches what you specified via <tt>UseFontFile</tt> in the [[#Add a custom language|language data]], and the target for the image matches what you specified via <samp>pages</samp> in the [[#Font files|font data]]. | + | Now you just need to make them available through the game's <samp>Content/Fonts</samp> folder. Make sure the target for the <samp>.fnt</samp> file matches what you specified via <samp>FontFile</samp> in the [[#Add a custom language|language data]], and the target for the image matches what you specified via <samp>pages</samp> in the [[#Font files|font data]]. |
| | | |
| For example, here's the previous Esperanto example with a custom font (note the <samp>UseLatinFont</samp> and <samp>FontFile</samp> fields in the language data, and the two new patches at the bottom): | | For example, here's the previous Esperanto example with a custom font (note the <samp>UseLatinFont</samp> and <samp>FontFile</samp> fields in the language data, and the two new patches at the bottom): |
| {{#tag:syntaxhighlight| | | {{#tag:syntaxhighlight| |
| { | | { |
− | "Format": "{{Content Patcher version}}", | + | "Format": "{{Content Patcher version}}",<nowiki> |
| "Changes": [ | | "Changes": [ |
| // define language | | // define language |
Line 215: |
Line 229: |
| "Target": "Data/AdditionalLanguages", | | "Target": "Data/AdditionalLanguages", |
| "Entries": { | | "Entries": { |
− | "Pathoschild.Esperanto": { // for technical reasons, you need to specify the ID here *and* in the "ID" field | + | "{{ModId}}_Esperanto": { // for technical reasons, you need to specify the ID here *and* in the "ID" field |
− | "ID": "Pathoschild.Esperanto", | + | "ID": "{{ModId}}_Esperanto", |
| "LanguageCode": "eo", | | "LanguageCode": "eo", |
− | "ButtonTexture": "Mods/Pathoschild.Esperanto/Button", | + | "ButtonTexture": "Mods/{{ModId}}/Button", |
| "UseLatinFont": false, | | "UseLatinFont": false, |
− | "FontFile": "Fonts/Esperanto", | + | "FontFile": "Fonts/{{ModId}}/Esperanto", |
| "TimeFormat": "[HOURS_24_00]:[MINUTES]", | | "TimeFormat": "[HOURS_24_00]:[MINUTES]", |
| "ClockTimeFormat": "[HOURS_24_00]:[MINUTES]", | | "ClockTimeFormat": "[HOURS_24_00]:[MINUTES]", |
Line 231: |
Line 245: |
| { | | { |
| "Action": "Load", | | "Action": "Load", |
− | "Target": "Mods/Pathoschild.Esperanto/Button", | + | "Target": "Mods/{{ModId}}/Button", |
| "FromFile": "assets/button.png" | | "FromFile": "assets/button.png" |
| } | | } |
Line 238: |
Line 252: |
| { | | { |
| "Action": "Load", | | "Action": "Load", |
− | "Target": "Fonts/Esperanto", | + | "Target": "Fonts/{{ModId}}/Esperanto", |
| "FromFile": "assets/Esperanto.fnt" | | "FromFile": "assets/Esperanto.fnt" |
| }, | | }, |
| { | | { |
| "Action": "Load", | | "Action": "Load", |
− | "Target": "Fonts/Esperanto_0", | + | "Target": "Fonts/{{ModId}}/Esperanto_0", |
| "FromFile": "assets/Esperanto_0.png" | | "FromFile": "assets/Esperanto_0.png" |
| } | | } |
| ] | | ] |
− | }|lang=javascript}} | + | }</nowiki>|lang=javascript}} |
| + | |
| + | ==Limitations== |
| + | Custom languages must be available very early in the game startup, and won't be handled correctly if they're added later. That means: |
| + | * For Content Patcher packs, they must be added without <samp>When</samp> conditions (or only using immutable conditions like config or <samp>HasMod</samp>). |
| + | * For C# mods, they should be added in [[Modding:Modder Guide/APIs/Events#Game loop|<samp>GameLaunched</samp>]] or earlier. |
| | | |
| ==See also== | | ==See also== |