During most of Selenite's life there were no classes
Classes are a relatively new feature in the design of Selenite; and they are there
out of need first and convenience second.
The way resources work
The Selenite Editor, manages resources for the developer; you simply add files to the project in the context of their need:
import images for animations, add sounds via loading sound files, etc.
in addition to some resources being created for you through data entry, notably as you write scripts, or choose a font to use for the game, which is promptly converted into a bitmap font image, and widths data.
but for anyone who has made a resource system, or an editor, they know that resources can be difficult.
- Do we save linkages to them?
- Do we pack their data along with us?
- How are resources shared?
- How do we avoid duplicate resources?
- How do we avoid broken file linkages/mis-namings
That is quite a list of issues; most indie game developers and engine developers, simply use a folder of external resources, named in various varieties:
you get it...
these of course are subject to the above issues, they can move, they can be renamed, rock and rock2 could be the same image, and all other manners of things can go wrong, not least of all forgetting to distribute some of these files with the final game, resulting in an error.
The issue is, the developer has his fingers way too deep into this process; and when developing an all inclusive editor, it simply doesn't need to be the case.
For a good sized game you're looking at, at-least thousands of resource files, but more like tens of thousands if it's a big production; as humans we aren't really wired to deal with that much data management, and while we can do an okay job of keeping it all in order, we'd rather not have to.
"Computer, arrange my data for me."
The computer however is exceptionally good at dealing with this much data, however it must be in a form that it can easily understand; and so I used a fairly familiar method.
As each resource is imported, or created as a result of user input I do some work on it.
I first open it up completely and create an MD5 hash from its entire binary data. This hash is then converted to an ASCII hex string, so it results in 32 characters.
MD5 is very good at creating a unique value for a set of data; and while it can be made to have collisions, duplicate hashes for different data, it seems that is rather rare with real-world, not-made-to-break-it data.
Once I have this hash string, I open a new file in a project-local folder (resources, call it) and write the file data into a file with the hash string as its file name, with a .bin extension.
What I have done here, is created a file, and made its file-name associated with its data. Now I should mention that before i actually write this new file I check if it exists because if it does exist, it means the developer has already imported a file that is exactly the same.
I save the hash string and use it as the 'resource reference' a 32 character resource identifier, very handy.
With this system I get:
- No filename conflicts
- No duplicate data
- Automatic sharing of resources without developer involvement
- No broken links (files are stored in a project relative special spot)
- The user not caring about their resources
This post has grown over-long so in my next post I will explain why this extremely elegant and beneficial resource system all but staked Selenite in the heart for a time and how Classes were the answer.