Ungewöhnlich hoher RAM-Verbrauch von TPF2 führt zum Absturz des Spiels / OS

Willkommen in der Transport Fever Community

Wir begrüßen euch in der Fan-Community zu den Spielen Transport Fever und Train Fever, den Wirtschaftssimulatoren von Urban Games. Die Community steht euch kostenlos zur Verfügung damit ihr euch über das Spiel austauschen und informieren könnt. Wir pflegen hier einen freundlichen und sachlichen Umgang untereinander und unser Team steht euch in allen Fragen gerne beiseite.

 

Die Registrierung und Nutzung ist selbstverständlich kostenlos.

 

Wir wünschen euch viel Spaß und hoffen auf rege Beteiligung.

Das Team der Transport-Fever Community


  • Ich behaupte einfach mal, das die Fahrplanmod programmiertechnisch absoluter Müll ist. Ein lächerlicher Scriptmod welcher mit -im Prinzip- nichts weiter als ein paar Zahlentabellen, 20GB RAM zumüllt, würde ich mir nie antun.

    Ryzen 5700X3D, RX 9070, 32 GB RAM

  • Um einen Fehler zu kritisieren, muss man doch erst die nötige Kenntnisse haben, um den Fehler zu erkennen.

    Per se etwas als fehlerhaft zu bezeichnen, ist schon etwas anmaßend!


    Du kannst entscheiden, ob Dir ein Essen schmeckt oder nicht, aber dem Koch einen Fehler vorzuwerfen, wenn man selbst nicht kochen kann, funktioniert dann allerdings nicht...

    Der Mensch ist nicht das, was er vorgibt zu sein - er ist das, was er verbirgt!

  • Ich benutze die Version 1.2 Station Fix und habe damit keinerlei Probleme, mit der 1.3 hatte ich dagegen auch Abstürze.

    Ich habe jetzt die Version 1.3 gefixt, wobei ich nur relativ wenig am Code geändert habe. Im Endeffekt habe ich nur ein paar Vorschläge hier im Thread umgesetzt und habe zudem zwei getrennte Skripte für GUI und Engine gemacht. Das dürfte auch das künftige Debuggen erleichtern. So kann ich gezielt das GUI oder die Zugsteuerung ausschalten und sehen, von welchem Teil das Problem stammt.

    PS: Die aktuelle Änderung aus Github ist in meinem Fix schon mit eingearbeitet.

  • Celmi ist schon seit Mitte 2021 nicht mehr für TPF2 aktiv. Bei dem Steam Eintrag "Fahrpläne 1.3" ist Gregory365 der Hauptautor, auch wenn Celmi in der Autorenliste oben steht. Nur der Hauptautor kann bei Steam Updates hochladen.


    Gregory365 scheint also aktiv zu sein und sein Github Repo ist der einzige aktive Fork. Daher wäre es sinnvoll, Diskussionen und Fixes dort zu platzieren.


    MarkMcWire Schön, dass du die Mod verbessert hast. Wenn du das Interesse hast, dich mit Github zu beschäftigen, damit deine Änderungen nachhaltig für alle zur Verfügung stehen, wäre es schön wenn du die Änderungen dort einbringst. Dazu musst du einen Fork von dem Repo erstellen, dann deine Änderungen auf Basis der aktuellsten Version comitten, und einen Pull Request zum originalen Repo erstellen. Bei Fragen zu Git, schreib mir gerne.


    Vielleicht ist das der Nachteil des gitHub-Konzeptes: Du bist gezwungen, fremden Code, in den du dich mühsam einarbeiten musst, zu übernehmen, weiterzuentwickeln und vor allem zu pflegen.

    Nur weil man etwas auf Github stellt, "muss" man es nicht maintainen - siehe Celmi.

    Einarbeitung in fremden Code ist immer anstrengend, aber am Ende ist es doch besser wenn alle an einer Sache gemeinschaftlich arbeiten, als wenn es 20 verschiedene zip files irgendwo gibt und man nicht sehen kann, wo die Unterschiede sind. Wenn man alleine arbeitet, kann man Versionskontrolle vielleicht noch gerade so selbst managen, aber bei kollaborativem Arbeiten liegen die Vorteile von Github auf der Hand. Man kann alle Änderungen auf einen Blick nachverfolgen und kontrollieren. Und solange der Owner mitspielt, fließen Erweiterungen von anderen direkt ins Hauptprojekt ein, wovon alle profitieren, die Änderungen auch beim nächsten Update noch drin sind, und sich nicht die Frage stellt, wo kann/darf ich das als separate Version hochladen.




    Ich habe eine Lösung gefunden. Ich habe das Script res/config/game_script/timetable_gui.lua in zwei Dateien aufgeteilt. Die original-Datei verwaltet nur noch das Interface und dessen Eingaben.
    Das neue Script res/config/game_script/timetable_engine.lua verwaltet die Ausführung des Fahrplans und die Steuerung der Züge.

    Das finde ich interessant, weil ich das bei mir auch so gemacht habe

    Trennung von Logik/Berechnungen und Gui ist halt irgendwie Standard... Die game_scripts sind da irgendwie unflexibel und auch nicht intuitiv: Dieselbe Lua Datei wird in 2 Threads parallel geladen mit denselben Variablen, die dann 2x existieren, aber in Engine und Gui Thread werden jeweils andere Funktionen aufgerufen. Nur die "load" function wird in beiden aufgerufen. Das kann zu Problemen führen, siehe Game Script => Save function, Unerklärliches verhalten




    Ich behaupte einfach mal, das die Fahrplanmod programmiertechnisch absoluter Müll ist. Ein lächerlicher Scriptmod welcher mit -im Prinzip- nichts weiter als ein paar Zahlentabellen, 20GB RAM zumüllt, würde ich mir nie antun.

    Wie "sauber" eine Mod lua-seitig aussieht und welche Probleme im Spiel dadurch entstehen können, hat absolut nichts miteinander zu tun! Ich kann dir Mods schreiben, die mit 2 Zeilen random Crashes produzieren und gleichzeitig gibt es hier Mods, die programmiertechnisch eine Katastrophe sind (zB 1000 Zeilen was auch in 10 Zeilen geht), aber fehlerfrei laufen. Es geht hier nicht um Konzeptfehler in Mods, sondern um nicht-offensichtliche Probleme in der TPF2 Engine. Wenn es offensichtlicher Design Fehler der Timetable Mod wäre, dass Datenmengen unkontrolliert im Lua Code angehäuft würden, wäre der Fehler schon längst gefunden.


    Hier ein ähnliches Beispiel, wie eis_os genannt hat: https://github.com/IncredibleH…TPF2-Timetables/issues/50

    Woher soll ein Modder wissen, dass ein simpler API Aufruf nur in bestimmten Situationen einen random Crash erzeugt?

  • Auf den Fork hatte ich schon verwiesen.


    Das liegt an der Natur der Sache wenn man mit Pointern arbeitet eines Iterators.

    Noch schlimmer wird es wenn du einen Crash erzeugen kannst,

    wenn du Daten von der API erhältst und dann nicht wieder in die selbe API kippen darfst.


    Mein VehicleScript Objekt in LUA darf eine Kopie der Daten machen damit ich einen Zug ändern kann. Alle anderen Versuche haben da Fehler produziert.


    Wenn man dann keinen Support durch UG erhält , bzw. der Support selber nicht weiß warum etwas passiert, ist das etwas bescheiden.


    Zum Beispiel hat die UI des Build Cursors (zum Akzeptieren/Abbrechen) einen eigenen UI Manager. D.h. Angebunden UI Elemente müssten theoretisch eine eigene LUA Runtime erhalten, damit da nix durcheinander kommt.


    Es gibt bei UG wohl geschätzt zwei Angestellte, dir das beantworten könnten.


    Man kann mit einer instabilen API nicht arbeiten. Wenn man nicht viel Zeit investieren möchte, bleibt eigentlich nur die Entwicklung eines Mods nicht weiter zu verfolgen. Das API Funktionen offensichtlich kaputt gemacht werden ist dann noch ein anderes Thema. UGs Lösung. Der LUA Thread wird ohne Fehlermeldung abgebrochen! Sehr toll beim Debuggen...


    Das ich offensichtlich Böse werden muss und das an die große Glocke hängen muss, das ist dann auch Übel.


    Beispiel: mod.lua Parameter Crash bei doppeltem Key. Das hätte UG debuggen können, es war Ihnen egal. Irgendwann musste ich sehr unfreundlich werden, weil CommonAPI2 immer beschuldigt wurde, diesen Fehler zu produzieren....




    Hier ein Beispiel, das nirgends im "Handbuch" steht und recht schnell komplex wird:


    Du darfst keinen Zeiger zu Entity Daten über GameScript Funktionsgrenzen halten.

    Warum?


    Nehmen wir an UG, bindet via Sol eine API, der dir zu einem c++ vector<irgendwasausdenentitysystem> zeigt.


    Du baust dann ein sehr einfachen LUA code


    local d = getIrgendEtwasAusDemEntitySystem()

    p = d[1]


    <Aufruf nach einem Update der UI>

    print(p.irgendwas)



    Was ist nun p?

    Ein sol Objekt das auf ein Element im Vector im Arbeitsspeicher zeigt, ggf. ist es ein Const Pointer. Sprich du darfst es selber nicht mal ändern über die Schnittstelle.


    Was passiert wenn du nun d irgendwie änderst durch eine andere API, du fügst ein Element hinzu?

    - Wenn der C++ Vector noch groß genug ist, bleibt alles gut

    - Wenn der C++ Vector nicht groß genug ist, wird ein neuer Speicher alloziert und die Daten + das neue Element dort hin kopiert. p ist nun im Eimer.


    In C++ heißt es, das Iteratoren oder Pointer invalid werden, das bekommt man aber nirgends zur Laufzeit mitgeteilt. das steht im Handbuch deiner STL Library deines Compilers.


    Ok, du sagst ich ändere ja im UI Thread mit keiner API diesen vector.


    Was passiert aber nach dem Aufruf einer Funktion im UI Thread deines GameScript?


    Vielleicht erst mal gar nichts, weil das Teil im UI Bereich liegt, aber wenn durch Userinteraktion irgendwo der Vector verändert wird?


    Dein LUA Sol Lua Objekt zeigt nun ggf. auf einen validen anderen Eintrag, ggf. auf etwas anderes im Arbeitsspeicher oder gar nichts. Bravo, dein Game Script im UI Thread ist instabil geworden.


    Was passiert wenn dein Pointer auf Entity Daten zeigen?

    - GameScript UI Funktion wird aufgerufen

    - Spiel läuft weiter

    - Neue Daten werden von Simulations/Script Thread -> zum UI Thread kopiert.

    - Deine UI Funktion wird aufgerufen.

    - p.irgendwas

    *Kaboom*


    Für LUA und SOL hat sich eigentlich nichts geändert.


    Nunja, aber die Welt drumherum hat sich massiv geändert, du hast eine neue Kopie der Daten im Arbeitsspeicher an ggf. einem ganz anderem Ort!

    Dein Pointer zeigt irgendwo hin...


    Schauen wir mal das ganze bei einem Game Tick an:


    -GameScript Simulations Thread Funktion wird aufgerufen:

    - Spiel läuft weiter

    - <irgendwas passiert hier>

    - Deine Funktion wird erneut aufgerufen.

    - p.irgendwas

    *Kaboom*


    Jetzt die große Frage? Passiert das ständig, nein. Wenn deine Daten im Vector immer noch am selben Platz liegen kannst du 1000 Spieljahre durchlaufen lassen, dein Mod funktioniert. Ist p.irgendwas als Integer gebunden, bekommst du halt mal falsche Daten. Als float, kann es dir passieren das du den Pointer als Float nicht lesen kannst. Das mag dein CPU gar nicht und du bekommst ein Exception.


    Du hast nun ein Spieler, der 1 Zug mehr hat oder irgendwas macht. Der Vector muss größer werden und liegt an einem anderen Platz.


    Und nein, das kann dir auch keine KI richten oder erklären...

  • Mag ja sein, dass im Hauptprogramm nicht alles optimal programmiert ist (könnte ich auch nicht beurteilen, zu viel Fachchinesisch ;)), aber wenn offensichtlich ausschließlich eine einzige Mod, die von Anfang an einige bislang nicht behobene Bugs aufweist, instabil läuft, läge es zumindest nahe, das Problem zunächst dort zu suchen.


    Was das Handling der Threads betrifft, ist das in der Tat ein ziemliches Gewusel. Ich sehe das Problem in der Synchronisation, aber das ist mit viel Ausdauer in den Griff zu bekommen. Wenn in meinen Skripten was abgestürzt ist, dann aus Unwissenheit und manchmal auch Schlampigkeit, aber eigentlich nie, weil das Hauptprogramm Mist baut. Was anderes sind Lags, zu denen das Hauptprogramm tatsächlich seinen Teil beiträgt, aber auch die sind mit Workarounds einigermaßen in den Griff zu bekommen. Und dann gibt es noch einige wenige API-Befehle, die wirklich buggy sind, und die muss man halt kennen.

    Ich will TpF3 mit Dinos, Zombies und Vulkanen!

  • Ganz simple einfache Fragen:


    Wenn UG die API Funktion der UI ändert via Update, nun einen anderen Art Parameter erhalten möchte und das nicht im Changelog vermerkt. Ist das dann der Fehler eines Mod Authors?


    Wenn du eine API anbietest und du nirgends öffentlich ansagst, das deine API Bindung Probleme hat und man das nur mit temporären Zwischenvariablen lösen kann? Ist das ein Fehler eines Mod Erstellers?


    In der Zeit der Entwicklung des Mods hat die UI noch sehr komische Sachen gemacht...


    Und so eine API anzubieten ist nicht einfach.

    Ich kämpfe da selber ständig mit in der CommonAPI2. Ich kenne beide Seiten und erlaube mir daher ein Urteil.


    -edit-

    Da ich da nicht noch weiter ausholen möchte, nein ich denke da Beispiele in der Community, die keine wirkliche Hilfe von UG bekommen haben, bzw. nicht hilfreich waren...

  • Zitat

    Wenn UG die API Funktion der UI ändert via Update, nun einen anderen Art Parameter erhalten möchte und das nicht im Changelog vermerkt. Ist das dann der Fehler eines Mod Authors?

    Mit subtilen Änderungen und Lücken in der Dokumentation muss man bei UG leider immer rechnen. Wenn der Autor das weiß, seine Mods pflegt - sprich regelmäßig und gerade nach Spiel-Updates selber benutzt - und am Testprogramm teilnimmt, sollte er frühzeitig ein Patch anbieten oder notfalls UG konsultieren. Auf jeden Fall sollte er ein Feedback an die Benutzer geben, wenn aus irgendwelchen Gründen kurzfristig oder generell ein Patch nicht möglich ist.


    Falls du dich da auf die CommonAPI bezogen hast, wäre die allerdings ein schlechtes Beispiel, da ich mir vorstellen könnte, dass UG die aus Prinzip nicht besonders unterstützt. (Das sei eine Feststellung und kein Vorwurf.)

    Ich will TpF3 mit Dinos, Zombies und Vulkanen!

  • Mit subtilen Änderungen und Lücken in der Dokumentation muss man bei UG leider immer rechnen.

    Nicht nur bei UG, eigentlich immer. Ich musste mal ein Linux-Treiber für eine sehr spezielle Hardware entwickeln und die Doku die ich hatte und die Kernel-API waren nicht konsistent. Es gab auch keinen Vermerk was dieser zusätzliche Pointer-Parameter eigentlich machen soll, Eingabewert oder Ausgabewert und welche Bedeutung. Ich bin dann in einen git-commit-Kommentar fündig geworden. Das ist eine schlechte Stelle für die Doku.