[Tutor] Best way to save a D&D-like game's state?

Alan Gauld alan.gauld at yahoo.co.uk
Sat May 22 07:04:52 EDT 2021


On 22/05/2021 01:25, boB Stepp wrote:
> I am contemplating the design of a D&D-like game where I will
> prototype various ideas I have in Python.  Currently I am pondering
> how such games typically have their state saved. 

In practice its usually in a flat file since they usually load
it all into memory at startup. (the actual volumes of data are
not that big on modern computers - ie. where a few megabytes is
considered normal...

The flat file will usually have some kind of format such as
config file, XML, CSV, JSON or YAML.

Whether there is one big file with different sections
for different data types or separate files for different
types of data(settings, config, player status, etc.) seems
to be an arbitrary choice by the programmer.

> be plenty of custom data types, which represent the state of the game
> world when the players save.

Not usually. These can all be abstracted to a relatively
few data items. weapons for example equate to relative
power, effect, fuel/ammo levels etc. But there might be
many types of weapon, but for data storage it's only a
few common attributes that matter. (You may also have
a separate file for each weapon holding the features
unique to that item but the status data will be small.


> types done in Python.  Next that comes to mind is JSON, but my
> understanding is that it is limited in what it can save and restore
> without additional work by the programmer.  

There will always be extra work required, even with pickle,
because you need to be in control of what gets saved and
when. Almost inevitably you will want to write a save/load
pair of methods for each persistent object. (you could
use a persistence mixin class to simplify this)

> I suppose an SQLite database could be made to work.

Yes, both as a persistence store - although I'd prefer
JSON etc for this - but more importantly for a dynamic
store during the game using sqlite's in-memory mode of
working. That gives very fast access combined with SQL's
searching capability. The downside is having to create
the in-memory database at startup each time.

> 1)  First off, am I thinking along the correct lines of doing this, or
> is there a better way?

Yes, you are on the right lines..

> 2)  If it does become true that sizable amounts of data need to be
> stored, which of the above options is most performant?  Thinking about
> this I suppose that in the case of large amounts of world data one
> would want to divide up the data into logical units and only load what
> is currently needed at any point in the game.

That should rarely be an issue with a D&D type game. If you make it a
large multi player game it might be a problem, although then you'll be
running on a server with, hopefully, bigger RAM/disk capacity. All of
the options discussed will happily scale up to several hundred
megabytes of data.

> 3)  Algorithmically, how would one perform incremental saves?  I know
> this is done by many programs, so that only the changes to the
> original data are stored, which saves (pun intended) on the amount of
> data that needs to be saved.

The standard technique is to use a dirty flag per object then in the
save() method write code like:

def save(self):
   if self.isDirty():
      self.store()

Where self.store() is the function that writes the object state
to storage. self.save() is probably an inherited method of the
persistence mixin while self.store() will be an abstract method
of the mixin implemented in each concrete object class.

self.isDirty() can be a simple getter of an attribute or it can
do a more sophisticated examination of the internal state to
see if changes are necessary. Usually a simply flag attribute
is enough and every write operation sets it to True.

> 4)  I am not adverse to considering third party libraries.  If I do
> so, YAML also comes to mind.  I have no idea what other formats might
> be worth considering.  I hope XML is not a serious option as I have
> heard that it can turn into a mess with data files not easily parsable
> by human readers.

Yes, and also hugely inefficient in storage - often up to
a 3 to one ratio of markup to content! YThis is one reason JSON
has become popular, it has a much lower size when you need to
store or transmit it.

> 5)  If this project proceeds to fruition then it is entirely possible
> that portions or all of it will need to be rewritten in a more
> hardware performant language.  If that proves to become the case will
> that alter any of your answers to the above questions?

Most D&D games do not need high performance computing so Python
should be more than capable. But if you do think its a possibility
choose a portable option such as XML, JSON, or SQLite.

The other thing to consider in that scenario is the overall structure
of the application. Keeping the areas that might need to be rewritten
separate from bits that don;t might reduce the amount of code to be
ported. That's usually a much bigger issue than converting the data storage!

Finally, somebody else suggested a NoSQL database such as Mongo
and while that would indeed be a good choice, it does add a whole
extra layer of learning. (Assuming you are familiar with
regular SQL, or JSON etc. but not with Mongo)

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list