[PYTHON] How to keep Python Variable value after load game

ciruela

Warlord
Joined
Sep 24, 2015
Messages
202
in my Game of Throne FFH2 modmod v2.00,due to first time to involve Python changes,and now I have some question need experienced modders to answer:

1.How to Save Python Variable in Savegame and get value of these Python Variable after loaded savegame file.
add a lot variable in CvEventHandler.py to run a Season System and mark current Season,mark current climate.
Spoiler :
Code:
class CvEventManager:
    def __init__(self):

        #Ciruela Season 20171014
        self.iSeason = 0
        self.sSeason = 0
        self.iSeasonRatio = 2
        self.iSeasonACRatio = 1
        self.iSeasonTurn = 150
        self.iSeasonTurnLeft = 150
        self.iMaxX = -1
        self.iMaxY = -1
        self.iCurrentColdY1 = -1
        self.iCurrentColdY2 = -1
        self.iMinColdY = -1
        self.iMinPlainY = -1
        self.iMinTundraY = -1
        self.iMinSnowY = -1
        self.iPlotYChangeRef = 0.125
        self.iSeasonPCRatio = 1
        self.iCurrentPlainY = -1
        self.iCurrentTundraY = -1
        self.iCurrentSnowY = -1
All things Work well until reload a savegame, all Python Variable's value initialized,can't continue to follow the season's trace.

2.add a minor civ or add a civ permanent war with all other civs.

now I can add a civ and declare war to all other civs,but they will make peace after 10 or more turns.
 
Last edited:
1.How to Save Python Variable in Savegame and get value of these Python Variable after loaded savegame file.
You don't. The DLL is able to save variables kept in the DLL. You could add a new variable inside the DLL, make get and set functions to expose it to python and then add it to the savegame code. This obviously requires a recompile of the DLL.

2.add a minor civ or add a civ permanent war with all other civs.

now I can add a civ and declare war to all other civs,but they will make peace after 10 or more turns.
If you set teamA to declare war on teamB, then you make the war permanent with
PHP:
teamA.setPermanentWarPeace(teamB.getID(), true)
First argument is the team it affects and the second is a bool telling if the peace/war situation is locked. Naturally you need to declare war before making it permanent or you will lock it to prevent war. It just locks the situation without changing if there is war or not.
 
You don't. The DLL is able to save variables kept in the DLL. You could add a new variable inside the DLL, make get and set functions to expose it to python and then add it to the savegame code. This obviously requires a recompile of the DLL.


If you set teamA to declare war on teamB, then you make the war permanent with
PHP:
teamA.setPermanentWarPeace(teamB.getID(), true)
First argument is the team it affects and the second is a bool telling if the peace/war situation is locked. Naturally you need to declare war before making it permanent or you will lock it to prevent war. It just locks the situation without changing if there is war or not.

Thanks for quick answers!
I'll try to second one.
for first one,can't open 2kgame's SDK download page.and i'm not familiar with complex c++/SDK Environment even following the Guide
When my develop environment is ready,did i Simply put dll file in IDE such as VC++/Vitual Studio to edit
or I should find source code which dll version i used before compile,import to IDE,add Variable and get/set method and recompile again to replace old one?
 
1.How to Save Python Variable in Savegame and get value of these Python Variable after loaded savegame file.
add a lot variable in CvEventHandler.py to run a Season System and mark current Season,mark current climate.

All things Work well until reload a savegame, all Python Variable's value initialized,can't continue to follow the season's trace.

You don't. The DLL is able to save variables kept in the DLL. You could add a new variable inside the DLL, make get and set functions to expose it to python and then add it to the savegame code. This obviously requires a recompile of the DLL.

You can use getScriptData() and setScriptData() to do what you are describing, in Python. No need to delve into the DLL. You combine your data into a string, and use these functions to save/retrieve the string from a CyGame, CyPlayer, CyCity, CyUnit, or CyPlot instance.
 
You can use getScriptData() and setScriptData() to do what you are describing, in Python. No need to delve into the DLL. You combine your data into a string, and use these functions to save/retrieve the string from a CyGame, CyPlayer, CyCity, CyUnit, or CyPlot instance.
You could add a new variable inside the DLL, make get and set functions to expose it to python and then add it to the savegame code.
Or you could use the vanilla function, which does precisely what I had written as requirements for such a variable. I wasn't aware of this variable, but it is clearly intended to be used for what you need.

The problem is that it's just one variable, but there are tools to convert strings to arrays and back. Say you want to work with
PHP:
       self.iSeason = 0
        self.sSeason = 0
        self.iSeasonRatio = 2
Obviously you want all, but I won't want to write that much :p

You can then write code like this:
PHP:
def save(self):
    array = [ self.iSeason, self.sSeason, self.iSeasonRatio ]
    save_str = "|"
    save_str.join( array )
    gc.getGame().setScriptData( save_str )

def load(self):
    array = gc.getGame().getScriptData().split[ "|" )
    self.iSeason = array[0]
    self.sSeason= array[1]
    self.iSeasonRatio = array[2]
