Skip to content

Names in the player's own language: goods, ports, types and bands (#7) - #8

Merged
tastybento merged 8 commits into
developfrom
i18n-issue-7
Sep 4, 2026
Merged

tastybento merged 8 commits into
developfrom
i18n-issue-7

Conversation

@tastybento

Copy link
Copy Markdown
Member

Fixes #7.

A Chinese server owner reported that goods, fuel and hulls in the market are always English and that port names cannot be translated at all. Both were structural, and both are addressed here, plus the smaller leaks found on the way.

Items

ItemNames.label(user, material) replaces every PriceEngine.prettify(material.name()) a player could see. It returns the locale's own tradewinds.materials.<key> line when one is written, and otherwise a MiniMessage <lang_or:key:fallback> tag. BentoBox substitutes variables and then parses the string, so dialogs, GUIs, holograms and boss bars render the item in the client's language with no translation work at all. Chat, which BentoBox flattens to legacy, shows the English fallback unless the locale line is filled. en-US lists all 153 traded materials, blank by design. Enchantment names on the shelf go the same way. Player-given item names are now escaped before substitution: a sword named <red> used to restyle the dialog.

Ports

A port name is 2-4 tokens from the Elite digraph table. NameGenerator.tokens exposes them, and PortNames.display maps each through tradewinds.name-token.<syllable> in the viewer's locale, so a Chinese locale renders "Lave" in Chinese for every Chinese client, consistently. The canonical name stays the island's identity everywhere else (registry, resident tags, logs, admin commands); a 40,000-hash test holds name() byte-identical to the previous implementation. The star chart draws the transliterated name only when MinecraftFont can (it is ASCII bitmap and drawText throws otherwise).

The rest

Island type reached players as the raw enum in five places; three places used a hardcoded English band name; /tw prices prettified the category enum. All go through getLocaleKey() now, SecurityBand.getDisplayName() is gone, and LocaleKeyTest checks every enum constant, name token and traded material has a locale line.

Tests

629 pass (was 620). New: ItemNamesTest, PortNamesTest, three NameGeneratorTest cases, three LocaleKeyTest cases.

No hold, boat or ocean model change: no clean slate needed.

🤖 Generated with Claude Code

https://claude.ai/code/session_011kwguMkwTr1i1C8qxqrbYT

tastybento and others added 8 commits September 3, 2026 22:39
The market subtitle, warp tooltips, chart holograms and the chart and
admin listings printed the raw enum for an island's type (AGRICULTURAL),
three places still used a hardcoded English band name although
tradewinds.band.* has existed for months, and /tw prices prettified the
category enum. All of it now goes through getLocaleKey(), the English
display name on SecurityBand is gone, and the dash and question-mark
placeholders come from tradewinds.general too. LocaleKeyTest checks
every enum constant has its line. First of three commits for #7.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011kwguMkwTr1i1C8qxqrbYT
Every item name shown to a player was the material enum prettified, which
no locale could touch (#7). ItemNames now gives the locale's own line
(tradewinds.materials.<key>) when the translator wrote one, and otherwise
a MiniMessage lang_or tag: BentoBox substitutes variables and then parses
the string, so in dialogs, GUIs and holograms the client renders the
item's name in its own language for free, and chat, which BentoBox
flattens to legacy text, falls back to the English name. Enchantment
names on the shelf go the same way. Player-given item names are escaped
before substitution, closing a MiniMessage injection into the dialogs.
en-US.yml lists every traded material, blank by default, and
LocaleKeyTest keeps the list complete.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011kwguMkwTr1i1C8qxqrbYT
Port names are procedural, so no locale could list them (#7). Every
name is 2-4 tokens from the Elite digraph table, though, and a locale CAN
list those: NameGenerator now exposes the token sequence (its joined
name is byte-identical to before - a 40,000-hash test holds it to the old
implementation, because the name is the island's identity in every
existing world), and PortNames maps each token through
tradewinds.name-token.<syllable> for the viewer's locale. Every
player-facing line switches to the display name; the island registry,
resident tags, logs and admin commands keep the canonical one. The star
chart draws the transliterated name only when the map font can - it is
ASCII bitmap and throws on anything else - so a Chinese locale sees
Chinese names everywhere but the chart. The on token is quoted in the
locale: bare on/off/yes/no are YAML booleans.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011kwguMkwTr1i1C8qxqrbYT
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011kwguMkwTr1i1C8qxqrbYT
Variables are substituted and then the string is parsed as MiniMessage,
and the legacy flattener prints a translatable's fallback. Both are
checked against the real BentoBox Util so a core change fails the build
here rather than in a playtest.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011kwguMkwTr1i1C8qxqrbYT
… the locale

Playtest with a Chinese BentoBox locale and an English client (#7): the
spawn port read Spawn everywhere because its name is given, not
generated, so the token table never touched it - PortNames now maps it to
tradewinds.spawn.name. The outfitter's gear (rod, compass, iron kit, bed,
pickaxe, mutton) is code, not config, so the materials list and its
completeness test had missed it. And a boat's baked-in text - item name,
lore, floating label - was written with the console's locale; it is now
the owner's when they are online, and the hull's own item name goes
through tradewinds.item.boat-name so it follows the locale (or the
client) like every other material.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011kwguMkwTr1i1C8qxqrbYT
The border pane's six-clause instruction was one clipped line, in every
language (playtest 2026-09-04). Hold lore keys now split on newlines
into lore lines, the convention BentoBox's own panels use; each line
carries its own colour tags because an open tag does not reach the next
line. The border and TNT tooltips are rewritten as short lines.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011kwguMkwTr1i1C8qxqrbYT
Every key of en-US, checked by script for key, placeholder and tag
parity. Materials are filled with the official zh-CN item names so chat
lines name goods in Chinese too, the port-name syllables are
transliterated (the lone A is 亚 rather than 阿 so no two English names
can collapse into one Chinese one), and the spawn port is 出生港.
Requested in #7.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011kwguMkwTr1i1C8qxqrbYT
@tastybento
tastybento merged commit c597d0f into develop Sep 4, 2026
1 check passed
@tastybento
tastybento deleted the i18n-issue-7 branch September 4, 2026 14:14
@sonarqubecloud

sonarqubecloud Bot commented Sep 4, 2026

Copy link
Copy Markdown

@tastybento tastybento mentioned this pull request Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Please extend the translation document

1 participant