Construct 3 provides an easy way to make savegames. These allow your players to save the game, then come back later and load it from exactly where they left off. It's important for long games, especially when the levels or stages are lengthy. While it's possible to have a very simple "last level reached" type save using Local Storage, it's usually very difficult to use it save the full state of every last object. The System object's Save and Load actions conveniently allow you to do just this, allowing you to easily add a complete savegame feature with very little effort.
Basic savegame support
A simple way to add savegames is just using the system Save and Load actions when a certain key is pressed. For example:
For mobile games you'll obviously need to use some kind of touch input instead, but to keep things simple we'll focus on a desktop game.
Savegames are stored on the local system by the browser. This means players can switch off their computer or device, come back the next day, and the savegame can still be successfully loaded. Note however savegames are associated with the specific browser. For example, Firefox and Chrome will store savegames separately; if a player saves a game while using Chrome, then switches to Firefox, they will not be able to load that savegame.
Savegames are not saved in the cache. The browser cache is a very much temporary storage that is used to save things like images on web pages without having to re-download them every time, and it's regularly cleared. Savegames are saved instead to IndexedDB storage, which is more permanent. However the user can still manually clear their storage which will wipe IndexedDB as well.
Save slots
It's often useful to allow players to have multiple savegames. This is what the save slot allows. Each slot is like a separate file that stores a different save. You could offer the player a set of slots to save to, or allow them to enter their own savegame names.
Note that most browsers have a limit on how much data a web page can save to disk. This is unlikely to be a problem for most games, but if you have a huge number of separate save slots you might hit the storage limit. Offering a limited number of save slots is a good way to ensure you never hit the limit. Appropriate use of the No Save behavior can also help make savegames smaller (see below).
Completed triggers
Saving can take a moment to complete, and the game keeps running in the mean time. Once saving has completed, the System trigger On save complete triggers. Similarly loading can take a moment to finish, and triggers On load complete when done. Note any changes made after the Save action, but before On save complete triggers, may still be saved.
If you try to load from a slot that hasn't been saved to yet, On load failed will trigger. If the user is choosing a save slot to load, you may just want to start a new fresh game in this event.
'No Save' behavior
Anything with the No Save behavior will not be saved, and won't be affected when loading. It is good practice to add the No Save behavior to any static objects, such as scenery and backgrounds. It can also be used on automatically-updated objects like the HUD and text objects which are updated every tick. This won't make any difference to the game, but it makes savegames smaller and faster to save and load, since the unnecessary information is omitted.
Changing the project after saving
Savegames should be robust to changes in your project. You should be able to add, remove and reorder various things like variables, behaviors and other objects, and still have old savegames load successfully. Note however anything new you add won't have save data for it, so will not be affected when loading. Also note if you remove anything from the project it won't be able to load again either. You can delete individual instances without affecting savegames, but if you remove entire object types, layouts or layers, they will never be loaded back from a savegame.
Advanced topics
Everything covered so far is enough for most games to easily add a savegame feature. However advanced users may be interested in the following topics which go in to further detail about the savegame system.
Saving data somewhere else
By default the savegame system provides a basic ability to save and load to and from named slots in browser storage. You may wish to save to another location, such as to a file using the File System plugin, to a cloud service, or even just with the Local Storage plugin so you have more control over save data (e.g. being able to identify used slots, or use encryption or compression for save data).
To do this, use the Save to JSON system action instead. Then when On save complete triggers, you can use the SaveStateJSON system expression to get a string of the save data in JSON format. You can then save this somewhere else, and later retrieve it again and then load it with the Load from JSON system action.
Save location
By default the built-in save slots save to the same location as the Local Storage plugin uses, which is browser storage. This is stored in an internal database and does not produce any easily identifiable files on disk. If you want to save data to easily identifiable files on disk, such as storing save data in a file in the user's Documents folder, consider using the File System plugin instead - see the section Saving data somewhere else above for more information.
Tracking which slots are used
The system save/load actions don't tell you which slots have been saved to. The best way to track this is to skip using the built-in slots and save using the Local Storage plugin instead, which has the ability to check whether key exists, as well as listing all keys. See the section Saving data somewhere else above for more information.
What is and isn't saved
The full state of the game - including instance variables, global and local variables, behavior properties, effects, particles, currently playing audio, etc. - is saved. However there are a few exceptions, hopefully none of which are surprising. The following things are not saved and won't be affected when loading:
- Input state (i.e. mouse position, or whether the player was holding keys or touches)
- Network connections, including AJAX, WebSockets, and Multiplayer connections
- The XML object
- User Media video or audio feeds
- Login state for any services like Facebook
- Local Storage state
- Any in-app purchases on any platform
- Anything with the 'No Save' behavior
Versioning
Usually you'll be able to change your project and old games will still load just fine. However some advanced users may wish to track precisely which version of their project a savegame has come from. You can do this using a global variable. Call the variable Version and initialise it to 1. Later, if you publish a new version of your game, change the initial value of the variable to a new number, e.g. 2. Now when On load complete triggers, the global variable has been loaded and set with the value of Version at the time the Save action was used. This might be useful if you add lots of new objects to the game, but want to make sure they're destroyed or hidden when loading old savegames.