Localization & UX · July 6, 2026
Localizing a Shmup: Text Expansion, Fonts, and String Management
A shmup has less text than an RPG, but the text it does have is packed into small, fixed UI elements — score readouts, stage-clear banners, weapon names — and those are exactly the places translation breaks first.
Published July 6, 2026
Most solo developers treat localization as a late-stage checkbox: export the English strings, send them to a translator, import the results, ship. The problem shows up the moment those strings come back longer than the boxes built to hold them. German runs 20-30% longer than English on average. French menu labels routinely blow past a button that was sized for "PAUSE." A shmup's UI is dense and often screen-edge-anchored, so there is little slack to absorb the overflow gracefully.
Never hardcode layout to string length
The single biggest source of localization pain is UI built around the pixel width of the English source text. A weapon-select label centered under a fixed-width icon works fine at "LASER" and breaks at "LASERSTRAHL." The fix is to lay out UI with dynamic measurement — measure the rendered string at runtime and center, scale, or wrap based on that measurement, never on a value baked in during development. This is more setup work upfront but it is the difference between a translation pass that takes an afternoon and one that requires touching every screen by hand.
Font size scaling is a reasonable fallback for tight spaces (shrink text that doesn't fit rather than truncate it), but it has a floor — below a certain point players can't read status text during fast bullet patterns, which defeats the purpose. Truncation with an ellipsis is worse in a genre where players need full information at a glance; a truncated power-up name mid-boss-fight is a real usability problem, not a cosmetic one.
Fonts are not one-size-fits-all
A pixel font hand-drawn for the Latin alphabet almost never has the glyph coverage for Polish diacritics, Turkish dotless-i variants, or Japanese kana, let alone CJK ideographs. Before committing to a language list, check what each target language actually needs and confirm your font (or fallback font) covers it. Bitmap fonts in particular need this checked glyph by glyph, since there's no automatic fallback the way there is with a system font stack on the web.
For languages that need a genuinely different script, plan for a second font asset rather than trying to force one typeface to cover everything — a stylized pixel font that reads well in English usually looks broken rendering kana or Cyrillic, and it's cheaper to ship a matched secondary font than to redesign the primary one around every alphabet you might someday support. The Unicode CLDR project is worth bookmarking here — it publishes locale data (plural rules, date formats, collation order) that covers far more edge cases than most teams think to test for themselves.
String management: get this right before you localize
Every user-facing string should live in a lookup table keyed by an identifier, never inline in code as a literal. This sounds obvious but shmups accumulate UI strings fast — combo labels, rank titles, achievement text, options-menu tooltips — and it's easy to let a few slip through as hardcoded English, especially in code written under jam-style time pressure. Once localization starts, every one of those becomes a manual find-and-fix instead of a translation-file entry.
Keep context notes attached to each string ID for the translator: is "CONTINUE" a menu button or a countdown prompt? Those two uses need different words in most languages, and a translator working from a bare spreadsheet has no way to know which is which without playing the build. A short note next to each key ("shown on pause menu, max 8 characters") saves multiple review round-trips. The W3C's Internationalization Activity publishes general guidance on this kind of string-context practice that applies well beyond web content.
Test with pseudo-localization before the real translations arrive
Pseudo-localization — programmatically expanding every string by roughly 30% and wrapping it in accent marks — catches layout bugs weeks before a human translator ever touches the project. Run your build through a pseudo-localized string table and walk every menu; anything that clips, overlaps, or truncates gets fixed while it's still cheap to fix, rather than during a translation review when the clock is running and a paid translator is waiting on your reply.
Related work worth reading alongside this: the layout discipline described in accessibility features for indie shmups overlaps heavily with localization — both force you to stop assuming a fixed pixel width for every label. And if you're tracking how players actually use each language build, the setup covered in telemetry and analytics for indie games is the cleanest way to find out whether a locale is worth the ongoing translation cost before you commit to maintaining it long-term.