MotoGP: localization

The MotoGP menu system worked roughly like the XNA Framework Game State Management sample, but uglier because it was written in C with manual memory management and no events.

We translated the game into English, French, Italian, German, Spanish, and Japanese, using a similar approach to the XNA Framework Localization sample:

  • Text strings lived in an Excel spreadsheet, one column per language
  • We converted TrueType fonts into bitmaps using a program similar to this utility
  • The resulting bitmaps were built into spritesheet textures by a tool similar to the FontTextureProcessor
  • To avoid the Japanese font becoming ridiculously large, we only included the characters that were actually used in our translation strings

As the game was nearing completion, we kicked off the translation process:

  • Email the Excel file to our publisher
  • Publisher sends it on to a translation company
  • A week or two later, back comes a translated version
  • Hmm, the build fails…
  • For some reason the translators decided to reorder and rename several of the strings!
  • Spend a couple of hours fixing up the string names, until the build finally succeeds
  • Hmm, now the game crashes on startup…
  • For some reason the translators decided to turn “Player {0} got a score of {1}” into “Player <n> got a score of :2nd-placeholder”, which is upsetting our format calls!
  • Spend a couple of hours fixing up the format strings, until the game finally runs
  • Hmm, many of the translated strings are too long to fit on the screen…

We had to test the entire game to find which strings were too long in each language, then report back to the publisher, who reported back to the translator, who changed the translation to make it shorter, then sent the changes to the publisher, who sent them to us, who repeated the above process, only to find more problems. Rinse, lather, repeat.

As our ship date approached, we still had many translation errors. It was taking too long to turn around each batch of fixes.

Fortunately (and unusually!) the translation company was based just down the road from us. To speed things up, they sent a couple of translators over to our office, so they could spend an afternoon making changes directly in the master string table and immediately check the results. One of our programmers had to spend an afternoon helping them rebuild and test the game, but the Italian translator turned out to be young, female, and curvy in all the right places, so he didn’t mind too much  🙂

  • Italian: done!
  • Spanish: done!
  • French, German, and Italian: still a few strings that are too long
  • Expected turnaround on getting updated translations: one week
  • Ship date: two days away

In desperation, we added code that measured each string before drawing it, and compared against the destination screen area. If the string was too long, we automatically applied a horizontal scale to make it fit exactly. With the font we were using, we found we could shrink Latin1 characters to about 80%, and Kanji to 90%, before they became illegible. This was enough to clean up the last few problems, and allowed us to ship on time.

Comments (5)

  1. Metalov says:

    "but uglier because it was written in C with manual memory management and no events" Oh Shawn are you one of those who actually think OOP is so coool,much more convenient, and smarter ?IMO we’re losing hours & hours because of OOP and encapsulation writing getters and setters !

    It reminds me one of my teacher who used to warn us about goto ; i always wondered if he even wrote one assembly line … compiler output is full of jumps and if you call it unreadable why call yourself a programmer ?

  2. JoelBennett says:


    It’s not about OOP, it’s about having a language and tools that are a lot cleaner, and faster to work with.  Working with managed languages like C# is a dream come true – no more worrying about null pointers, allocating memory, deallocating memory, built in things for events, etc.

    If you are spending hours writing getters and setters, you are doing it wrong.  Even plain vanilla visual studio has refactoring tools to do just that for you.  Add-ons such as ReSharper make it even more efficient.

    You’re welcome to go back to using C and assembly, but I’ll stick with C# and XNA.  🙂

    P.S.: I think Shawn knows what he’s talking about.  He’s worked on how many games that have actually been shipped?

  3. ShawnHargreaves says:

    Metalov: I’m actually a big fan of multi-paradigm programming ( Different problems are best solved in different ways. For me, the most powerful programming languages are those that provides me with a wide range of tools, so I can select the most appropriate one for any given task.

    In this case I wasn’t actually talking about object oriented programming at all (although I generally would use objects when implementing a menu system: this is one case where I find objects tend to be a more natural fit than an imperative or functional style). I was actually talking about automatic memory management and events, though: two C# features that are independent of whether or not you use objects, but which I found made this kind of screen and menu management code much simpler and easier to work with.

  4. Metalov says:

    Ok I understand 🙂 But don’t get me wrong XNA is a pure wonder especially when it comes to productivity.With your great framework even learning students are able to produce stunning results in no time.One of my first book was "Michael Abrash’s Graphics Programming Black Book", I stil remember these days when we had no HW zbuffer,no directX, when it took pages & pages of assembly & C to do some basic things … while the book was very very instructive; I don’t want that pain back!

  5. paulecoyote says:

    That’s an interesting insight in to your localisation experiences, thanks 🙂  Slightly tangential, but do you know of any middle-ware that deals with that kind of thing? Something like Havok is to physics… something that solves localisation related issues.