Skip to main content

Documentation Index

Fetch the complete documentation index at: https://v5.rpgjs.dev/llms.txt

Use this file to discover all available pages before exploring further.

Internationalization

RPGJS uses the same i18n shape on the server and the client. Modules can ship default translations, and the game can override them with provideI18n().

Configure Translations

// src/i18n.ts
export default {
  defaultLocale: "fr",
  fallbackLocale: "en",
  messages: {
    fr: {
      "npc.guard.hello": "Bonjour {name}",
      "choice.fight": "Combattre",
      "rpg.menu.items": "Objets"
    },
    en: {
      "npc.guard.hello": "Hello {name}",
      "choice.fight": "Fight",
      "rpg.menu.items": "Items"
    }
  }
}
Use the same config on both sides when the game needs translated gameplay text on the server and translated local UI on the client.
// src/server.ts
import { createServer, provideI18n, provideServerModules } from "@rpgjs/server"
import i18n from "./i18n"

export default createServer({
  providers: [
    provideI18n(i18n),
    provideServerModules([])
  ]
})
// src/config.client.ts
import { provideI18n, provideClientModules } from "@rpgjs/client"
import i18n from "./i18n"

export default {
  providers: [
    provideI18n(i18n),
    provideClientModules([])
  ]
}

Translate Gameplay Text

The GUI APIs still receive final strings. Translate explicitly with player.i18n() or player.t().
async onAction(player) {
  const { t } = player.i18n()

  await player.showText(t("npc.guard.hello", {
    name: player.name
  }))

  const choice = await player.showChoices(t("npc.guard.question"), [
    { text: t("choice.fight"), value: "fight" },
    { text: t("choice.run"), value: "run" }
  ])
}

Player Locale

player.setLocale("fr")
player.getLocale()
The locale is stored in the player snapshot, so save(), load(), and session restore keep the selected language.

Module Defaults and Game Overrides

Reusable modules can provide default translations:
export const QuestModule = {
  server: {
    i18n: {
      en: {
        "quest.accepted": "Quest accepted"
      },
      fr: {
        "quest.accepted": "Quête acceptée"
      }
    }
  },
  client: {
    i18n: {
      en: {
        "quest.menu.title": "Quest Log"
      },
      fr: {
        "quest.menu.title": "Journal de quêtes"
      }
    }
  }
}
If the game provides the same key through provideI18n(), the game translation wins. Use namespaces such as quest.* or my-module.* for module keys.

Client Menus

Built-in RPGJS menus use rpg.* keys internally, such as rpg.menu.items and rpg.save.title. Override these keys in the game config to rename or translate the default menus.