Internationalisation (i18n)
La lib utilise le système i18n natif de Minecraft. Aucun texte brut ne doit apparaître dans les widgets — toujours une clé de traduction.
Principe
Chaque chaîne affichée est identifiée par une clé i18n (ex. monmod.screen.hub). Minecraft résout automatiquement la clé dans la langue active du client.
Si la clé est absente du fichier de langue, LocaleResolver affiche la clé brute au lieu de crasher — pratique en développement.
Structure des fichiers de langue
Chaque mod fournit ses propres fichiers dans :
src/main/resources/assets/<modid>/lang/
en_us.json ← anglais (obligatoire — langue de fallback Forge)
fr_ca.json ← français canadien (Apocaly)
La lib fournit ses propres clés internes dans assets/apocalyinterface/lang/. Tu n'as pas à les dupliquer.
Format JSON
{
"monmod.screen.hub": "Hub de Clan",
"monmod.label.clan": "Clan : %s",
"monmod.label.membres": "Membres : %s",
"monmod.row.points": "Points",
"monmod.btn.rejoindre": "Rejoindre",
"monmod.tab.stats": "Stats",
"monmod.bar.xp": "Expérience",
"monmod.search.placeholder":"Rechercher…"
}
Conventions de nommage
| Préfixe | Usage |
|---|---|
<modid>.screen.<nom> | Titre d'écran |
<modid>.panel.<nom> | Titre d'un panneau (ApocalyMultiScreen) |
<modid>.label.<nom> | Label texte |
<modid>.row.<nom> | Clé d'un KeyValueRow |
<modid>.btn.<nom> | Texte de bouton |
<modid>.tab.<nom> | Libellé d'onglet |
<modid>.bar.<nom> | Label de ProgressBar |
<modid>.search.<nom> | Placeholder de SearchField |
<modid>.key.<nom> | Description d'un KeyMapping |
Utilisation dans les widgets
Tous les builders de widgets acceptent une clé i18n :
import net.minecraft.network.chat.Component;
import ca.tawess123.apocalyinterface.api.data.DataSource;
// Label avec valeur dynamique
Label.builder()
.text("monmod.label.clan") // clé → "Clan : %s"
.value(DataSource.of(clanName))
.build();
// Button
Button.builder()
.text("monmod.btn.rejoindre")
.command("clan join")
.build();
// KeyValueRow
KeyValueRow.builder()
.key("monmod.row.membres") // label à gauche
.value(DataSource.of("8 / 15"))
.build();
// ProgressBar
ProgressBar.builder()
.labelKey("monmod.bar.xp")
.value(0.45f)
.build();
// SearchField
SearchField.builder()
.placeholderKey("monmod.search.placeholder")
.onChange(text -> filtrer(text))
.build();
// TabBar
TabBar.builder()
.tab("monmod.tab.membres", () -> afficherMembres())
.tab("monmod.tab.stats", () -> afficherStats())
.build();
Titre d'écran
Le titre est passé au constructeur de l'écran :
// Cas normal — titre traduit
super(Component.translatable("monmod.screen.hub"), 260);
// Dev uniquement — texte brut (ne pas utiliser en production)
super(Component.literal("Debug Screen"), 260);
Interpolation avec %s
Quand une clé contient %s, la valeur fournie par DataSource est substituée :
{ "monmod.label.clan": "Clan : %s" }
Label.builder()
.text("monmod.label.clan")
.value(DataSource.of("Les Loups"))
.build();
// Affiche : "Clan : Les Loups"
Si la clé ne contient pas %s, la valeur .value() est ignorée — l'interpolation se fait uniquement via %s dans la clé.
KeyMappings
Les keybinds doivent aussi être traduits :
// Déclaration du keybind
new KeyMapping(
"key.monmod.open_hub", // clé i18n
GLFW.GLFW_KEY_H,
"key.categories.monmod" // catégorie dans les options
)
{
"key.monmod.open_hub": "Ouvrir le Hub de Clan",
"key.categories.monmod": "Mon Mod"
}
Clés internes fournies par la lib
Ces clés sont définies dans assets/apocalyinterface/lang/ et n'ont pas à être redéfinies :
| Clé | Valeur (fr_ca) |
|---|---|
apocalyinterface.scroll.position | Défilement : %s/%s |
apocalyinterface.screen.close | Fermer |
Fallback
Si une clé est absente de la langue active et de en_us.json, LocaleResolver affiche la clé brute (ex. monmod.label.titre). Aucun crash — pratique pendant le développement pour travailler sans lang files complets.