• Advertisement
Sign in to follow this  

How to store persistent data when the game changes level?

This topic is 3315 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I would like to store data which needs to be maintained while the game is being played or when level change occurs. Currently, the game structure is such that each level is treated as a state. When a level change occurs, the state is changed and the current objects are released. When loading the new level, the objects are recreated and reinitialized. The problem is that data such as combat level is lost during level change. Like in level 1, if the player object's ammunition is increased by 10 bullets, this change is not reflected in level 2 because the player object is recreated again. I have thought of a few ways but am not sure which to choose. One is not to destroy the player object. However it seems to violate the existing game state structure. The other is to create a global, persistent class to store whatever data needs to be maintained between levels. It looks easier although it could quickly become a huge messy class file. The third is to do object serialization and store whatever needs to be stored in a text/binary file. Then when the new level is loaded and the objects are recreated, read from the file and assign the data saved to the object's member variables. This approach seems to be the cleanest although i am not sure if reading and writing to file will slow down the process significantly. In game development, what is the better method to use? Besides game saving, is object serialization to file used during level loading as well?

Share this post


Link to post
Share on other sites
Advertisement
Extraneous disk access is almost always avoided as it's universally slow on just about every platform. So you don't want to be saving out data between every level, unless you happen to implement autosaving or some other feature that absolutely requires it.

The better solution is to persist that data at a higher scope. You mention that your game is split into a series of states, and that each state manages the resources it will need, RAII style. But there's no reason why you can't have the states be hierarchical. For instance, "initializing the game", "running the game", and "shutting down the game" are three states that exist at the highest level. You're either loading globally used resources, using those resources, or freeing them again. The "running the game" state is where everything interesting happens. Inside that state, you might have sub-states "single player game" and "multiplayer game". These are the states that will manage your player data. The "single player game" can then be split into different levels, each being its own self-contained sub-state. Those states contain level-specific data like monsters, world items, map geometry, etc. As long as you stay in the "single player state", you can switch levels at much as you want and not worry about player data because that data is being persisted by a higher-level state. At the highest level, your graphics system, network system, and audio system are around for the whole game, since they aren't freed until the shutdown phase, which is application exit. At the lowest level, you aren't holding on the monster and item data that isn't needed between levels. Essentially, the combination of states at different levels of the hierarchy, like "running the game/single-player/level01", make up your single discrete state. It's just managed different than a flat state system. If you can come up with and manage an appropriate state hierarchy, you can ensure your data will stick around just as long as you need it and no longer [smile]

I hope that helped a bit!

Share this post


Link to post
Share on other sites
Thanks for the comprehensive explanation :)

So if a hierarchial state machine is used, there would be 1 more level above the level 1 state called perhaps MainGamePlay state. Then for objects like the player object which needs data to be persisted through level changes, they will be created in the MainGamePlay state.

Then when the level changes, only the objects in the states like level 1, level 2 etc... below the MainGamePlay state hierachy will be released. The player object in the higher level state will still be maintained.

Then when the game is about to exit, there will be a ExitMainGamePlay state to release the player object.

Is this understanding correct?

Share this post


Link to post
Share on other sites
I handle level change in my current project by not destroying the player object. But my levels load fast enough to not even need a level transition state.

The slowness of file save/load method doesn't matter if it is only done during level load. Also, for saving large files during game play you can spawn a worker thread to save and have no effect on framerate.

Share this post


Link to post
Share on other sites
Why not save these changes that you wish to re apply to a text/xml file, then read this file at the start of a level to see if you need to apply any effects or not.

Something as simple as that won't even be noticed speed wise.

simple commands in a text file would do just fine

effect increase_ammo
{
amount = 10
}

You ofcourse will have to parse the file on your own and determine the changes that need to be saved.

Share this post


Link to post
Share on other sites
Quote:
Original post by freeworld
Why not save these changes that you wish to re apply to a text/xml file, then read this file at the start of a level to see if you need to apply any effects or not.

Something as simple as that won't even be noticed speed wise.

Why not store that information directly in memory, as the above posters suggested? There's no need for a save-to-file-and-then-load-again hassle. Perhaps your approach is fast enough, but it's always slower than not doing it at all.

Share this post


Link to post
Share on other sites
It's not the speed that's the issue here (although it really is still an issue in general since disk I/O is one of the slowest possible things you can do). It's that you shouldn't use the disk as a means of patching design limitations and temporarily storing data that you could just as easily be keeping in memory through a simple re-structuring of your states. You already have a state-based system in place that you understand, so all you need to do is make it layered and the proper resource scopes fall out naturally.

Share this post


Link to post
Share on other sites
Another solution could be to have a singleton class that contains the struct with the players state data, so the struct is allocated once at the game begin and you need only to set the value in it, befor change the levels, this method avoid fragmentation problem, and speed problem like the read and write in a file.

Share this post


Link to post
Share on other sites
Quote:
Original post by DocDumb
Another solution could be to have a singleton class that contains the struct with the players state data, so the struct is allocated once at the game begin and you need only to set the value in it, befor change the levels, this method avoid fragmentation problem, and speed problem like the read and write in a file.
That'll work but it's an horrible solution to a non problem (as Zipster pointed out layering states makes the problem magically disappear). Setting aside a lot of problems that singletons create themselves, what if you want to add multiplayer? Or if you want to add anything else that'll persist between two states for that matter. You can use singleton to work around the problem but I wouldn't call it a solution, it'll just cause more problems in the long run.

Share this post


Link to post
Share on other sites
Ok that don't is the more elegant solution, but this assure that the data persist also when all the levels are unloaded, you can also freed the resource, and this work well for the single and multiplayers too. So at the higher level the levels handler class could be the singleton, that know the current level, and contains the data, of the player(s) and about the level. But this is only another solution, the one from Zipster is valid too.

Share this post


Link to post
Share on other sites
<offtopic>
Quote:
Original post by Zipster
Extraneous disk access is almost always avoided as it's universally slow on just about every platform.

Unless you have one of those. :P
</offtopic>

Share this post


Link to post
Share on other sites
Zipsters explanation is really what it comes down to: you save the persisting data in a 'higher scope', or on a higher level, however you want to call it. But if you want to keep things efficient and workable, you keep that scope in the games memory, not in a file (which is needlessly far away). And you'd design your game with that in mind, not with slapping in singletons (which impose unnecessary restrictions and 'encourage' unwanted dependencies).

Both the singleton approach and the save-to-file approach do make use of a higher scope to save the persisting data in, and so both can work, but they're also fairly cumbersome. A proper design accomplishes the same, but in a better way.


@Konfusius: spiffy! :D

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement