Anima: UNICO – Crowdfunding on its way

As you may have seen, this last month the development of Anima: UNICO has slowed down a lot. That’s the thing about hobbies: they get the last spot on the priority queue. I would like Anima: UNICO to get to a better position in that queue. And, for that, it has to rise from “hobby” to “work”. And, nowadays, that means CROWDFUNDING!

Soon (I’m still missing some pieces) I’ll launch a crowdfunding campaign through IndieGoGo, with the objective of speed up the development of Anima: UNICO, and in case the campaign goes extremely well, to expand a little its scope.

I would love to hear your opinions and suggerences.

Making of Anima: UNICO – Localization

Here I am again. Today I am going to address a tricky issue: localization, this is, translating the application to other languages. Just from the start, there are several issues with the process.

I can’t just translate every game term to other language: I have to find and use the word used in the official translation. Luckily, I count with the great help of Vincent ‘Moklo’ Bouscarle, corrector of the French edition of the game, who is translating A:U to French, and Andre ‘Dynaes’ Reich, from the English forum, who is translating to English. I want to use this chance to, again, thank both for their help.

As I have explained before, Anima: UNICO is designed mostly in three layers. Model layer organizes information. Controller layer knows the models and the views and manages the generakl workflow of the application. The View layer gets data from the Controller and shows what the user sees in the screen. Only this layer has to be translated.

My solution

function setIdiomaUI() {
   var lang = navigator.language || navigator.userLanguage;
   
   if ((lang.lastIndexOf("es") != -1) || (lang.lastIndexOf("spa") != -1)) {
      IDIOMA_UI = SPA;
   } else {
      IDIOMA_UI = ENG;
   }
}
function L(id, spa, eng) {
   this.id = id;
   this[SPA] = spa;
   this[ENG] = eng;
   if (!diccionario["ANIMAUNICO_"+this.id]) {
      diccionario["ANIMAUNICO_"+this.id] = this;
   } else {
      console.log("Clave de diccionario repetida: [" + this.id + " / " + this[SPA] + " / " + this[ENG] + "]");
      console.log("--Clave previa: [" + diccionario["ANIMAUNICO_"+this.id].id + " / " + diccionario["ANIMAUNICO_"+this.id][SPA] + " / " + diccionario["ANIMAUNICO_"+this.id][ENG] + "]");
   }
}
L.prototype = {
   constructor: L,
   toString : function() {
      return this[IDIOMA_UI];
   },
   getId : function() {
      return this.id;
   }
};
function _l(clave) {
   if (diccionario["ANIMAUNICO_"+clave]) {
      return diccionario["ANIMAUNICO_"+clave].toString();
   } else {
      return clave;
   }
}

A bit of explanation: I have a class, L, that will be instantiated with every string to translate and its translations. I also have a function, _l, that gets the id of a string and returns the translation to the current user interface language. The Model and Controller layers work only with the id of the strings, which are unique. When the View layer shows any string in screen, it does so through the _l function.

The initialization of strings is like this:

var UI_DAÑO_FINAL = (new L("UI_DAÑO_FINAL","Daño final","Final Dmg.")).getId();
var UI_VELOCIDAD = (new L("UI_VELOCIDAD","Velocidad","Speed")).getId();
var UI_TURNO_FINAL = (new L("UI_TURNO_FINAL","Turno final","Final Init.")).getId();

As you can see, this is only for spanish and english. When the french localization starts, I’ll just have to add another field to the class L and another argument to every string.

Obviously, this solution still has several problems. For example, it is not specially good to form sentences with several variable parts, as it does not account for sintactic differences between languages. But for a character sheet, that will mostly show isolated terms, it is working well enough for me.