TranslatorScript

Willkommen in der Transport Fever Community

Welcome to the fan community of Transport Fever and Train Fever, the economic simulators of Urban Games. The community is free for you to share and inform yourself about the game. We cultivate a friendly and objective interaction with each other and our team will be happy to answer any questions you may have.

 

Registration and use is of course free for you.

 

We wish you a lot of fun and hope for active participation.

The Team of the Transport-Fever Community

  • [Blocked Image: http://ftp.train-fever.net/flaggen/de.png] (translation below)
    Hallo alle zusammen!


    Als mich @Rjoande darauf ansprach, dass er meine Signalmods ins Italienische übersetzen will, ist mir folgendes aufgefallen:
    Um einen Mod zu übersetzen, müssen alle Texte in den Modeldateien geändert werden. Also muss man auch für jede Sprache das Model extra bereitstellen.


    Ich bin kein Fan von redundanten Daten, daher habe ich mir einen Skript geschrieben, der das ganze einfacher macht. Nur noch eine Sprachdatei muss die jeweiligen Sprachen bereit gestellt werden - und eine einzige "Grunddatei" mit dem Model. Die komplette Anleitung findet ihr dann auf der Downloadseite des Skriptes.


    Wie findet ihr die Umsetzung? Habt ihr Fragen dazu? Immer her damit. Da es um Übersetzungen geht, bitte auf Englisch wenn möglich!


    Entwicklung wurde eingestellt!
    Durch die neuen Möglichkeiten des neuen Modding-Systems (strings.lua) wurde TranslatorScript überflüssig. Ich werde in den kommenden Tagen ein Tutorial für das neue System schreiben.


    Download ->
    Anleitung für Modder ->

    [line][/line][Blocked Image: http://ftp.train-fever.net/flaggen/gb.png]
    Hello everyone!


    When @Rjoande ask me for permission to translate my mods, I recognized one thing:
    To translate a mod, all texts in the model files must be changed. Because of that, a complete model file must be uploaded for each language.


    I hate redundant data, so I wrote a script to make it simpler. Only one language file (with only the translation) has to be uploaded per language. And only one single model file as base. The complete manual is written down on the download page of the script.


    How do you like it? Any questions? Please answer in english (if possible), because here everything is about translation.


    Development aborted!
    With the possibilities of the new modding system (strings.lua) TranslatorScript is unnecessary. I will write a tutorial for the new system in the coming days.


    download ->
    manual for modders ->

  • [Blocked Image: http://ftp.train-fever.net/flaggen/de.png] Es wird ab V2.0 auch nach einer Sprachdatei namens "_TRANSLATION.lang" im Ordner der *.mdl-Datei gesucht und dann ggf. daraus die Übersetzung entnommen. Es kann nur eine solche Datei pro Ordner geben! Daher vorsicht bei gemeinsam genutzten Ordnern!


    Es wird empfohlen, für jede einzelne *.mdl-Datei eine eigene Sprachdatei zu verwenden. Der Aufwand ist praktisch gleich und verhindert Überschreibung durch andere Mod-Übersetzungen (falls mehrere Mods im gleichen Ordner sind)! Daher werde ich dieses Feature nicht mit in die Anleitung mit auf nehmen.
    [line][/line][Blocked Image: http://ftp.train-fever.net/flaggen/gb.png] Since V2.0, TanslatorScript searchs a file named "_TRANSLATION.lang" in the folder the *.mdl is located and uses the translation defined there. It can only exist one such file! Beware in shared folders!

    It is recommended to use a single language file for each *.mdl-file!
    The effort is practically the same and prevents overwriting by other mod translations (if several mods are in the same folder)! Therefore, I will not include this feature into the manual.

  • Hallo @BR146,
    habe einen neugierigen :D Blick in Dein Skript geworfen und dazu, falls es recht ist, ein(ig)e Frage(n). ?(


    Du verwendest dort "package.path".
    Wo ist package definiert und ist es damit möglich den aktuellen Pfad des "res-Verzeichnisses" zu ermiteln?


    Auch nach längerer Betrachtung bin ich (leider :cursing: ) nicht dahinter gekommen, wie du die Dateien findest; ebenso das Öffnen dieser erschliesst sich mir nicht.


    Liebe Grüße
    Enno :)


    PS: Ach ja, fast hätte ich es vergessen. Welchem Zweck dient die Umwandlung bestimmter Charakter? Ich war der Meinung, TF unterstützt UTF8 und hätte dies nicht nötig. Irre ich mich hier?

    Auch ein alter Fuchs schaut gern ein Huhn, selbst wenn er's nicht mehr Reißen kann. ^^

    137505-jw4l0v-4-png

  • Lieber EAT1963, dass erkläre ich dir gerne:


    package.path ist eine von der LUA-Umgebung vordefinierte Variable. Sie beinhaltet die Suchparameter für Scripte. Durch das anfügen von '?.lang sucht jetzt LUA auch nach *.lang-Dateien.

    Zum Dateien finden:

    Code
    1. local ok, translation = pcall(require, langFileName():gsub("/", "."))

    Hier "öffne" ich die Datei. Um genau zu sein binde ich sie per Require-Befehl ein. Das pcall() unterdrückt Fehlermeldungen falls keine Datei existiert. Der Befehl require gibt mir als Rückgabewerte einmal einen Statuscode und einmal (hier in translation abgespeichert) den Wert, der per return aus der zu "öffnenden" Datei kommt. Das sollte auch der Aufbau der Lang-Dateien erklären .

    Zur Pfadermittlung:

    langFileName() macht das "Wunder". Es gibt mir den Pfad folgendermaßen aus: res/models/model/railroad/BR146/TEST/test

    local str = debug.getinfo(3, "S").source:sub(2) ermittelt mir dabei den relativen Pfad vom "res"-Verzeichnis aus zur aufrufenden *.mdl-Datei. Hier etwas zum lesen zu den Parametern: http://www.gammon.com.au/scripts/doc.php?lua=debug.getinfo
    Danach entferne ich nur noch die Dateiendung.


    gsub("/", ".") ersetzt mir alle "/" durch ".", denn so muss ich das an require übergeben (http://www.lua.org/manual/5.2/manual.html#pdf-require).


    Was passiert an einem Beispiel:
    debug.getinfo(3, "S").source -> @res/models/model/railroad/BR146/TEST/Crocodile_test.mdl
    :sub(2) -> res/models/model/railroad/BR146/TEST/Crocodile_test.mdl
    Rest -> res/models/model/railroad/BR146/TEST/Crocodile_test
    gsub() -> res.models.model.railroad.BR146.TEST.Crocodile_test


    [Anm.: langFilePath beruht auf der selben Methode, es wird nur noch hinten mehr weggeschnitten]

    Spezielle Zeichen:

    Naja, ich habe alles mögliche versucht um Ä,Ö,Ü usw. ins Spiel zu bekommen. LUA scheint alle eingelesenen Daten in einen 8-bit-Datenstream zu verwandeln. In UTF-8 bestehen Umlaute aus zwei 8-bit Zeichen. Im Spiel selber werden diese dann aber falsch interpretiert, wodurch komische Zeichen angezeigt werden. Wandle ich sie um, funktioniert es plötzlich. Es ist mehr oder weniger ein "Work-Around"....


    Wenn noch fragen sind, immer gerne stellen :D .

  • Es wäre genial, wenn wir die Sprachdateien aus den Model-Ordnern hinausbekommen könnten. Ich könnte mir vorstellen, daß alle Übersetzungen in einem bestimmten Ordner abgelegt werden. Eventuell kann man die Dateien da dann auch zusammenfassen. So kann man dann auch gezielter ein Backup der Sprachdateien machen.


    Innerhalb der Sprachdateien könnte man z.B. festlegen, für welche Modeldatei(en) sie Informationen beinhalten. So können dann auch Sprachpakete erstellt werden, die unabhängig von den eigentlichen Fahrzeugen sind.

  • Mhh, das trennen wäre soweit schon hilfreich. Nur wie trenne ich hier die Sprachdateien auf? Weil alle in einen Ordner werfen geht nicht. Weil sonst jeder Mod einen eigenen Namen dafür haben müsste. Meine Idee wäre, so zu verfahren wie bei den UI-Vorschaubildern: Die Dateien würden dann in res\strings\models rein kommen mit der selben Ordnerstruktur.


    Dateien da dann auch zusammenfassen

    für Modeldateien in einem Ordner geht es ja bereits schon. Nur darf der Ordner nur von einem einzigen Mod (oder einem zusammengehörigen z.B. wie bei meinen Sperrsignalen) verwendet werden.

  • Hallo @BR146,
    herzlichen Dank für die Informationen.


    Habe mir eine Debug-Ausgabe (debug.txt) "gebastelt" und konnte so schon einige Dinge nachvollziehen. Zumindest konnte ich sehen, was langFileName und langFilePath so zurückgeben.


    Was sich mir gar nicht erschliesst, sind die Parameter von debug.getinfo:


    Code
    1. ...
    2. debug.getinfo(3, "S").source:sub(2)
    3. ...


    Auf der von Dir verlinkten Seite und auch auf weiteren Seiten, auf welchen ich geschaut habe, kann ich einfach keine erhellenden Erläuterungen zu den verwendeten Parametern finden.
    Da wäre z.B. die 3 (getinfo(3...). Warum eine 3? ?(?(?(


    Ich muss gestehen, dass ich eher mit Pascal (Delphi) klarkomme und Lua nicht so beherrsche, auch wenn ich das Gro verstehe, was dort im Quelltext steht.


    Was ich vorhabe ist, den Pfad zum res-Verzeichnis AUTOMATISCH zu erkennen, ohne dass der Benutzer diesen erst eingeben muss, was einige überfordert.


    Liebe Grüße
    Enno :)

    Auch ein alter Fuchs schaut gern ein Huhn, selbst wenn er's nicht mehr Reißen kann. ^^

    137505-jw4l0v-4-png

  • 3? Ganz simpel erklärt:
    "The function name can be an integer representing the stack level, where 0 is debug.getinfo itself"
    Schauen wir uns mal den Call-Stack an:
    TF ruft data() auf, welche _() aufgeruft.
    _() ruft langFileName() auf, was wieder debug.getinfo() aufruft:

    Code
    1. data() -> '3'
    2. _() -> '2'
    3. langFileName() -> '1'
    4. debug.getinfo() -> '0'


    Verständlich?


    P.S.: Pfad zum res-Verzeichnis: schau dir mal die package.cpath an ;) , diese lautet bei mir:
    D:\Programme\Spiele\Steam\steamapps\common\Train Fever\?.dll;D:\Programme\Spiele\Steam\steamapps\common\Train Fever\loadall.dll;.\?.dll

  • Meine Idee war es, daß in einem Unterordner alle Sprachdateien ausgelesen werden.
    Dort könnte dann der relative Pfad zur mdl drinstehen und dazu die übersetzten Strings. Wie dann die Sprachdatei heißt, sollte egal sein.


    Ob das jetzt mit TF und so einfach Lua machbar ist, weiß ich natürlich nicht.

  • Wie dann die Sprachdatei heißt, sollte egal sein.

    Naja, nur ein Problem sehe ich da, z.B.:
    MOD 1 hat seine Sprachdaten in res\strings\models\translation_gb.lang
    MOD 2 hat seine Sprachdaten in res\strings\models\translation_gb.lang


    Der User installiert Sprachdateien für MOD 1. Jetzt downloaded er Sprachpaket für MOD 2 - und BÄM! jetzt wird überschrieben! Es dürfte dann keine 2 Mods mit den selben Sprachdatei-Namen enthalten...

  • Verständlich?


    Oh ja, das ist verständlich. Verstehe jetzt, was mit dem Stack gemeint ist. Hätte halt nicht gedacht, dass man erst mitzählen muss. Aber da es sich um eine Debug-Schnittstelle handelt ist das wohl verzeihlich. :D


    So schaut das ganze bei mir aus. Rufe alles aus der buildingutil.lua (mittels Kopien Deiner Funktionen) heraus auf, da ich da gerade herumgeistere.


    Code
    1. package.path: ?.lua;E:\Program Files (x86)\Steam\steamapps\common\Train Fever\lua\?.lua;E:\Program Files (x86)\Steam\steamapps\common\Train Fever\lua\?\init.lua;E:\Program Files (x86)\Steam\steamapps\common\Train Fever\?.lua;E:\Program Files (x86)\Steam\steamapps\common\Train Fever\?\init.lua;.\?.lua;res/scripts/?.lua
    2. package.cpath: E:\Program Files (x86)\Steam\steamapps\common\Train Fever\?.dll;E:\Program Files (x86)\Steam\steamapps\common\Train Fever\loadall.dll;.\?.dll
    3. langFileName: res/scripts/buildingutil
    4. langFilePath: res/scripts/


    Wenn in cpath der erste Wert IMMER den Pfad zum Programmverzeichnis behinhaltet, egal auf welchem Betriebssystem TF läuft, so kann ich damit durchaus etwas anfangen. Mal schauen.


    Nochmals meinen herzlichen Dank. :thumbsup:


    Gruß
    Enno :)

    Auch ein alter Fuchs schaut gern ein Huhn, selbst wenn er's nicht mehr Reißen kann. ^^

    137505-jw4l0v-4-png

  • Weil sonst jeder Mod einen eigenen Namen dafür haben müsste



    Aber hast du im Lexikon nicht geschrieben das die Sprachdatei nicht sowie so den gleichen namen haben muss wie der Mod an sich. Ein extra Ordner für die Sprachdateien wäre schon besser, da sonnst ein Ordner recht schnell überfüllt wirkt. Man (bzw.Du :)) musst es irgendwie schaffen das sich der Translation Mod seine Angaben aus einem anderen Ordner bezieht. Am besten ja gleich ein Sprachdateien-Ordner welcher sich im Unterverzeichnis das "res" Ordners befindet

  • Aber hast du im Lexikon nicht geschrieben das die Sprachdatei nicht sowie so den gleichen namen haben muss wie der Mod an sich.

    Nicht wie der Mod, sondern wie die *.mdl-Datei. Das ist ein Unterschied. Für jedes Kompaktsignal habe ich eine eigene Sprachdatei. Dieses Muster würde ich beibehalten. Ich arbeite gerade an folgender Umsetzung:


    Modelldatei: res/models/model/railroad/BR146/Beispiel/Crocodile.mdl
    Sprachdatei: res/strings/models/railroad/BR146/Beispiel/Crocodile.lang
    (Oder für einen ganzen Ordner eine Sprachdatei: res/strings/models/railroad/BR146/Beispiel/_TANSLATION.lang)

  • Der User installiert Sprachdateien für MOD 1. Jetzt downloaded er Sprachpaket für MOD 2 - und BÄM! jetzt wird überschrieben! Es dürfte dann keine 2 Mods mit den selben Sprachdatei-Namen enthalten...


    Ja, das ist logisch. Zwei Modelle haben aber auch nicht den selben Namen. Sinnvoll ist es also, Dateinamen zu verwenden, die beschreiben, was in ihnen steckt.
    Also medis_mods_translation_gb.lang oder so ähnlich.
    Zudem kann man ja die Namen der MDL-Datei trotzdem verwenden.


    Theoretisch könnte man für alle Sprachcodes dort auch Unterordner anlegen. Also GB oder IT ...

  • Theoretisch könnte man für alle Sprachcodes dort auch Unterordner anlegen. Also GB oder IT ...

    Wenn du mir sagst, wie ich die aktuelle Sprache aus LUA rauskitzeln kann ;) .


    Hier eine Preview: TranslatorScript V3.0.zip
    Die Dateien werden wie in meinem Beispiel oben abgelegt:

    Modelldatei: res/models/model/railroad/BR146/Beispiel/Crocodile.mdl
    Sprachdatei: res/strings/models/railroad/BR146/Beispiel/Crocodile.lang

  • Die Frage ist, ob es sich lohnt diese Unterscheidung zu machen? Natürlich könnte man dann die Sprachdateien direkt mit im Mod mitliefern...


    eis_os: diese Idee werde ich mal ausprobieren.


    Edit: _("Waypoint") liefert mit immer "Waypoint"... geht so also nicht. Ich habe bisher auch keine Variable gefunden, durch die ich die Sprache raus bekomme.
    Folgenden Code habe ich zum Testen mal in die "signal_waypoint.mdl" direkt nach function data() eingefügt:

    Code
    1. file = io.open("abc.txt", "w")
    2. file:write(_("Waypoint"))
    3. file:close()

    Habe als Dateiausgabe "Waypoint" erhalten :( .


    Ich überarbeite gerade die Anleitung. Ist der Abschnitt im Spoiler verständlich??? ([hl] steht für "Überschrift", die Zahl für die Tiefe der Überschrift)