I assume you mean in Python. You have to save any data manually since the game only saves its own data and is pretty much unaware of any Python data. There is a variable which is provided specifically for this on many of the game objects called "ScriptData".
If you are using BUG it has built-in functions to help you do this known as "BugData" as it is implemented in the BugData.py file.
There are also stand-alone mod components to help do this, like the SdToolKit.
To do it by hand without BUG or SdToolKit, what you do is have an event handler for the OnPreSave event in your CvEventManager.py file, in the BtS CvEventManager.py file there is already a function for this called onPreSave. In that function you can save the data to one or more scriptdata locations. You also need a function for the OnLoad event, which also already exists in the default BtS CvEventManager.py where it is called onLoadGame.
There are two relatively straightforward designs. The first is to store everything for a player in that player's CvPlayer object's scriptdata. The second is to store everything in a dictionary and store that dictionary in some object like the CvGame object.
To save an array on each player you'd have something like this (not tested, largely stolen from commented tu code int he original Final Frontier mod):
Code:
def onPreSave(self, argsList):
"called before a game is actually saved"
CvUtil.pyPrint('OnPreSave')
# save player data
for iPlayerLoop in range(gc.getMAX_PLAYERS()):
pPlayer = gc.getPlayer(iPlayerLoop)
aPlayerData = self.aaiPlayerDatas[iPlayerLoop]
pPlayer.setScriptData(pickle.dumps(aPlayerData))
def onLoadGame(self, argsList):
CvAdvisorUtils.resetNoLiberateCities()
# Load player data
for iPlayerLoop in range(gc.getMAX_PLAYERS()):
pPlayer = gc.getPlayer(iPlayerLoop)
aData = pickle.loads(pPlayer.getScriptData())
self.aaiPlayerDatas[iPlayerLoop] = aData
return 0
This assumes that the data for the players is stored in an array attached to the CvEventManager called aaiPlayerDatas with index being the player number (the "aai" prefix would indicate that it is intended to be an array of arrays of integers). If they are stored in some global arrays you just need to read/write them instead.
The CyPlayer.scritpdata variable holds a text string. The pickle object exists to convert things to a text string representation (via pickle.dumps(X)) and from a string back to a copy of the original object (via pickle.loads(X)). This "pickling" operation is also called "serialization" and some other things.
You would use these in the CvEventManager in the usual ways of manipulating arrays, perhaps something like these sorts of things:
Code:
# initialize array of arrays, 1 per player with 2 values in each starting with 0 for both
self.aaiPlayerDatas = [[0,0] for i in range(gc.getMAX_PLAYERS())]
# change the data for player iPlayer
self.aaiPlayerDatas[iPlayer][0] = 42
self.aaiPlayerDatas[iPlayer][1] = 3.14
If you need to use the data in some other file, like CvGameUtils.py for example, you need to import CvEventInterface.py into that file and then get the event manager with the CvEventInterface.getEventManager() function and use that to access the variables, something like this:
Code:
EM = CvEventInterface.getEventManager()
EM.aaiPlayerDatas[iPlayer][0] = -1
There are probably other good ways of doing it, but because of that CvEventInterface.getEventManager() function making it easy to access the event manager object from any file, it is pretty easy to use that as the place to keep your data if you need to access it in more than one file.
The original Final Frontier mod is an example of doing "manually" this since all of the star system data, AI data, and tutorial data is stored in the scriptdata of various objects in this way. The Final Frontier Plus mod uses BugData to store some data, but mostly does it the same as plain Final Frontier (I had to switch the tutorial over since it was using the CyGame's scriptdata which BUG uses for BugData and there was therefore a conflict where one overwrote the other).