Skip to content

Localization

You can localize every asset in your novel. Readers can choose separate languages for text and voice.

First, list the locales your novel supports in your workspace’s project.json, using IETF language tags:

{
"locales": ["en-US", "fr-FR", "ja-JP"]
}

To localize a file, put the locale in its filename:

scene-i.en-US.fountain

Or put it in a locale folder:

screenplay/en-US/act-i/scene-i.fountain

You can use both approaches in the same novel. The only rule is that a file’s translations have to follow the same pattern as the original. If the original is in a locale folder, its translations need to be in locale folders too.

Only translate the text the reader sees: narration, dialogue, and link text. Leave everything else as it is in the original.

Every other part of the screenplay connects to your artwork and code, and changing it breaks that connection.

Inkweaver shows the artwork for the reader’s text language. There are two ways to localize your artwork:

  • Separate files. Make a complete copy of the PSD for each locale, named or placed in a folder like any other localized file.
  • Variation sets. Keep a single PSD, and add a layer for each locale inside a variation set. The reader’s current locale counts as a label, so a layer named en-US shows and hides the same way as any other variation.

A stem with lyrics is localized like any other file. Inkweaver picks the version that matches the reader’s voice language.

JavaScript files are the only assets that can’t be localized.

If a script needs a localized asset, load it with the SDK’s resolve function.

Each menu field keeps its text in its locales property, with one version per locale. Menus use the reader’s text language.

The Novel plugin’s menus are in English. To translate them, decorate buildMenuSchema and add your locale to each field, matching fields by name:

const JAPANESE = {
back: "戻る",
continue: "つづきから",
newStory: "はじめから",
options: "オプション",
};
decorateCommand("buildMenuSchema", async (context, next) => {
const result = await next(context);
const fields = result.schema.fields.map((field) => {
const text = JAPANESE[field.name];
if (text == null) return field;
return { ...field, locales: { ...field.locales, "ja-JP": text } };
});
return { schema: { ...result.schema, fields } };
});
NameEnglish
newStoryNew Story
continueContinue
saveSave
loadLoad
optionsOptions
mainMain Menu
languageLanguage
textLocaleText
voiceLocaleVoice
controlsControls
slot-1, slot-2, slot-3Slot 1, Slot 2, Slot 3
backBack