Friday Facts #244 - Localised plurals & Modernisation progress

Posted by Klonan, kovarex, Posila on 2018-05-25

New Python developer (Klonan)

Mobile users may see that the website is significantly easier to read today, that is all thanks to our new Python developer Sanqui. Apart from making our website more mobile friendly, we have a lot of tasks on the backlog that he will start working on soon.

His first major task is to speed up and optimize the matching server, with which he is already making some progress. A bigger rewrite for the long term is underway, but in the last week he has reduced a lot of the slowness and timeouts people were seeing during peak times. He will be taking over our database management and web administration from HanziQ, as well as spending time cleaning up our codebase, maintaining our web services, and developing features for the mod portal.

Plural form localisations (kovarex)

Plural localisations are needed here and there in Factorio. For example, when the time is specified, it can be either 1 minute 5 seconds, or 5 minutes and 1 second, so there needs to be some system to select the correct word depending on the count.

In 0.16, we have this very specific custom system of specifying some of the translations by 3 different forms, while very specific code selects the correct one depending on the corresponding number:

English:
minute1=minute
minute2-4=minutes
minute5+=minutes
The English translators might be quite surprised, why do we need 2 different translations for plural of minute? The Czech people reading will understand, as the Czech localisation file looks like this:
minute1=minuta
minute2-4=minuty
minute5+=minut

Yes, we (Czech people) have a different kind of plural for count 2,3,4, than the other plurals.

The problem is, that we eventually discovered that there are other languages than English and Czech (!) and plural possibilities in other languages are not as simple as English only speakers tend to think. For a reference, here is the sum up of the common plural forms.

This made it clear, that having different translation key for every possible form for every language would be too crazy, so we invented something more generic. In 0.17, the translation of X minutes (the number is now included in the translation to allow to put it on different position, or to add some other word somewhere) will look like this:

English:
minutes=__1__ __plural_for_parameter_1__[1]__minute__[rest]__minutes__
Czech:
minutes=__1__ __plural_for_parameter_1__[1]__minuta__[2-4]__minuty__[rest]__minut__
Romanian:
minutes=__1__ __plural_for_parameter_1__[1]__minut__[ends in 01-19]__minute__[rest]__de minute__
etc.

Progress on engine modernisation (Posila)

The rewrite of the rendering framework goes well. We are at the point where the game looks exactly the same (with minor fixes to line rendering) as our main 0.17 branch, and the only major thing that is missing is proper error handling - for example, we don't want the game to terminate if a screenshot command fails for whatever reason. I was surprised at how many things we had to rewrite, but we took our time, and I think it is already worth it. The game rendering performs significantly better (well, at least on CPU side of the pipeline for now - more on that in some future Friday Facts) in both OpenGL and DirectX.

Speaking of which, some people were wondering why do we even bother with DirectX, and not just to use OpenGL everywhere. The reason is Windows is still the main OS for PC gaming and for some reason, we can't squeeze as much performance from OpenGL as we can from DirectX (we are seeing about 30% more time spent in calls to OGL as opposed to D3D). It also seems the OpenGL driver quality is all over the place. We already ran into the problem where our first implementation of building sprite atlases worked great on Windows and macOS, but was so inefficient on Linux it took over half an hour for the game to load.

We are actually trying to design the new rendering around architecture of current-gen APIs - Vulkan/Metal/DirectX 12 - and in future we would like to create Vulkan and Metal backends, but we are focusing on older APIs first as a large portion of our current player-base doesn't have Vulkan capable hardware. By using OpenGL 3.3 Core and DirectX 11 feature level 10.0, we should cover 99% of our current players (according to our Steam hardware survey statistics). These APIs should be supported by any dedicated GPU manufactured in the past 10 years, and integrated Intel HD Graphics since Sandy Bridge. We'll still leave 1% of players behind, so they are going to be stuck with 0.16, similar to when we dropped 32-bit support, but everybody else should benefit from better performance and hopefully a better looking game eventually.

As always, let us know what you think on our forum