The item list is sorted in an order that looks wrong to players
A player looks at an alphabetized item list, a leaderboard of names, or a character-select screen and something is off: names that should be adjacent are far apart, accented letters cluster at the wrong end, or the order simply does not match what they'd expect from a phone book or dictionary in their language. Nothing is broken in the technical sense — every string displays correctly, nothing is missing or garbled. The sort order itself is wrong for the language it's being shown in.
This is a different category of bug from most localization issues, because the text is not the problem — the comparison function is. Fixing it means understanding what alphabetical order actually is: a locale-specific convention, not a property of the characters themselves.
Byte order and code point order are not alphabetical order
A naive sort compares strings by comparing their underlying character codes one position at a time — this is what a plain string comparison operator does in most languages, including JavaScript's default Array.prototype.sort(). That produces a real, deterministic order, but it is the order of the character encoding, not the order native readers of the language use.
The clearest failure case is capitalization and accents: in code point order, every uppercase Latin letter sorts before every lowercase one, so a word like Zebra sorts before apple — which is not how any human alphabetizes. Accented letters sit at whatever code point Unicode happened to assign them, which is rarely adjacent to their unaccented base letter, so café and cafe can end up far apart in a list where a reader expects them next to each other.
["café", "cafe", "Zebra", "apple"].sort(); // → ["Zebra", "apple", "cafe", "café"] — code point order, not alphabetical // uppercase Z sorts before lowercase a; café's accent puts it after cafe
Collation is locale-dependent, not universal
The rules for what counts as correct order — called collation — differ by language and are standardized per-locale rather than being one global rule. Where a language places accented letters, whether case is ignored, and how punctuation and digits interleave with letters are all locale decisions. A comparison that produces the right order for one language can produce a visibly wrong order for another, even on the exact same list of strings, if only the display language changes.
Japanese ordering: kana and kanji need separate handling
Japanese text adds a layer naive sorting cannot handle at all: kanji have no inherent phonetic order by their character code, so sorting kanji strings by code point produces an order with no relationship to how a Japanese reader would alphabetize them by reading (yomigana). Lists of Japanese names or terms are conventionally ordered by their kana reading, in gojūon (aiueo) order — which means the sortable key is not the displayed string itself but a separate reading associated with it.
This has a direct consequence for how you structure data: if your game shows Japanese names or item titles and expects them to sort sensibly, you need a reading (furigana/kana) stored alongside the kanji text to sort by, because the kanji characters alone do not carry that information.
- Kana-only text sorts reasonably well by locale-aware comparison alone, in gojūon order
- Kanji text needs an associated kana reading as the actual sort key — the kanji code points do not encode pronunciation
- Mixed lists (kana + kanji + Latin, common in item names) need a locale-aware collator applied consistently, not per-entry special cases
The fix: use a locale-aware collator, not a naive comparison
The general-purpose fix is to stop comparing strings directly and use a comparison built specifically for collation, configured with the target locale. JavaScript's Intl.Collator (part of the ECMAScript internationalization API, backed by CLDR collation data) does this without a dependency, and produces correct capitalization- and accent-aware ordering per locale automatically.
const collator = new Intl.Collator("de");
["café", "cafe", "Zebra", "apple"].sort(collator.compare);
// → ["apple", "cafe", "café", "Zebra"] — case-insensitive, accent-aware order
// Different locale, different valid order for the same list
new Intl.Collator("sv").compare("z", "ö"); // Swedish sorts ö after zPrevention
Any list that sorts player-facing, translatable strings — names, item titles, chat, leaderboards — should route through a single locale-aware comparator keyed to the active display language, never a default or hardcoded-locale comparison. For Japanese specifically, make sure names and titles carry a kana reading field wherever sortability matters; retrofitting it after launch means backfilling readings for every existing entry. Test sort order with a real native speaker of at least one non-Latin-alphabet language before shipping a list feature — an order that looks fine to you can be visibly wrong to them, with nothing in the UI hinting at why.