Sonstiges: Developer Diary - The Creation of a 3DS/Switch Game
Michael Grönert, am 26.12.2016, Seite 8 von 15
Part 8: Saving & Loading
Now that we can change first states in the game like positions of objects in our inventory, it’s time to deal with a save system. Again, there are some aspects that should be well planned beforehand and others that can be addressed immediately. As you may know from other games, there are different variants of saving systems. In some games, saving is restricted to certain locations or to certain events. In others you can interrupt and save the game at almost any time. Some games only save automatically and some may allow you to do so manually, too, while others can only be saved manually. Often, there is a fixed number of usable savegame slots while other games theoretically allow an infinite number of game slots, provided there is enough memory available. There are several reasons for these differences. On the one hand, it should fit the general theme of the game and not, for example, have a negative impact on the mood due to long waiting times or have frequent saving make the game too easy. Especially in the case of older hardware, such decisions are strongly influenced by the technical aspects, such as a low memory capacity.
Integration into the game
I would like to have the possibility to save by pushing a button, even if only for testing purposes. Later, I might change it to have the game save its state by itself but that depends on how long the process takes on my target platforms. If the game were to take a second or longer to save after each action that changes a state, it would affect the game flow too much. But perhaps I would like the player to not be able to backup every step and to reverse wrong decisions. In that case, I should give them no control over the system. I will leave the decision for later in order to be able to match it better to the rest. Alternatively, I had the idea that you could carry some kind of diary as an item in the inventory with which you can save at any time. The player will then be allowed to get rid of this object if he wants to do so.
So I start with two small buttons labeled "S" and "L" with which I can save and load at any time on the overworld map. For now, I just want to save the position of my character and the items in my inventory. Next, I thought about the file format in which I want to save the game. There are easy-to-read formats, such as XML or JSON, and binary variants which are illegible to people. The first variant is easy to understand and change - practically an open invitation to cheat. The second one consists of unreadable strings of ones and zeros which require much less space than written out words. Especially on consoles, where the storage space plays a bigger role and the savegame files are hard to reach and change with a text editor, legibility definitely plays a smaller role compared to saving memory.
What and how to save?
In previous projects, I've always created the savegames manually, so the files got written and read by their own code. For this you have to take care that all sequences always remain the same and that everything is complete or can be bypassed when something is missing. With Unity, you can make your life easier by creating serializable data objects that can then be automatically saved and loaded (see Serialisability on Wikipedia). This can not be optimized as easily as a manually created procedure but it simplifies and speeds up the process considerably. While I can simply add a new variable to such a serializable object, which is then stored, a manual variant would have me write each variable individually into the file.
So I create a serializable object with a variable for every value that I want to store. In my case, it’s the X and Y coordinates of my character, but not Z because we can only move on a flat plane at the moment. This also serves as a great example for how much room for optimization we have:
1. I drop unneeded information like the Z-coordinate.
2. Range: Depending on how big the world can be, you could limit the coordinates. For example, smaller data types may be sufficient for which less space has to be reserved. (For example, a sbyte covers values from -128 to +127 and short for -32.768 to +32.767.
3. Accuracy: The above mentioned data types can only keep integers. So I throw away the digits after the decimal point. I could also stretch or compress the value range and "encode" it differently - divide it by eight before storing and multiply it by eight after loading.
4. Alternatives: Instead of the coordinates, I could use fixed locations that work as predefined save points and save me the trouble with the big numbers. I would only have to remember the locations, maybe in the form of a much smaller number.
In addition to the coordinates, we need to take care of the items. With these it is somewhat more complicated since, theoretically, there can be any number of items and even whole inventories. Examples of other inventories would be chests or items that can contain additional items, such as our GameGuy. For the time being, I limit myself to the inventory of my character, which can be a list of items of any length, and another place for items - the previously mentioned GameGuy.
Even when saving, there are advantages to using inheritance and abstraction. On the one hand, there is save data for the main game itself, as mentioned above. In addition, there is data for separate mini games as well as shared data between all of them. For example, all games should have a level and therefore experience points must be stored. The main memory file can then hold a list of mini game data, making it possible to pack everything into a single file. Alternatively, the data of the mini games can also be kept in separate files.
These thoughts, however, raised questions: Can you have multiple copies of the same game? And if so, do they have their own savegames? Would that mean you could produce infinite game data? These are questions I will not answer right now. It will ultimately depend on how much disk space there is available on the target platforms.
This should suffice for a little insight into saving and loading. In the next diary entry I would like to expand the interface between the mini games and the world - menus for several possible options are still missing, after all. In particular, I will focus on the skills system that will be placed here. This will allow us to further develop our mini games.
Do you prefer to read this diary in the developer's mother tongue? Then click here to read this diary entry in the original German language!