Russian plurals and cases: why a two-form template always breaks
Any localization pipeline that has been tested against Russian tends to develop a healthy respect for the language, because Russian breaks assumptions that hold for almost every Western European language a team is likely to have designed around first. Two features in particular cause the most damage when discovered late: plural forms, and grammatical case changing the shape of nouns depending on their role in a sentence.
Plurals: more than singular and plural
English has two plural categories: one for the count 1, and 'other' for everything else, including 0. A template like '{n} item' / '{n} items' covers all of English with two strings. Russian has more categories than that, and the Unicode CLDR plural rules — the standard reference for how many plural forms a language needs and which numbers fall into each — define four for Russian: one (numbers ending in 1, except those ending in 11), few (numbers ending in 2–4, except 12–14), many (numbers ending in 0, 5–9, or 11–14), and other, used for certain fractional values.
Concretely, this means 1 item, 2 items, 5 items, and 21 items in Russian each potentially require a different word form: 1 предмет, 2 предмета, 5 предметов, 21 предмет — note that 21 reverts to the 'one' form because it ends in 1, while 11 does not, because it falls in the 11–14 exception band. A template hard-coded for two forms simply has no slot for three of these four cases; it will either crash, fall back to English pluralization logic that produces wrong Russian, or silently ship grammatically incorrect text.
Cases change the noun itself, not just what surrounds it
Russian is a case language: nouns, along with their adjectives and articles-equivalent modifiers, change form depending on their grammatical role in the sentence — subject, direct object, possession, and so on, across six cases (nominative, genitive, dative, accusative, instrumental, prepositional). This matters directly for localization because an item name is rarely inserted into a sentence in its dictionary form. 'You found a sword' uses the accusative form of sword (меч); 'no swords remaining' uses the genitive plural (мечей); 'fight with a sword' uses the instrumental (мечом). These are not stylistic variants — they are different words derived from the same root, and using the wrong one is a grammatical error a Russian reader will notice immediately.
A localization database that stores only one form per item name cannot correctly fill every sentence template it gets substituted into. Full correctness requires either storing multiple case forms per noun, or restructuring sentences so the noun always appears in the same case regardless of context — the second option is often more practical for game UI than a full declension table, but it constrains what your source-language templates are allowed to say.
Script and font coverage
Russian is written in Cyrillic, a distinct script from Latin with its own letterforms — а, б, в, г, д and so on are not stylistic variants of Latin letters, they are separate glyphs. Any font used for Russian UI text needs an actual Cyrillic character set; a font that silently falls back to a default system font for unsupported glyphs will produce visually inconsistent text, mixing your intended typeface for Latin characters with a fallback for Cyrillic ones. This is worth checking explicitly rather than assuming a font 'probably' covers Cyrillic.
ICU MessageFormat plural syntax as the portable fix
The practical answer to Russian's plural categories is to stop hard-coding plural logic in application code and instead use a message format that expresses plural branching declaratively, per language, so the correct number of forms is defined once for Russian and once for every other language, each with exactly the categories that language needs. ICU MessageFormat plural syntax is the widely adopted standard for this: a translator (or a translation file) provides one branch per CLDR plural category the target language actually uses, and the runtime library selects the correct branch based on the number and the current locale's plural rules — the application code that renders the string never needs to know how many plural forms Russian, Arabic, or English requires.
- Never hard-code two plural forms (singular/plural) for a string that will be translated into Russian
- Use CLDR plural categories (one, few, many, other) as your data model for plurals, not a boolean
- Store or generate the case-appropriate form of item names for each sentence template that inserts them
- Verify your font's Cyrillic glyph coverage explicitly; don't assume system-font fallback is acceptable
- Adopt ICU MessageFormat (or an equivalent declarative plural syntax) rather than per-language if/else logic in code