Anyone know how signs are persisted?

Koshling

Vorlon
Joined
Apr 11, 2011
Messages
9,254
Background:

I'm working on SDK changes to support large map scalability by exposing 'viewports' (essentially windows into a large underlying map) as virtual maps to the game engine. See http://forums.civfanatics.com/showthread.php?p=11388145 and http://forums.civfanatics.com/showthread.php?t=460023 for more details.

Anyway, the Dll externals by which the game engine queries the game state are virtualised and seek to not expose the existance of anything outside the viewport to the game engine (so as far as it is concerned the 'game' is just the stuff inside the current viewport). Thus things like
Code:
CvMap::plot()
and so on return NULL for coordinates outside the virtual map represented by the viewport (and the engine thinks the map size is the viewport size).

On loading a fairly complex existing game state I found
Code:
CvPlot::getPoint()
(and only that method) was beign called via a NULL CvPlot. To try to track this I modified the virtualisation to instead of returning NULL for coordinates outside the viewport, returned a 'pseudo-plot' so that when that is handed back to CvPlot::getPoint() I could track where it came from.

It turns out that during load, after the game state is loaded, but before most of the graphics initialization, the engine makes a few very specific calls to
Code:
CvMap::plot()
passing what looked like random requests for a few plots scattered over the map. Closer examination shows these to be plots that have had signs added via events ('waters of life' etc.).

This raises the question of how the game engine knows about the signs at this point. I initially assumed that these were stored as landmarks on the CvPlot (we're based off of AND, which I think is where the landmarks originated??), but the plots in question have NO_LANDMARK. They also don't possess any other distinguishing feature I can see that relates to the sign.

I now suspect that the game engine persists signs entirely independently of the DLL, adding sign data to the save game stream after the calls to the DLL to persist its infomation (i.e. - the game engine persists data independently of the DLL). If this is the case it's a massive pain in the backside for me, because I can't stop these calls occuring, and have no way to distinguish them and perform coordinate mapping on them.

As far as I can tell it's only signs that have these issues. I guess I **could** write some (horrible, hacky) Python that runs on game load and queries the sign data for every plot, transferring persistence to the DLL via a new property on CvPlot, and clearing the state peristed by the game engine (in the wrong coordinate system) after load, replacing it with the subset in the viewport with appropriately mapped coordinates. This would be a last resort though.

Anyone know anything more about how signs work internally, and in particular about how they are persisted?
 
I had a look at that and the reason for the problem is the EventSigns.py script. It persists event landmarks using the SdToolKit as a global so it ends up in the m_szScriptData of CvGame. Instead of directly storing it in the CvPlot m_szScriptData it references plots by coordinates. When you load the game it turns the coordinates into plots and tries to place landmarks there via direct engine calls.

So, luckily, the engine does not persist that itself but the Python script will need some changes (probably best to move its functionality to the DLL).
 
It persists event landmarks using the SdToolKit as a global so it ends up in the m_szScriptData of CvGame.

Ah, it was this that I did't know (that it would wind up in CvGame m_szScriptData. Thanks AIAndy ;-)
 
As an FYI, in case anyone else comes looking for this information:

It turns out that the game engine itself serialises sign/landmark data (and restores it on load) entirely outside of the DLL/Python. At least in ROM derivatives, the Python ALSO serialises it as per AIAndy's descriptions above and also (redundantly) sets it on load.
 
Back
Top Bottom