UDN
Search public documentation:
ConfigSavegameSystem
日本語訳
中国翻译
한국어
Interested in the Unreal Engine?
Visit the Unreal Technology site.
Looking for jobs and company info?
Check out the Epic games site.
Questions about support via UDN?
Contact the UDN Staff
中国翻译
한국어
Interested in the Unreal Engine?
Visit the Unreal Technology site.
Looking for jobs and company info?
Check out the Epic games site.
Questions about support via UDN?
Contact the UDN Staff
UE3 Home > Input / Output > Save games using the configuration system
Save games using the configuration system
Document Summary: This document explains how to use the standard configuration system to create a save game system.
Overview
The configuration system of the Unreal Engine is quite powerful and can be used for more than just saving various settings. This document presents a method to create a save game system for an RPG like game. The save game system is pulled of by clever use of the UI datastore system and the
PerObjectConfig
directive.
Before you start with this document, read the ConfigurationFiles document to understand how configuration files work in the Unreal Engine.
Sapitu
Sapitu (short for: Savegames Are Possible In The UDK) implements a simple save game system for an RPG like game. It has the ability to store a character and its inventory. You can download the full source code of this example here. Sapitu is split up into 4 classes. The download also contains 2 additional classes:
SapituGame
and SapituPC
, those are only used to play with the Sapitu system from within the game.
The four classes of Sapitu are as follows:
-
Sapitu
: This is the main class that manages various parts of the savegame system. -
SapituCharacter
: This class stored the character information. -
SapituInventory
: This class is an inventory item which can belong to aSapituCharacter
. -
SapituItem
: This class is used as a database record to createSapituInevntory
items from. Instances of this class are read-only within the system.
Sapitu
Class
This class defines some method to manage the creationg and loading of new characters. It also contains methods to create new inventory items, and keeps a reference of the item database.
Item database
The methodloadItemDB
initialized the database of SapituItem
instances. It requests all definitions of SapituItem
instances in the configuration files. This is part of the UI datastore system in the Unreal Engine. This system is also used to retrieve information about game types, maps, and weapons in UT3.
The getItem
method provides the means to look up an actual SapituItem
instance in the current database given the object's name (the Object.name
property). This name (or rather identifier) is an internal name. In your final game you would probably never show this to the player.
The item database is used by the inventory system to look up the static definition of the inventory items. And it is also referenced to create new inventory items.
Characters
TheSapitu
class is also the entry point to load and create SapituCharacter
instances. The character system makes use of the normal configuration system and the PerObjectConfig
class directive.
The getCharacters
method returns a list of IDs of all registered characters. Just like the identifier of the items in the database, this refers to the Object.name
property. It is not a user friendly name, but an internal identifier. This identifier is required during the loading and creation of characters. Due to the way the name is used there is an important limitation. The name should not contain spaces and various other non-alphanumeric characters. It is best to stick to using just the alphanumerical characters for the id.
Loading and creating of characters is actually similar. The both are done using the following code:
myChar = new(none, "MyCharId") class'SapituCharacter';The magic is within the second paramater for the new operator. This defines the name of the object to create. Because the
SapituCharacter
character is defined as PerObjectConfig
it will load the configuration for an object with that given name.
Because we want to make a clear distinction between loading and creating a new character in Sapitu we first check if a given identifier exists and then accept or reject the loading or creation.
Loading of a character is not finished by creating the proper instance. We also need to initialize it's inventory. The SapituCharacter
stores a list of identifiers for SapityInventory
items (SapituCharacter.inventoryRecord
). In a similar way these items are created and added to the list of inventory item instances SapituCharacter.inventory
. See the loadCharacter
method for the exact implementation.
Inventory item creation
Inventory items need to be created in a special way. An inventory item is based on a specificSapituItem
instance. the createInventory
method create a new inventory item based on the given SapituItem
instance. It constructs a unique identifier for the inventory instance, and then executes the special new(none, inventoryId) class'SapituInventory'
constructor to create inventory item. After that it will initialize various variables that were loosely defined by the SapituItem
instance, like the level, weight, and value.
The created inventory item does not belong to any character, in fact, it has not been saved to the save file. So when you exit the game, this instance is also lost. Saving of these items is left to the character instance when it has this inventory item in its inventory.
SapituCharacter
class
This class is defined as
class SapituCharacter extends Object config(Sapitu) perobjectconfig;This means that certain variables in the class will be saved in the configuration file
UDKSapitu.ini
, and that for each object a separate section is created. The latter is the result of the perobjectconfig
class directive. The name of the object is of importance when saving the instance, because it defines part of the section name.
This class defines various config variables for the character name (which is the human friendly name), health, etc. The character's inventory is stored in a different way. Because object variables cannot be a config variable we keep a record of the identifiers of all inventory items (which are strings). And save that list instead. This means additional administration is required to manager the inventory.
Adding and removing inventory items must be done using the addInventory
and removeInventory
methods. These method update both the inventory
and inventoryRecords
arrays. The inventory
array should not be modified directly. The Sapitu
class does do this during load, but that's a special case.
Additionally, a saving of the character has to be done in an alternative way. You can not call SaveConfig
directly, because that does not save the inventory properly. The save
method iterates through the inventory array also calls SaveConfig
on each item, and then calls SaveConfig
on itself. This way everything belonging to this character is properly saved.
Note: that neither the SapituCharacter
not the SapituInventory
instances are saved any where else in the Sapitu system.
SapituInventory
class
This class is an actual instance of an inventory item. It is based on an specific instance of the SapituItem
class. This class is declared in the same way as the SapituCharacter
class.
Because this instance is based on an SapituItem
is needs special care with the regard to recreating to the proper reference. This is done by the Sapitu
class as mentioned earlier.
SapituItem
This class defines an item type which can be used to create an inventory item from. This class should be considered as a readonly database entry.
Unlike the SapituCharacter
and SapituInventory
classes this class is a subclass of UDKUIResourceDataProvider
. It is not declared as config
, because the parent class is already defined as a config class. It is declared as PerObjectconfig
.
Just like the other classes this also defines a couple of config
variables. These are used to create an item definition.
Also notice the bSearchAllInis=true
entry in the defaultproperties section. This variable is part of the UI datastore
system. It defines that the datastore system should go through all configuration files to find objects of this item.
Loading of SapituItems
should not be done through the previously mentioned new(none,id)
constructor. To get all declared SapituItem
s you should use the following code:
class'UDKUIDataStore_MenuItems'.static.GetAllResourceDataProviders(class'SapituItem', ProviderList);(see the
Sapitu.loadItemDB
method)
SapituItems
are declared by hand. At runtime the should never change. To declare an item simply create a configuration file. And add an entry like this:
[sword1 SapituItem] DisplayName=Short sword level=(min=1,max=10) weight=(base=10,levelMult=0.5) value=(base=5,levelMult=1)See the
UDKGame\Config\SapituItemDB.ini
file in the source for more examples.
Save game storage
The characters and inventory items are saved in the file
UDKGame\Config\UDKSapitu.ini
. See the file in the download for an existing "savegame". Note that all characters and inventory are saved in the same file.
Also note that it is saved as plain text. You could worry about possible cheating. But for a offline single player game you can always cheat by modifying the save game. It does not matter if the save game is plain text or a binary file.
Playing with Sapitu
To play with this system, simply compile the source and start a game as follows:
udk examplemap?game=sapitu.sapitugameThe
SapituPC
class defined a bunch of console commands you can use to play with the system:
- createChar name
- saveChar
- loadChar charId
- printChars
- showChar
- createRandomItem
- createItem baseItem
- pickupItem itemId
- pickupAll
- findItems
- listItemTypes
Downloads
- Sapitu-source.zip: source code
- Sapitu-source-2010-04.zip: source code (2010-04 build)