Skip to content

Localization

Ben Straub edited this page Feb 20, 2023 · 3 revisions

Hello! If you're looking to contribute translations to the project, you're in the right place. Thanks!

The original English text of the system is spread out between Foundry-localizable text (in en.json) and in actors/items contained in compendia (example: starforged-moves.db).

Localizing Foundry text

Much of the UI text is translated using Foundry's built-in system. The original English text is located in en.json, and other localizations are also located in that directory.

Four tour content, this goes through a bit more of a pipeline; manual input should go into a YAML file (which supports Markdown syntax), and is then pulled into the Foundry JSON files by running tour-i18n.js. Take a look at welcome-tour.yml to see how that's done.

If you're looking to extend an existing translation, you can modify one of those files in place. If you've got a new language to introduce, there's a bit of code to modify; see #175 for an example of how that's accomplished.

Localizing compendium text

Most of the text content of the game is in moves, oracles, and foes/encounters, which are packaged into compendiums, and Foundry's built-in localization system doesn't work with these. To translate these, we rely on Babele, which is a module that allows other modules to modify compendium content as it is loaded. An example of this is the ironsworn-es-es module, which when installed and activated, will replace the English text in the compendiums with Spanish. See the Babele project for information on how to create a module.

Here are some examples that show the data layout:

