Beiträge von eis_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


    Das Problem ist mal wieder die Doku von UG, was sie als default env definieren.


    Da debugPrint von UG nicht wirklich genutzt wird, kann man sich das require beim laden sparen.

    init.lua wird in jedem neuen UG State ausgeführt. Jetzt optimiert UG halt mal was, das ist auch wieder nicht gut ;) (So etwas ist aber gängige Praxis, das man via require nur dann lädt, wenn man es braucht)


    Das UG selber den globalen Namespace so verbraucht, es wäre nie zu einem Problem gekommen, wenn UG toString als Funktion des Moduls definiert hätte und es auch so dokumentiert.

    SSD ist nur interessant beim Laden von Daten.

    Grundgesetzlich gilt man kann RAM nicht durch Auslagerung ersetzen, gerade in TPF2 oder ähnlichen Spielen (Cites Skylines). Hintergrund Anwendungen (Einblendungen usw. abschalten, Shadow Play, OBS usw.)


    Alle Texturen müssen in den Grafikspeicher passen, wer mit 1000 Mods spielt darf sich nicht wundern. Die Ladezeiten steigen auch drastisch an. Zum Beispiel LUA require klappern halt dann alle Pfade ab, für jedes require wenn die Datei noch nie geladen wurde im LUA State. Natürlich kann TPF2 eine Textur nachladen, dann braucht es halt auch wieder nen schnellen Datenspeicher. Aber auch hier gilt, wenn der Dateissystem Cache des Betriebssystem groß genug ist, kommen die Daten halt auch aus dem RAM.


    Sprich, im Taskmanager im laufenden Spiel schauen, ist der RAM voll? Wenn ja, dann ist halt essig. Nur mehr RAM hilft und alles andere nicht laufen lassen.


    PS: Und der Monitor gehört an die Grafikkarte und nicht ans Mainboard...

    Also mir wäre da keine Möglichkeit bekannt mehr Daten zu liefern zu dem Script*. Ich habe mir mittlerweile viele TPF2 Teile angesehen.

    Bei vielen Sachen liegt es halt am Unwillen von Urban Games. Es wäre auch schön extra ModDaten an ein Entity zu binden. Ich stoße da auf Taube Ohren und habe meine Bemühungen mittlerweile halt eingestellt. Die beste Lösung ist immer Urban Games direkt zu nerven. Schreibt Mails damit es sich beim Dino stapelt.


    * Ich habe die Code stelle wo TPF2 das Script aufruft, da was dran von Außen zu verändern ist sehr schwierig.

    Da die Daten zwischen Threads repliziert werden ICompVec Kopien, kann ich auch gar nicht mehr irgendwo an ein Entity anbauen. Beim nächsten Daten kopieren (Sync zwischen Threads) sind Zusatzdaten einfach weg.

    Performance Killer Beispiel, die hier kaum auftauchen:

    • Debug Log Ausgaben während des Spiels (Ich hab trotz 300000 Logeinträgen bezüglich Animationsstest immer noch 20 Frames, aber man merkt es dennoch)
    • Verhinderung der Städte KI sich auszubreiten. -> Wer meint via Kollisionsobjekt die Ausbreitung der Stadt zu verhindern braucht sich nicht wundern. Bei jedem Durchlauf wird wieder versucht ein Haus hinzustellen -> es kommt zu Kollision -> es wird weiter gesucht. Das frisst im Laufe des Spiels immer mehr Zeit.
    • Die Texturen passen nicht in den Grafikspeicher -> Swap angesagt. -> Performance geht in den Keller
    • Spielstand zu groß für Arbeitsspeicher -> Dauerswappen -> tödlich für die Performance und ggf. für eine SSD mit Swapdatei.

    Beachtet TPF2 ist ein ganz anderes Kaliber in Speichernutzung als andere Spiele und auch Anwendungen.


    Synthetisches Beispiel:

    Ich habe ne Datenanwendung mit X GB an Daten, ich suche via Index dort Daten, das CPU hat ne halbwegs lineare Index Daten und muss nur einmal den Datenbestand(Index) durchgehen.


    TPF2 muss wahllos pro Simulationsschritt an X stellen Daten bearbeiten. Sobald man den Spielstand nicht mehr im Arbeitsspeicher halten kann, ist die Performance im Keller. Die Daten sind auch noch voneinander abhängig, sprich parallelisieren geht nur zu einem Teil.


    Animationen werden im Grafikrenderthread ausgewertet, diese laufen dauernd und schauen in den Metadaten wie die Animation beschaffen ist. Um so mehr Animationen dargestellt werden um so größer wird der Wust an Daten die dort durchlaufen.


    Sprich, zwar kann der Renderthread völlig ausgelastet sein, aber sich eure Grafikkarte trotzdem langweilen...

    TPF2 hat mir beim Entwickeln dann immer eine TRUCK CAR oder was auch immer in die laneconfig eingebaut. Vielleicht hat UG etwas geändert.


    Ich würde nur Trams gerne als Failback nutzen, wie sieht die config für die Straße aus? Dann kann ich das nochmal testen.


    -edit da ich nicht weiter Offtopic sein möchte-

    Bei transportModesStreet = { "TRAM","ELECTRIC_TRAM" }, erhalte ich direkt beim Bau ohne CommonAPI2 :

    ..\..\src\Game\UI\Util\BuilderRenderer.cpp:761: void __cdecl UI::BuilderRenderer::Clear(bool,bool): Assertion `!m_proposalEngine' failed.

    Ich möchte darauf hinweisen, das ich dort am Code via CommonAPI2 Native herum bastele. Daher kann das Ergebnis variieren.

    Technisch kann TPF2 nur mit CommonAPI2 ein Tram, Strasse ohne CAR/BUS im Lane darstellen, sonst gibt es Chaos wie diesen hier:


    Sprich CommonAPI2 ändert die Render Berechnung von Lanes. (auch bastele ich an der Validierungssroutine herum)

    TPF2 möchte auch keine Fußgänger Lanes in der Mitte der Strasse und jeweilige Asymmetrien sind tabu.

    .

    Auch mag es partout keine Haltestellen in die Mitte der Strasse legen... bzw. ich habe noch nicht herausgefunden wie...


    ... wenn ich nur Code Access hätte, das wäre so viel einfacher ...

    I am sorry I did want to answer earlier.


    According to my binary analysis producing is a referenced string in a Transformator

    I cannot find production connected to a Transformator and/or productionHalf and productionFull .


    That doesn't mean I say these are not working at all, but I simply find no traces in the binary code.

    Different example: The animal movement types aren't hardcoded in the exe either, but seems to run randomly from defined movement types)


    A Transformator grabs readonly ECS Entity Data and selects actually the desired Animation to Render a Construction, Vehicle, Animal, Bridge and so on. It's called heavily in the Render Thread.


    Actually that is the reason (Design) you can't really fire an specific Animation as in TPF1 via Script Interface.


    The desired animation was passed as string mostly in TPF1 and stored in the entity system.

    Now in TPF2 you only have some flags, like isDoorOpen and doorTime. The used animation name from Modeldata is calculated every rendering...



    UG really could create a Wiki overview page with a list of all triggers, event names for animations and sound...

    Der verhindert irgendwas die Ausführung von curl (ist ein Windows 10 Bestandteil). stdout.txt log nach dem klicken sollte Informationen geben welche Domain das ist. Hier oder Werkstatt. Bitte beachte, ich hab ein fix in CommonAPI2 1.7.20211017 bezüglich curl redirect eingebaut.


    Und das Blinde updaten von Mods ist keine gute Idee. Das Problem wird nur noch schlimmer...

    Why not use UGs Console and let it simple output the entity data, then you can see the structure? (Actuall it uses the same toString system)


    78928 is a SIM_BUILDING of a steelmill (as shown on my last screenshot. You get stats by Cargo type (past data only):


    This is because a game_script is heavily running thread. As UG didn't want me to tell how to sync to it, it's not possible to reliable know the current state this lua is. maybe it's somewhere in a deep nested function (Note: the summer update made things more async, so it's even worse)


    game.interface.getEntity(<entityid sim building>) (using SIM BUILDING Entity of a construction) shows a lot of data.


    Technical internally it will use the same entity components.

    The problem with UGs api.* functions is, they really aren't finished. Every time you see userdata, UG missed a part of the puzzle.

    However, sometimes it is easier to use the old game apis, maybe the needed info is already in there.

    game.interface.getEntity and api.system.* are completely different beasts. The first does a lot of data computing to get meaningful data and are made for TPF1/2 campaigns. The api.* are more interfaces to the direct internals of the game.


    The data you get via game.interface.getEntity are the past performance of an industry.


    Internally the game normally subscribes to state changes to know if something happens via the Enity Systems, but that isn't doable from the lua side.
    So while TPF2 is a lot faster and open, the CommonAPI TPF1 was a lot more flexible because there was only one thread and the interfaces was a lot more clearer.


    The question really is. What do you want to do? What is your goal in the end. Then you can select the right "tools"


    PS: Renaming shouldn't be necessary. game_script gui* is run in "GUI Thread", the other updates are run in "Script Thread". Renaming should be only done once, otherwise you fill your log with debug info...

    The proper API way, if you have a sim building entity, at least from API description as mentioned earlier.

    industryEntity is a SIM_BUILDING

    streetConnectorSystem.getConstructionEntityForSimBuilding(industryEntityId) => should give you a construction entityid


    You should ask UG for a complete guide how to do it properly.

    And if you have an answer, please post them so others can learn too.

    Yeah, the construction should have the stocklist. At least my inspector shows there is a stocklist.


    But as api.engine.getComponent(<constructionentityid>, api.type.ComponentType.STOCK_LIST) returns userdata.


    Damn. So still you have to use some api.system.* functions to get meaningfull data or old game.* interfaces

    See here, I am using my API left bottom Button -> Inspector Window. Second Tab has a "Get Entities" function, we see a Construction and SIM_BUILDING



    You want the whole UG API Madness, let's do it. You have a construction entity.

    1. Get the construction component,

    2. Use the simBuilding(s) EntityId to get component SIM_BUILDING

    3. we have a list Entity Ids of Stocks => stockList

    4. use simEntityAtStockSystem to get count.


    Dump of UG Console:



    Easy? Yeah... There are tons other apis the api.engine.systems ,so it's likely there is an easier way... but with the good documentation...


    There are some industry mods out there, maybe look what apis they use to get to a easier code path...




    -edit- More madness while we are at whole thing. Let's say, we have a SIM_BUILDING and want a construction?


    api.system.streetConnectorSystem.getConstructionEntityForSimBuilding

    https://transportfever2.com/wi…ctionEntityForSimBuilding