Why translation sucks, and TruckersMP don't do them anymore

After 3 years, TruckersMP stops accepting new translations, and once sufficient change has happened, will cease to allow you to change language on the website.

Now, 2 years ago, I started the work of rebuilding the website from the ground up, and with that I attacked the problem of translations. Prior to this, it was done purely via GitHub merge requests by users who didn’t know git, nor how PHP worked, less than ideal. My work started then by reviewing tools and learning a lot of them, including “bare metal” tools like gettext. But eventually the options stood between the open source tool Pootle or the commercial, hosted option Crowdin.

I decided for Crowdin since I didn’t want to sit around babysitting another system while also developing a website from the ground up, and maintaining an existing codebase, doing necessary fixes(yes, this was the deciding factor for this). At the time my experience with translations was very limited and mostly at the translator side. But now, 2 years later, I can say that I at least understand many of the difficulties that translations introduce, and that management of translations, especially in accepting community translations, is why we’re stopping now.

Out of 35 Languages (well, 34 if you don’t count “English(upside down)”), 30 languages was included on the website, all thanks to community translations. At the other end of the spectrum, 40% of all 500 errors where caused by translations that where performed incorrectly. Here is the crux of the problem; you will need proof readers who both understand the language well, and has an understanding of how translations work in your application. If you are getting paid for the job, obviously, you’ll be doing what the client wants, just make sure you factor this in, but if you’re a hobby project, you either need to love this part of the job immensly, or I’d strongly suggest avoiding this and not touch the topic with a 10 foot pole.

TruckersMP uses Laravel, and Laravel in turn uses Symfony’s translation module in the back, at first glance, it might seem sensible, but then you come to edges like this:

{0} No players in queue|{1} :players player in queue|[2, Inf] :players players in queue

Now, you may say, “That’s not so bad, you don’t need to have 3 clauses!”, well, yeah, in English you’d be right, but other languages, not so much. You’d also be surprised to learn that the “I” in “Inf” is case sensitive…

This is just one example of one specific framework, but I’ve seen similar horrors in other systems as well, apearantly that multiple range syntax is fairly common, for some god damned idiotic reason.

If you’re starting a new project, do split strings into translation files, it’ll keep it nice and pretty, and should you wish to translate it in the future, the worst part of the job is done at least, but unless it’s paid and the spec require it, don’t do it.

As a side note, if you are in the boat of having to translate, you might look at Microsoft, Apple, Logitech, or any of the other huge companies around, and how they put the language key in the URL. If you have a slight inkling that users might share links, don’t do that, or prioritize their accept headers over the language key in the URL, and make absolutely sure that you redirect to the same page in that language, or English(or the company’s regional language if English isn’t the main one). That’s a thing I didn’t think about, and considering a large number of our userbase is Turkish, we got a lot of links with the Turkish language key in it, and user’s translations where switched to Turkish as a result, no fun.

One other thing, use ISO 639-1/2/3 language codes (2 or 3 letter ones), eg. no, nb, tuk, eng, rather than IETF ones, eg. en_US, no_NB, etc. 1. it’s easier to find, and 2. they are properly standardized.