Skip to content

Internationalization (i18n)

Epiphany uses Minecraft's native Component + lang file mechanism for internationalization. Whether you're a datapack author or a mod developer, simply provide translation keys in the appropriate assets/<namespace>/lang/<language>.json and the game will automatically display localized text.

Mechanism: Native Component Support

All Component-typed fields in datapacks (name, description, condition_description, *_reward_description, and UI text) support three JSON writing styles:

StyleMeaning
"Warrior" (string)Plain literal text
{ "text": "Warrior", "color": "gold" } (object)Styled literal text
{ "translate": "mymod.module.combat.name" } (object)Translation key (looked up in lang files)

How translation keys work

When JSON is written as {"translate": "key"}, Minecraft automatically looks up the translation for that key on the client:

  • Found in assets/<namespace>/lang/en_us.json or other language files → displays the translated text
  • Not found → displays the raw key string

This mechanism is natively supported by Minecraft; Epiphany does no additional processing. You only need to: ① write {"translate": "key"} in your JSON; ② provide the translation for that key in a lang file.

Epiphany's Default Lang Auto-Fallback

TIP

When a Component field is omitted (not written or set to null), Epiphany automatically constructs a convention-based translation key rather than displaying the raw ID string or leaving it blank.

This means you don't need to write {"translate": ...} in your JSON — just fill in the convention keys in your lang file.

The fallback rule for all four data types:

<type>.<namespace>.<path>.<field>
Data TypeFieldTranslation Key
Modulenamemodule.<ns>.<path>.name
Moduledescriptionmodule.<ns>.<path>.description
Modulecondition_descriptionmodule.<ns>.<path>.condition_description
Moduleon_select_reward_descriptionmodule.<ns>.<path>.on_select_reward_description
Moduleon_complete_reward_descriptionmodule.<ns>.<path>.on_complete_reward_description
Insightnameinsight.<ns>.<path>.name
Insightdescriptioninsight.<ns>.<path>.description
Insightreward_descriptioninsight.<ns>.<path>.reward_description
Epiphanynameepiphany.<ns>.<path>.name
Epiphanydescriptionepiphany.<ns>.<path>.description
Epiphanycondition_descriptionepiphany.<ns>.<path>.condition_description
Epiphanyreward_descriptionepiphany.<ns>.<path>.reward_description
Pathnamepath.<ns>.<path>.name
Pathdescriptionpath.<ns>.<path>.description

Where <ns> and <path> come from the registry ID <ns>:<path>. For example:

  • data/mymod/epiphany/module/class/warrior.json → registry ID mymod:class/warrior
  • name omitted → fallback key: module.mymod.class/warrior.name

Slashes in subdirectory paths

The path portion of the registry ID retains slashes (/). So a translation key might be module.mymod.class/warrior.name (with a slash). This is valid but not very tidy in a lang file. If you prefer cleaner keys, you have two options:

  • Use flat filenames in your datapack (avoid subdirectories)
  • Explicitly write "name": {"translate": "mymod.class.warrior.name"} with dot-separated keys

Three i18n Styles

Omit name in JSON; only fill in the lang file:

jsonc
// data/mymod/epiphany/module/warrior.json
{
    "initial_state": "selectable",
    "insights": [ ... ]
}
json
// assets/mymod/lang/en_us.json
{
    "module.mymod.warrior.name": "Warrior",
    "module.mymod.warrior.description": "Veteran of the battlefield"
}

Style B: Explicit Translation Keys

Cleaner decoupling between datapack and lang; free-form key naming:

jsonc
{
    "name": { "translate": "mymod.warrior.name" },
    "description": { "translate": "mymod.warrior.desc" }
}
json
// assets/mymod/lang/en_us.json
{
    "mymod.warrior.name": "Warrior",
    "mymod.warrior.desc": "Veteran of the battlefield"
}

Style C: Literal Text (No i18n)

Suitable for small datapacks serving a single language:

jsonc
{
    "name": "Warrior",
    "description": "Veteran of the battlefield"
}

The displayed language is independent of the player's client language and always shows this text.

Lang File Location

assets/<namespace>/lang/<language>.json
  • <namespace> typically matches your datapack or mod namespace
  • <language> follows MC standards: en_us, zh_cn, ja_jp, etc.

KubeJS Perspective

When accessing localized text visible to players from KubeJS scripts, take special care:

js
let module = Epiphany.getModule('mymod:warrior');

// ❌ Raw Optional (the literal Component from the datapack JSON; may be empty)
let rawName = module.name;   // Optional<Component>

// ✅ Display text with full lang fallback
let displayName = module.effectiveName('mymod:warrior').getString();

See KubeJS Compat · Data Queries.