The saved string will then be "0|0|2". It should work as long as you make sure the variables are in the same order. You might have to work a bit with it and look up the functions refer to here, like split and join for python strings, but it should be technically possible without messing with C++ and compilers.

Just a disclaimer: I haven't actually done anything like this in python. Usually when I have this problem, it's always in perl scripts. This means I haven't tested what I just wrote. However it should work as I have tested the approach in perl and it's pretty much a standard in all programming languages.

in my Game of Throne FFH2 modmod v2.00
for first one,can't open 2kgame's SDK download page
Since you work on a modded DLL, in this case FFH2, you need the source code for that one, not 2kgame's SDK. Besides it's actually included in the game install, at least in my DVD version. It's in a folder called CvGameCoreDLL next to the exe file. Alternatively it should be available here since @Leoreth uploaded it. We should all thank him for his work in preserving the needed files :goodjob:

Having said that, setting up the compiler today sadly requires a guide since you need MSVC from 2003. I wrote one such guide here, though it assumes you work on Medieval Conquest, in which case I have already set up the project file and makefile, which means it skips that part. It does however link to all the compiler files you need.
 
try these code and have a test,sometimes that worked,sometimes not.
Spoiler :
Code:
    def onPreSave(self, argsList):
        "called before a game is actually saved"
        #Ciruela Try to save Variable 20171016
        DictSeasonVariable = []
        DictSeasonVariable.append(self.iSeason)
        DictSeasonVariable.append(self.sSeason)
        DictSeasonVariable.append(self.iSeasonRatio)
        DictSeasonVariable.append(self.iSeasonACRatio)
        DictSeasonVariable.append(self.iSeasonTurn)
        DictSeasonVariable.append(self.iSeasonTurnLeft)
        DictSeasonVariable.append(self.iCurrentColdY1)
        DictSeasonVariable.append(self.iCurrentColdY2)
        DictSeasonVariable.append(self.iMinColdY)
        DictSeasonVariable.append(self.iMinPlainY)
        DictSeasonVariable.append(self.iMinTundraY)
        DictSeasonVariable.append(self.iMinSnowY)
        DictSeasonVariable.append(self.iPlotYChangeRef)
        DictSeasonVariable.append(self.iSeasonPCRatio)
        DictSeasonVariable.append(self.iCurrentPlainY)
        DictSeasonVariable.append(self.iCurrentTundraY)
        DictSeasonVariable.append(self.iCurrentSnowY)
        dSeasonVariable = pickle.dumps(DictSeasonVariable)
        CyGame().setScriptData(dSeasonVariable)
        CvUtil.pyPrint('OnPreSave')

Spoiler :
Code:
    def onLoadGame(self, argsList):
        CvAdvisorUtils.resetNoLiberateCities()
        #Ciruela Try to load Variable 20171016
        dSeasonVariable = CyGame().getScriptData()
        DictSeasonVariable = pickle.loads(dSeasonVariable)
        self.iSeason = DictSeasonVariable[0]
        self.sSeason = DictSeasonVariable[1]
        self.iSeasonRatio = DictSeasonVariable[2]
        self.iSeasonACRatio = DictSeasonVariable[3]
        self.iSeasonTurn = DictSeasonVariable[4]
        self.iSeasonTurnLeft = DictSeasonVariable[5]
        self.iCurrentColdY1 = DictSeasonVariable[6]
        self.iCurrentColdY2 = DictSeasonVariable[7]
        self.iMinColdY = DictSeasonVariable[8]
        self.iMinPlainY = DictSeasonVariable[9]
        self.iMinTundraY = DictSeasonVariable[10]
        self.iMinSnowY = DictSeasonVariable[11]
        self.iPlotYChangeRef = DictSeasonVariable[12]
        self.iSeasonPCRatio = DictSeasonVariable[13]
        self.iCurrentPlainY = DictSeasonVariable[14]
        self.iCurrentTundraY = DictSeasonVariable[15]
        self.iCurrentSnowY = DictSeasonVariable[16]
        return 0
which edition of Windows Platform SDK are you use? Win7 can't install old one
 
Last edited:
I has tried another method, call save method when game start,and load,do,save at end of every turn,worked before first 4 turns,but will got python error each turn after 4 turns
Code:
    def onGameStart(self, argsList):
        'Called at the start of the game'

        #Ciruela Season 20171014
        ss.seasonCounterStart()

        #Ciruela Try to save Variable 20171016
        ss.saveSeasonData()

        ........

    def onBeginGameTurn(self, argsList):
        'Called at the beginning of the end of each turn'
       
        #Ciruela Try to load Variable 20171016
        ss.loadSeasonData()

        #Ciruela Season 20171014
        ss.doSeasonChange()

        #Ciruela Try to save Variable 20171016
        ss.saveSeasonData()

        .......
 
which edition of Windows Platform SDK are you use? Win7 can't install old one
I have run into the same problem on XP and I decided to just ignore it and carry on and work based on error messages. They never showed up. My current install on win7 lacks the SDK too and it works just fine, which makes me wonder why the guides claim it to be needed.
 
Top Bottom