Devlog: Preserving squad data across levels - Ivan Shyika
Hi! I am Ivan Shyika, our Team Leader, Project Manager, and Engine Developer.
Today, I would like to share about the issue of transitioning data between maps in our game and my solution to it.
PROBLEM: Data Persistence
First of all, why keeping data between maps is a problem? There must be ways to store it, right?
And you would be correct. Some objects exist from when a game opens and until it is closed, regardless of whether you are in the menu or in a "real" game level. The issue, however, is the specific data you likely want to store - for example, the status of your squad - exists not in those perpetual objects but in transient ones such as "actors" located at the game level. When one map/level is unloaded, those transient objects are deleted with all their data. The only way to preserve that data is to copy it into a perpetual object before the transient owner is destroyed.
Our Case for Data Persistence
In our game, a squad of heroes travels from chamber to chamber (our term for "level"). There is a lot of information to keep track of: gold, playthrough time, the count of completed chambers; and above all, information about the squad itself, which is an arbitrary composition of Heroes of different classes in arbitrary conditions (each hero of the squad has their own health and may have died in one of the previous encounters).
Because the squad can be customized, we have to remember the squad composition (i.e., which Hero classes the squad consists of) in such a perpetual object so that the squad can be recreated. In addition, there are also things like health upon completion of a chamber, and we also must have a way not to confuse data between heroes.
So, if the squad is essentially forgotten on chamber completion, how can we recreate the squad at the next chamber seamlessly?
SOLUTION
Data Organization
We can use a series of specialized containers that will be stored within one another. Think of it like a box in a box in a van:
- Hero Data contains information relevant to one particular hero in the squad: their class, current HP, whether they are dead, and a pointer to the Hero entity in the world. It is like a profile of you at this point in your life, and the pointer to the entity to be an indication at you as a human being. The profile describes you, and the pointer/indication can be used if someone wants to refresh or deepen their knowledge about you.
- Squad Data is a container of Hero Datas - simply put, a catalog of profiles.
- Run Data contains all the information pertaining to the playthrough: Squad Data plus all the other variables like current gold, health potions count, playthrough time, and game progression statistics such as a list of encounters completed so far. It is like the principal spreadsheet with *all* the info that needs to be tracked.
This idea of compartmentalization is often referred to as modularity in software development. In essence, a complex system is broken down into smaller, individual chunks ("modules"), which can function independently.
That topmost spreadsheet (Run Data) will be stored in a perpetual object. And since the catalog of profiles (Squad Data containing individual Hero Datas) is stored within it, we have all this data stored safely where it will not be deleted (until the game is closed).
Such a modular setup allows for a straightforward implementation of data persistence and save file systems: if you want to recreate a squad, you only need an instance of Run Data. And if you want to have a history of playthroughs, you would only need to load a list of Run Datas.
Applying and Updating Data
There are two key times when the data persistence system is essential: recreating squad on chamber load, and updating squad data on chamber completion.
Recreating a squad
- On encounter start, we consult the principal spreadsheet (Run Data) to recreate the squad as it was at the end of the previous encounter.
- We go through the entire profile catalog (Squad Data), retrieve individual profiles (Hero Datas), and recreate alive heroes based on their hero class.
- We update Hero variables (like current health) to their last known values.
- Finally, we set the pointer inside of the profile (Hero Data) to point at the newly created Hero.
Updating squad data
On the encounter end, we need to update Run Data with up-to-date information on the squad. Updating information is very easy as we have the pointer to every hero stored in their profile (Hero Data).
- We retrieve the profile catalog (Squad Data) and walk over each profile (Hero Data).
- The Hero pointer inside of each profile (Hero Data) will tell us which hero to consult to update this specific profile (Hero Data). Using that pointer, we set the variables in the profile to the values of the alive hero.
- Once we are done with actualizing the info, we proactively invalidate the pointer because the chamber is about to unload, destroying the Hero object in the process.
Handling hero death
You may point out, "But what if the hero dies and no longer exists?" That's an important consideration.
If the hero is dead, it does not make sense to recreate them in the next encounter. Besides, their profile will not change after their death, so there will be no need to update their profile either.
And it is accounted for: when the hero is created, the system proactively asks them to let the system know when they die so that the system can mark them as such and invalidate their pointer.
You may be surprised, but in our game, Heroes are so obliging that they always inform the system about their death right before they die, even despite the inconvenience of it. They are true examples of commitment and human decency. Fills you with hope for humanity, doesn't it?
Conclusion
We can now rest assured that any squad data persists across the in-game chambers. Furthermore, you know an example of modularity applied in a real-world case.
I hope you found this breakdown useful, and I thank you for your attention.
Best,
Ivan Shyika
Team Leader, Project Manager, and Engine Developer of Good Faith Team
Get Return to Divinity
Return to Divinity
Strategic combat, tactical formations, and perilous dungeon runs—can you survive the depths?
More posts
- Devlog: Overhauling Squad Movement and Formations - Keegen Love6 hours ago
- Devlog: Hero Classes and Special Abilities - Ivan Shyika15 hours ago
- DevLog: Implementing Death (Animations) - Violet Weathersby16 hours ago
- DevLog: Squad Selection Crashes - Violet Weathersby6 days ago
- Devlog: Fixing Squad AI Freezing in Combat: A Deep Dive into Task Instancing and...6 days ago
- DevLog: Camera Issues - Adam Denomme6 days ago
- Devlog: Designing interaction between player and autonomous AI - Ivan Shyika13 days ago
- DevLog: Creating the Player HUD - Violet Weathersby13 days ago
- DevLog: Fixing Invalid Click Locations in Pathfinding - Keegen Love13 days ago
Leave a comment
Log in with itch.io to leave a comment.