Hallo, hier mal ein generelles Feedback zu Gamescript und welche Probleme das bei mir aktuell mit sich bringt.
Wie ihr vlt schon wisst, entwickle ich gerade eine Statistiken Mod, welche daher auf Gamescript angewiesen ist. Da ich hier etwas weiter aushole und zahlreiche Unterdateien verwalte, habe ich das aufgeteilt in Script und Gui. Denn es ist ja so, dass dieselbe Gamescript Datei zweimal instanziiert wird - 1x im Script Thread und 1x im Gui Thread. Das ist etwas verwirrend am Anfang, wenn es dasselbe 2x gibt, aber mit anderen Zuständen. Daher macht es Sinn, das aufzuteilen, eine Datei script.lua und gui.lua. Denn in beiden möchte man andere Sachen machen und die Variablen sind ja eh nur pro Thread verfügbar. Trotzdem existiert dann beides jeweils 2x. Das funktioniert aber soweit.
In der Mod soll es auch Einstellungen geben, welche natürlich mit dem Savegame gespeichert und dann wieder geladen werden sollten. Das ist aktuell der Knackpunkt, denn wie ich im wiki gelesen habe, wird ja load auch dafür benutzt - hier allerdings im Script Thread. Das ist äußerst unpraktisch, dass das hier so zweideutig ist und nicht getrennt. Ich weiß, ihr macht das in den Kampagnen/missions mit "state = allState or state" und das mag dort Sinn machen.
Ich möchte aber nicht den ganzen state übergeben, sondern nur "state.settings". Das hat mehrere Gründe.
Im State gibt es nämlich noch alles mögliche andere, was nicht vom Savegame geladen werden soll, sondern ganz normal initialisiert wird. (z.B. ein Init Flag, was ich wiederum nur brauche, weil bei guiInit der initialisierte state (1. update call) noch nicht verfügbar ist.)
2. Da meine Gui Dateien logischerweise immer den aktuellen State brauchen (dessen Pointer sich jeden Step ändert), ist es mit einem einfachen "load = function (allState) state = allState or state" nicht getan. Sondern ich muss den state zu einer anderen table anhängen, damit der aktuelle Pointer gefunden werden kann.
Also, was ich jetzt gemacht habe, ist in der script.lua einfach in load meine settings zuzuweisen. Aber aus obigen Gründen wird das dann natürlich auch im Gui Thread kontinuierlich ausgeführt. Also habe ich mit einem ugly workaround versucht zu erkennen, in welchem Thread ich bin.
gamscript.lua
...
save = function()
print("SAVE",avs.thread.getCurrentThread())
return avs.script.state
end,
load = function(state)
print("LOAD",avs.thread.getCurrentThread(),state)
if state then
avs.script.load(state)
avs.gui.load(state)
end
end,
script.lua
...
function script.load(loadState)
if thread.isScriptThread() then
if loadState.init then
log(1, "State found",loadState.time.now.date)
log(1, "Load Settings")
log.logTab(2,loadState.settings)
state.settings = loadState.settings
end
end
end
function t.isScriptThread()
return game.interface.addPlayer ~= nil
end
stdout.txt
...
<Game Script Init>
Advanced_Statistics: Loaded advanced_statistics/main
No resources are missing!
LOAD Script Thread table: 000001872F5A8A20
Advanced_Statistics: State found 2021-02-06 11:53:17
Advanced_Statistics: Load Settings
{ <My Settings> }
SAVE Script Thread
LOAD Gui Thread table: 000001872F5B2700
SAVE Script Thread
SAVE Gui Thread
..\..\src\Game\Game.cpp:349: void __cdecl CGame::StartGameSim(void): Assertion `m_data->gameStates[1]->ScriptSave() == m_data->gameStates[0]->ScriptSave()' failed.
Das mag aber offenbar das Spiel ganz und gar nicht, auch wenn ich nicht verstehe warum. Offenbar müssen die Ergebnisse von SAVE in beiden Threads gleich sein.