Implement a “Save Game” Feature in Python with the shelve Module

This post goes into the details of how you can add a “save game” feature to your games. Python’s built-in shelve module makes this very easy to do, but there are some pitfalls and tips that you might want to learn from this post before trying to code it up yourself.

To give an example of adding a “save game” feature to a game program, I’ll be taking the Flippy program (an Othello clone) from Chapter 10 of “Making Games with Python & Pygame” (and Reversi from Chapter 15 of “Invent Your Own Computer Games with Python”.)

If you want to skip ahead and see the Flippy version with the “save game” feature added, you can download the source code and image files used by the game. You need Pygame installed to run Flippy (but not Reversi).

The Naïve Ways to Implement “Save Game”

A save game feature works by taking all of the values in the program’s variables (which in total called the game state) and writes them out to a file on the hard drive. The game program can be shut down, and when next started again the values can be read from the file and into the program’s variables.

If you are familiar with Python’s file I/O and the open(), write(), readline(), and close() functions, you might think that you can just open a file in write-mode, and then write out all the data to the hard drive that you want to load the next time the player plays the game. This is doable, but turns out to be a bad way to implement a “save game” feature.

Read the detailed explanation. »

What exactly is the format of the text you’ll write out? You could write out text like this (if you were making an RPG):

name=Hero

gold=42

hp=55/60

...

This has several problems. When you read the content in from the file to load a saved game, you’ll have to write a lot of code that is specific for your particular game:

fp = open('savedGame.txt')

name = fp.readline().split('=')[1]

gold = int(fp.readline().split('=')[1])

currentHp, maxHp = fp.readline().split('=')[1].split('/')

currentHp = int(currentHp)

maxHp = int(maxHp)

...

Yeesh. That’s going to be a lot of code we need to write, test, and debug as the game gets more complicated. Using the open(), read() and write() functions is good for basic file I/O, but not when it comes to a “save game” feature.

If you are familiar with JSON or XML, Python comes with built-in json and xml modules that can format your data to the JSON format or XML format. Then you can write this formatted text to a file. This is better, but still not as convenient as the shelve module.

Quick Start: The shelve Built-In Module

The shelve module has a function called shelve.open() that returns a “shelf file object” that can be used to create, read, and write data to shelf files on the hard drive. These shelf files can store any Python value (even complicated values like lists of lists or objects of classes you make).

Say you had a variable with a list of list of strings, like the mainBoard variable in the Flippy program. Here’s how you can save the state of all 64 spaces on the board (which are 64 string values) and the other variables (playerTile, computerTile, showHints, and turn):

import shelve

shelfFile = shelve.open('saved_game_filename')

shelfFile['mainBoardVariable'] = mainBoard

shelfFile['playerTileVariable'] = playerTile

shelfFile['computerTileVariable'] = computerTile

shelfFile['showHintsVariable'] = showHints

shelfFile.close()

The shelve.open() function returns a “shelf file object” that you can store values in using the same syntax as a Python dictionary.

You don’t have to put the word “Variable” at the end of the key. I just did that to point out that the name doesn’t have to be the same as the variable with the value being stored. In fact, just like any dictionary key, it doesn’t even need to be a string.

The data stored in the shelf object is written out to the hard drive when shelfFile.close() is called.

Note that the shelf file name is ‘saved_game_filename’, which doesn’t have an extension. An extension isn’t needed, but you can add one if you want. This will be explained more in detail.

Here’s the code to load the game state from a shelf file:

import shelve

shelfFile = shelve.open('saved_game_filename')

mainBoard = shelfFile ['mainBoardVariable']

playerTile = shelfFile ['playerTileVariable']

computerTile = shelfFile ['computerTileVariable']

showHints = shelfFile ['showHintsVariable']

shelfFile.close()

Page 1 of 3 | Next page