Assets (assets.db and starforged-assets.db)

  • name is the asset's title
  • data.requirement is a hint for when this asset comes into play
  • data.abilties[].description is the text of the asset's abilities
  • data.fields[].name is the label for the fillable fields (like Horse's "Name")
  • data.track.name is the name of the resource track (like Glowcat's "Health")
  • data.exclusiveOptions[].name is the text of the radio-select options (like Ironclad's "Lightly armored")
  • data.conditions[].name is the label for conditions (like Hoverbike's "Battered")
{
  "_id": "2d3070fbde3039ac",
  "name": "Ironclad",
  "type": "asset",
  "img": "icons/svg/item-bag.svg",
  "data": {
    "requirement": "<p>If you wear armor...</p>\n",
    "category": "Combat Talent",
    "color": "",
    "fields": [],
    "abilities": [
      {
        "enabled": true,
        "description": "<p>When you equip or adjust your armor, choose one.</p>\n<ul>\n<li>Lightly armored: When you @Compendium[foundry-ironsworn.ironswornmoves.fdb51ee928b4fca2]{Endure Harm} in a fight, add +1 and take +1 momentum on a hit.</li>\n<li>Geared for war: Mark encumbered. When you @Compendium[foundry-ironsworn.ironswornmoves.fdb51ee928b4fca2]{Endure Harm} in a fight, add +2 and take +1 momentum on a hit.</li>\n</ul>\n"
      },
      {
        "enabled": false,
        "description": "<p>When you @Compendium[foundry-ironsworn.ironswornmoves.7e008d0f656dc8b3]{Clash} while you are geared for war, add +1.</p>\n"
      },
      {
        "enabled": false,
        "description": "<p>When you @Compendium[foundry-ironsworn.ironswornmoves.be95ca063ded2b19]{Compel} in a situation where strength of arms is a factor, add +2.</p>\n"
      }
    ],
    "track": { "enabled": false, "name": "Health", "current": 0, "max": 0 },
    "exclusiveOptions": [
      { "name": "Lightly armored", "selected": false },
      { "name": "Geared for war", "selected": false }
    ],
    "conditions": []
  },
  "effects": [],
  "folder": null,
  "sort": 0,
  "permission": { "default": 0, "gXcI9ebHCY1jasJg": 3 },
  "flags": {}
}

Moves (ironsworn-moves.db and starforged-moves.db)

  • data.Display.Title is used in the move-sheet sidebar as the name of the move (you've discovered that you can also remap name to get the same effect)
  • data.Text is the full description of the move, shown when you expand it in the move sheet. Markdown is supported here.
  • data.Trigger.Text is shown in the preroll dialog
  • data.Trigger.Options[].Text is used for the bullet points in the preroll dialog
  • data.Outcomes.*.Text are used in the chat-message output of a resolved roll
{
  "_id": "e6ed148eff82c171",
  "name": "Face Danger",
  "type": "sfmove",
  "img": "icons/dice/d10black.svg",
  "data": {
    "dfid": "Starforged/Moves/Adventure/Face_Danger",
    "Category": "Starforged/Moves/Adventure",
    "Progress Move": false,
    "Variant of": "",
    "Text": "**When you attempt something risky or react to an imminent threat**, envision your action and roll. If you act...\n\n  * With speed, mobility, or agility: Roll +edge\n  * With resolve, command, or sociability: Roll +heart\n  * With strength, endurance, or aggression: Roll +iron\n  * With deception, stealth, or trickery: Roll +shadow\n  * With expertise, focus, or observation: Roll +wits\n\nOn a **strong hit**, you are successful. Take +1 momentum.\n\nOn a **weak hit**, you succeed, but not without a cost. Make a suffer move (-1).\n\nOn a **miss**, you fail, or a momentary success is undermined by a dire turn of events. @Compendium[foundry-ironsworn.starforgedmoves.78baa51694fe37c5]{Pay the Price}.",
    "Trigger": {
      "Text": "When you attempt something risky or react to an imminent threat...",
      "Options": [
        {
          "dfid": "Starforged/Moves/Adventure/Face_Danger/Trigger/Options/1",
          "Text": "With speed, mobility, or agility",
          "Roll type": "Action roll",
          "Method": "Any",
          "Using": ["Edge"]
        },
        // ...
      ],
      "dfid": "Starforged/Moves/Adventure/Face_Danger/Trigger"
    },
    "Outcomes": {
      "Strong Hit": {
        "Text": "You are successful. Take +1 momentum.",
        "dfid": "Starforged/Moves/Adventure/Face_Danger/Outcomes/Strong_Hit"
      },
      "Weak Hit": {
        "Text": "You succeed, but not without a cost. Make a suffer move (-1).",
        "dfid": "Starforged/Moves/Adventure/Face_Danger/Outcomes/Weak_Hit"
      },
      "Miss": {
        "Text": "You fail, or a momentary success is undermined by a dire turn of events. @Compendium[foundry-ironsworn.starforgedmoves.78baa51694fe37c5]{Pay the Price}.",
        "dfid": "Starforged/Moves/Adventure/Face_Danger/Outcomes/Miss"
      },
      "dfid": "Starforged/Moves/Adventure/Face_Danger/Outcomes"
    },
    "Oracles": [],
    "Source": {
      "Title": "Ironsworn: Starforged Rulebook",
      "Authors": ["Shawn Tomkin"],
      "Date": "050622",
      "Page": 147
    },
    "Suggestions": {},
    "Name": "Face Danger",
    "Optional": false,
    "Display": { "Title": "Face Danger", "Color": "#3C70A4" }
  },
  "effects": [],
  "folder": null,
  "sort": 0,
  "permission": { "default": 0, "gXcI9ebHCY1jasJg": 3 },
  "flags": {}
}

Oracles (ironsworn-oracles.db and starforged-oracles.db)

  • name is the display name in the oracle tree
  • description is shown in the expanded preview in the oracle tree
  • results[].text is the text of the result, shown in the preview and the result chat message
{
  "_id": "eb992ccf692d8592",
  "name": "Background Assets",
  "img": "icons/dice/d10black.svg",
  "description": "If you want some direction for your starting paths, roll or pick from the table below and take the two paths associated with your selected background.",
  "results": [
    {
      "_id": "7a9ce91fdedd34c5",
      "range": [1, 5],
      "text": "Battlefield Medic (HEALER; VETERAN)",
      "type": 0,
      "drawn": false,
      "flags": {}
    },
    // ...
  ],
  "formula": "d100",
  "replacement": true,
  "displayRoll": true,
  "folder": null,
  "sort": 0,
  "permission": { "default": 0, "gXcI9ebHCY1jasJg": 3 },
  "flags": {
    "dfId": "Starforged/Oracles/Character_Creation/Background_Assets",
    "category": "Starforged/Oracles/Character_Creation"
  }
}

Encounter/Foe (foes.db and starforged-encounters.db)

  • name is shown in the compendium browser
  • data.description is the HTML of the body text of the foe
{
  "_id": "09186bbb3dfdec3c",
  "name": "Worldbreaker",
  "type": "progress",
  "img": "icons/creatures/abilities/mouth-teeth-rows-white.webp",
  "data": {
    "description": "\n\n<div class=\"boxgroup flexrow boxrow\" style=\"margin-bottom: 0.5rem;\">\n  <div class=\"flexcol box\" style=\"justify-content: flex-start;\">\n    <h4 class=\"nogrow\" style=\"margin: 0.5em;\">Features</h4>\n    <p class=\"nogrow\">Titanic worm-like creatures</p>\n    <p class=\"nogrow\">Gaping maw with rotating, earth-grinding teeth</p>\n    <p class=\"nogrow\">Thunderous cry</p>\n  </div>\n  <div class=\"flexcol box\" style=\"justify-content: flex-start;\">\n    <h4 class=\"nogrow\" style=\"margin: 0.5em;\">Drives</h4>\n    <p class=\"nogrow\">Lurk within carved depths</p>\n    <p class=\"nogrow\">Shape the landscape</p>\n    <p class=\"nogrow\">Endlessly pursue prey</p>\n  </div>\n  <div class=\"flexcol box\" style=\"justify-content: flex-start;\">\n    <h4 class=\"nogrow\" style=\"margin: 0.5em;\">Tactics</h4>\n    <p class=\"nogrow\">Detect prey through vibrations</p>\n    <p class=\"nogrow\">Shatter stone and steel</p>\n  </div>\n</div>\n\n<p>The scale and strength of the worldbreakers is so beyond our reckoning that some consider them godlike beings. Capable of thriving on verdant jungle worlds, frozen planets, worlds scorched by volcanic activity, and even within barren asteroids in the vacuum of space, these worms possess a wisdom and a cunning that makes them a deadly threat for even the most competent spacer.</p>\n<p>Worldbreakers range in size from about the size of a cargo hauler to an unfathomable scale that dwarfs our largest starship. They bore tunnels to pursue their prey, and hibernate in those dark depths to conserve energy. Though blind, worldbreaker worms can detect even the subtlest of footfalls, and they follow these vibrations to eventually consume their quarry—along with any other creatures, starships, or structures that happen to be nearby.</p>\n\n\n<blockquote>Quest Starter: <p>On a lush world at the edge of the Terminus, a titanic worldbreaker worm holds sway. One faction seeks to destroy the worm so that the riches of this place can be harvested. Another swears to protect it. On which side do you fall?</p>\n</blockquote>\n\n<h2>Variants</h2>\n<ul>\n  <li>@Compendium[foundry-ironsworn.starforgedencounters.94f8f295090cb8df]{Worldbreaker Brood}</li>\n  <li>@Compendium[foundry-ironsworn.starforgedencounters.dbf123295e6b89bf]{Elder Worm}</li>\n</ul>\n\n",
    "rank": "extreme",
    "current": 0,
    "completed": false,
    "subtype": "progress",
    "starred": false,
    "hasTrack": true,
    "hasClock": false,
    "clockTicks": 0,
    "clockMax": 6
  },
  "effects": [],
  "folder": null,
  "sort": 0,
  "permission": { "default": 0, "gXcI9ebHCY1jasJg": 3 },
  "flags": {}
}

Setting Truths (starforged-truths.db)

These are custom-type Journal Entry Pages with structured data. Look for pages of type truth, and look at the text therein:

{
  "name": "Artificial Intelligence",
  "flags": {
    "foundry-ironsworn": {
      "dfid": "Starforged/Setting_Truths/Artificial_Intelligence"
    }
  },
  "_id": "3UNZSRCUMSFeeoER",
  "pages": [
    {
      "type": "truth",
      "name": "We no longer have access to advanced computer systems. Instead, we must rely on the seers we call Adepts.",
      "system": {
        "Floor": 1,
        "Ceiling": 33,
        "dfid": "Starforged/Setting_Truths/Artificial_Intelligence/1-33",
        "Result": "We no longer have access to advanced computer systems. Instead, we must rely on the seers we call Adepts.",
        "Roll template": {
          "Description": "Our computers are limited to simple digital systems and the most basic machine intelligence. This is because: ${{Starforged/Setting_Truths/Artificial_Intelligence/1-33/Subtable}}.\n\nThe Adepts serve in place of those advanced systems. They utilize mind-altering drugs to see the universe as a dazzling lattice of data, identifying trends and predicting outcomes with uncanny accuracy. But to gain this insight they sacrifice much of themselves."
        },
        "Subtable": [
          {
            "Floor": 1,
            "Ceiling": 33,
            "dfid": "Starforged/Setting_Truths/Artificial_Intelligence/1-33/Subtable/1-33",
            "Result": "The energies of the Forge corrupt advanced systems"
          },
          {
            "Floor": 34,
            "Ceiling": 67,
            "dfid": "Starforged/Setting_Truths/Artificial_Intelligence/1-33/Subtable/34-67",
            "Result": "AI was outlawed in the aftermath of the machine wars"
          },
          {
            "Floor": 68,
            "Ceiling": 100,
            "dfid": "Starforged/Setting_Truths/Artificial_Intelligence/1-33/Subtable/68-100",
            "Result": "We have lost the knowledge to create and maintain AI"
          }
        ],
        "Description": "Our computers are limited to simple digital systems and the most basic machine intelligence. This is because: ______.\n\nThe Adepts serve in place of those advanced systems. They utilize mind-altering drugs to see the universe as a dazzling lattice of data, identifying trends and predicting outcomes with uncanny accuracy. But to gain this insight they sacrifice much of themselves.",
        "Quest Starter": "An Adept is tormented by a dire future they have seen for the inhabitants of the Forge. What does this vision show?",
        "Quest": "An Adept is tormented by a dire future they have seen for the inhabitants of the Forge. What does this vision show?"
      },
      "_id": "IW76rCCXAyOYsP4v",
      "title": { "show": true, "level": 1 },
      "image": {},
      "text": { "format": 1 },
      "video": { "controls": true, "volume": 0.5 },
      "src": null,
      "sort": 0,
      "ownership": { "default": -1 },
      "flags": {}
    },
    // ...
    {
      "name": "Character Inspiration",
      "text": {
        "markdown": "If you are accompanied by machine intelligence, you might have a companion such as a COMBAT BOT, PROTOCOL BOT, SURVEY BOT, or UTILITY BOT. If your ship has an AI, you might have the OVERSEER module. If AI in your campaign is rare or unavailable, these units will operate using very basic machine intelligence. If AI is common and advanced, they may have their own sentient personalities.",
        "format": 2,
        "content": "<p>If you are accompanied by machine intelligence, you might have a companion such as a COMBAT BOT, PROTOCOL BOT, SURVEY BOT, or UTILITY BOT. If your ship has an AI, you might have the OVERSEER module. If AI in your campaign is rare or unavailable, these units will operate using very basic machine intelligence. If AI is common and advanced, they may have their own sentient personalities.</p>"
      },
      "flags": {
        "foundry-ironsworn": {
          "assets": [
            "Starforged/Assets/Companion/Combat_Bot",
            "Starforged/Assets/Companion/Protocol_Bot",
            "Starforged/Assets/Companion/Survey_Bot",
            "Starforged/Assets/Companion/Utility_Bot",
            "Starforged/Assets/Module/Overseer"
          ]
        }
      },
      "_id": "vGDdiV3HPVFJhBoa",
      "type": "text",
      "title": { "show": true, "level": 1 },
      "image": {},
      "video": { "controls": true, "volume": 0.5 },
      "src": null,
      "system": {},
      "sort": 0,
      "ownership": { "default": -1 }
    }
  ],
  "folder": null,
  "sort": 0,
  "ownership": { "default": 0, "a8u59CvdJFmbk4At": 3 },
  "_stats": {
    "systemId": "foundry-ironsworn",
    "systemVersion": "1.20.5",
    "coreVersion": "10.291",
    "createdTime": 1671553750421,
    "modifiedTime": 1671553750427,
    "lastModifiedBy": "a8u59CvdJFmbk4At"
  }
}