[BNW] Efficient use of SaveUtilis?

Serp

King
Joined
Apr 1, 2015
Messages
661
Spoiler Context: :

DLL - Various Mod Components
Hi whoward,

are you interested in an "Pre_Save" Event or similar? I would need such an event that is triggered shortly before the game is saved (by autosave,quicksave, normal save and so on).
Why do I need such an event? For example for mods like your Scouting XP mod. Saving data in ModDB or with SaveUtilis or any other tool in real time is very laggy.
But saving the stuff simply shortly before a savegame would be the ultimate solution.

Do you think such an event exists/is possible to add?
I only found various places where "gDLL->AutoSave(..) or gDLL->QuickSave(...) or gDLL->SaveGame(...)" is called, but I think these functions itself are inaccessable? And pushing a custom event in fornt of every line like this would be quite hacky I guess... not the best solution.

Myself, Pazyryk and ls612 delved deeply into this for his Éa Fantasy Mod and game to the conclusion that you cannot trap every possible exit from the game via C++/Lua, which is why he ended up using a heavily modded version of SaveUtils IIRC.

It would be far easier IMHO to make another Cv class and hang it off one of the existing ones (eg CvTeam or CvPlayer) and have it serialise/deserialise as it's owning object does - but "easier" is a relative term, it's still a mass of work

@whoward69
Thank you very much for the fast response (I created a new thread, because it would be too much offtopic in your thread)
Yes, I already tried to add a GameEvent before all the occurrences of "gDLL->SaveGame(...)" and so on, but for whatever reason it is not triggered (only the autosave when the map was generated works).
I have no experience regarding serialise/deserialise, so I guess this is no option for me.

Regarding SaveUtilis: Do you have a link to the most efficient version of it you know?

My current project:
I have a mod that shares visbility of one team with another team (eg. when they are friends). I achieved this by adding an event to the DLLs plot function "changeVisibilityCount". This way I get in lua notified about every visibility change and then I can "copy" this over to the friend-team.
But when friendship ends, I need to revert the visibilty to default somehow. And the only solution that came to my mind is, that I need to save all the plots with viscounts that are shared. (only alternative may be that I hide the whole map and then call a function that builds of visibilty from scratch based on current units and so on. But I don't think there is such a function).
So I save an array like this:
g_visible_made_plots[iTeam][iCivTeam][iPlot] = g_visible_made_plots[iTeam][iCivTeam][iPlot] + viscount
Depending on the number of teams, the units and the map size, this gets a really huge array. And this array is updated on every single call of "changeVisibilityCount", which is very often eg. when a unit moves, while we need to seperately save the array every single time of them. I already only save the relevant info for the specific team with:
save(pLeader,"g_visible_made_plots",g_visible_made_plots[iCivTeam])
but it is still by far too much, even on medium maps after ~50 turns it starts heavily lagging.
 
Last edited:
I searched for the Fantasy mod whoward mentioned and found the follwing (currently reading the part on where to put an dll event to catch every save):
https://forums.civfanatics.com/thre...lua-table-data-through-game-save-load.442249/

edit:
Problem solved thanks to that article :) I added an game event to the DLL when the game is saved. This way I only need to save with SaveUtili (or TableSave) when it is really needed -> the most efficient way.

I really wonder why no known DLL, like whowards or Community patch, implemented this GameSave Event in their DLLs, it is a really important one.
 
Last edited:
@whoward69 Do you ever experienced a "freeze" because of "gDLL->GetScriptSystem()" ? Like described from Pazyryk here: https://forums.civfanatics.com/thre...lua-table-data-through-game-save-load.442249/
I added his code to the DLL, but it seems not only the first autosave is causing this freeze, but randomly also other ones. I added CUSTOMLOG prior and after gDLL->GetScriptSystem() and indeed, this is the reason for the freeze between turns (when autosave is done). (it also happens when I use your GAMEEVENTINVOKE_HOOK(...) instead )

I also had this kind of freeze randomly happening half a year ago and never found out why. But maybe it was just another Event that froze during gDLL->GetScriptSystem().
So my final question is:
Is there a way to safely call gDLL->GetScriptSystem() and abort this after ~5 seconds, so the game can at least continue, instead of freezing?
 
my assumption, that ""gDLL->GetScriptSystem()" is the reason for the freeze, were wrong. I put more "prints" in the dlls code and found this:

Code:
bool LuaSupport::CallHook(ICvEngineScriptSystem1* pkScriptSystem, const char* szName, ICvEngineScriptSystemArgs1* args, bool& value)
{
   // Must release our lock so that if the main thread has the Lua lock and is waiting for the Game Core lock, we don't freeze
    CUSTOMLOG("CustomMods CallHook %s 1", szName);
    bool bHadLock = gDLL->HasGameCoreLock();
    CUSTOMLOG("CustomMods CallHook %s 2", szName);
    if(bHadLock)
    {
        CUSTOMLOG("CustomMods CallHook %s 3", szName);
        gDLL->ReleaseGameCoreLock();
    }
    CUSTOMLOG("CustomMods CallHook %s 4", szName);
    bool bResult = pkScriptSystem->CallHook(szName, args, value);
    CUSTOMLOG("CustomMods CallHook %s 5", szName);
    if(bHadLock)
        gDLL->GetGameCoreLock();
    CUSTOMLOG("CustomMods CallHook %s 6", szName);
    return bResult;
}
resulted in the following logs prior to the freeze:

Lua\CvLuaSupport.cpp[75]: LuaSupport::CallHook - CustomMods CallHook PreSaveEvent 1
Lua\CvLuaSupport.cpp[77]: LuaSupport::CallHook - CustomMods CallHook PreSaveEvent 2
Lua\CvLuaSupport.cpp[80]: LuaSupport::CallHook - CustomMods CallHook PreSaveEvent 3
Lua\CvLuaSupport.cpp[83]: LuaSupport::CallHook - CustomMods CallHook PreSaveEvent 4

So I guess the Lock system is the reason for the freeze. Since the SaveGame/PreSaveEvent is placed into the CvGame.cpp file, and CvDllGame.cpp includes code dealing with the Lock, maybe one should not mess with the lock within CvGame file? No clue...
 
Top Bottom