I suggest to abstract the requested features into different aspects of your game
Storage
Convert game states into store-able data and back.
Store
- extract the states from your game (positions, properties, animation frame ...)
- convert it into a storable format (e.g. strings, lists, ...)
- store it into a storage
Example:
import bge
storage = bge.logic.globalDict # globalDict is a predefined storage provided by the BGE
def store():
playerStorage = {}
storage["player"] = playerStorage # create a storage in storage
player = bge.logic.getCurrentScene().objects["Player"]
playerStorage["position"] = list(player.worldPosition)
playerStorage["health"] = player["health"]
This is just a very simple example demonstrating a basic storage system. When you have more data, you will need a much more complex data structure to keep all the states of all the different objects.
You do not need to use bge.logic.globalDict. You can create your own storage (similar to playerStorage).
Do not store any references to data that can't be persisted such as KX_GameObjects, KX_Scene, Vector. You need to extract the data that can be applied to a different object later.
Beside game states you need to store enough data to uniquely identify target objects for later restore. In the example it is the key "player" assuming this data is from an object called "Player". [Object names are not unique, so you need to store additional data].
Restore
Is the reverse of Store.
- read the data from storage
- convert it to game states
- identify the game objects it belongs to
- apply it to that objects
Be aware the objects you stored the data from are not necessarily the same objects you will restore it to. If that sounds confusing: Imagine you restarted the scene. This means the original scene is gone and all of it's objects are dead. But you created and loaded a new scene with new objects that look the same. But they are different object.
The objects do not even need to be equal. E.g. you stored the data of a walking character (e.g. health). Then you restore the data to a vehicle as the character is sitting inside the vehicle.
Identifying objects can be tricky. In most cases the object name is sufficient enough.
Example:
import bge
storage = bge.logic.globalDict
def restore():
playerStorage = storage["player"] # will result in error if nothing was stored before
player = bge.logic.getCurrentScene().objects["Player"]
player.worldPosition = playerStorage["position"]
player["health"] = playerStorage["health"]
In this example we assume that data from storage "player" should be applied to an object called "Player". The above operations assume these data exist. Otherwise the processing will return an error. You need to apply a proper error handling.
Usage
Store and Restore are useful within several situations:
- pre-step of persistence
- scene switch by keeping game states of related objects (such as player stats)
- object occlusion (objects out-of-sight are removed - and re-added when coming into sight again)
- network communication
Persistence
Often referred as Save/Load. It means you ensure the game states persist without a running game session. A typical situation is to persist the game states to a file.
There are several different ways to implement such a system. A very simple one is to use the build-in Persistence via GameActuator:
Save
The GameActuator in Save mode marshals the data from bge.logic.globalDict into a file called <your-blend-file's-name>.bgeconf
.
Example:

You simply activate the actuator and the BGE persists the previously stored globalDict to file.
Be aware this overwrites any previously saved data!
Load
The GameActuator in Load mode replaces the content of globalDict with the content from file <your-blend-file's-name>.bgeconf
.

Be aware: the complete globalDict will be overwritten!
A missing .bgeconf file will show a warning in the console.
All together
Now you have all the aspects together. You always need to consider the timing. This means you better store before save, restore after load. You always have the option to skip the persistence (e.g. on scene switch).
Advanced
The above examples are very simple. You will need to establish you very own storage. You might even want several different storage objects.
Always be sure what you store where.
Do not mix storage with other purposes (e.g. managing an inventory via globalDict). This will sooner or later result in heavy design issues.
The python part can become quite a lot of code. I suggest you do some training first to be able to manage that.
There are other ways to persist data. E.g. you can pickle the data via Python and save the pickled data to file. This supports more data formats than marshalling. E.g. you can store custom classes.
I hope it helps