In my previous post, I explained how unique resource file names were generated using the data contained within them. This is a darn useful feature, but in the long run it can undermine one of the biggest mainstays of game development.
If you're writing a game, chances are you're going to get something wrong. After you've written a game, deemed it 'shippable', and sold a few copies; days weeks or hours later you will get users complaining about issues.
Your game will have Bugs, and it will usually be in your best interest to fix these bugs and release a Patch; and depending on what you choose a patch can be easy or complicated.
A mainstay of patching a game, is changing a number of resource files (script,images,etc.) bundling them into an installer and releasing this. The user installs these files over the existing files and all is well...
...well, not always; this form of 'data-patching' can't solve every issue, especially issues that have been previously 'baked' into saved games. But data patching is one of the best tools a developer has to fix a bug in their game.
The Selenite resource system broke data patching!
That's right, I should have seen it coming, but we all make mistakes, just like when writing a game.
You see, whenever file data is changed, Selenite would make a new resource file for it, and this resource file would have a new name. Now, if I distributed these new files; all new games would work fine, but previously saved games wouldn't; and we can't have that.
Sure there are times when a bug is so bad that your save game is just toast; but this would be the case for any bug, you couldn't patch a thing in the game, and since most of the time patching can still render save games useful and even fixed this was no good.
Origin of the problem
After many days of failed thought experiments of how to fix this issue, finally got to the crux of the matter.
The problem is saved states hold references to resource files; the save game files, are holding information to resource file names which would never change as a result of normal gameplay. Why? you ask was I doing this? Because the game obviously needed to know what files it was using for various objects. If I save an actor instance, it needs to know what images to load back up, and the only way to persist that is through a file name, or some other system of reference... "system of reference... you mean like an alias!?" yes, or a 'file name' the very thing I sought to get rid of in the first place.
So by removing the developer-controlled ability to name resource files, and keep those file names constant, I destroyed data patching. But my issue in fact ran deeper, to a basic concept that I should have added a long time ago.
Originally in selenite, you would design 'instances' through the editor, each object was created and isolated, even if two objects were identical they would still be seperate. If I made a hundred trees with a single tree image, I would need to change each tree to a different image it I wanted them all to change. I noticed this issue, early on, and saw it as a potentially large user hurdle, but chose to ignore it. Now however it came and bit me in the butt in a completely different way.
Instances were holding references to their resource data, and thus binding themselves to always using these resource files.
The key to solving my problem was to re-introduce a developer naming scheme, but on a far smaller scale, and also result in a major feature development.
Points of separation
What I've shown is that with two points, The Resource File and the Game State joined by a Hex Hash tightly couples these two points making it so that changing the resource files results in new resource files and the game state referencing the old files:
Resource File <-> Hex Hash <-> Object Instance
The developer has no control over the hex hash, which is a feature we want.
The solution is to give the developer control over something useful to them Classes.
By introducing a class concept, the class would hold all references to resources (via hex hashes), an an instance would hold a reference to a class (via a class name).
This was the key! Reintroducing developer controlled naming, but at a higher, more useful level.
Resource File <-> Hex Hash <-> Object Class <-> Class Name <-> Object Instance
The New System
Class definitions were to store all gameplay immutable data, which most importantly was, the resources needed for a class, via their hex hashes.
All of the classes for a game were stored in classes.bin, a very lightweight library of Class Object definitions.
The file game.bin, would contain object instances, and all of the gameplay mutable data, and in addition, the reference to the class object which 'backed' them; via the class name, which is developer defined (e.g. "CTree").
When patching, new resource files would be created, in addition to new classes.bin and game.bin files; these would be distributed to the user.
The new game.bin file would contain possibly new data that would apply to new games.
Older save games when loaded, would create their instances, and each instance would look for it's class object, via the class name, which wouldn't have changed (unless by design). The class objects found would contain new hex hash references to updated resource files, thus giving old save games new, patched data.
In addition to fixing the patching problem; developers could now define a 'Tree' class, which they could base their one hundred trees from, and should they wish to change the tree image, would simply change the class data.
In my next post we will finally get into game state and see what mutable properties exist for objects in the Selenite Engine