I have written, in passing, about the resource-system and VFS ( Virtual File System ) I use in my own game-engine. This time it will however not be “in passing” but will dig down a bit deeper into one “feature” in it that I find kind of neat. I’m sure it has been done before but I have not seen it myself somewhere else. I’ll be writing about how I handle builtin resources in the engine.

When talking about a “builtin resource” I refer to resources generated by code and not read from files on disk such as a red.png or a cube.mesh. Resources read from disk I’ll refer to as “assets”. Builtin resources might be useful while prototyping in cases like “Oh, I’m creating an new enemy-type but I need some place-holder mesh and material while testing and I just do not want to model a cube and paint a red texture”

How is the resource-system structured?

I think that we will have to start with describing how the resource-system works, just to get some fundamentals down. In the bottom we have the VFS, or Virtual File System. That is just a system to hide access to “some kind of file-storage” ( file system, HTTP, archive-file etc ) where all files are referenced as an absolute path such as /assets/texture/apa.tex2d.

The VFS is in turn used by the resource-system that is a system with 2 purposes, creating/maintaining resource-containers and “turning VFS-paths to resources that can be used in engine”. I.e. load file via VFS and pass the data on to a callback, maintain a “handle” returned by said callback. A resource-container is just a collection of resources used to group resources such as base_resources and level_1_data etc.

Well, as you can see it’s fairly traditional :)

How about them builtin resources then!

So how do the engine handle the builtins then? Well, the paths to the VFS is always absolute and start at the root, i.e. start with a ‘/’. That opens up for “tagging” paths as special. So if the path is not starting with a ‘/’ it is not a valid VFS path and we could use that in the resource-system itself. As I currently have it implemented the resource-system supports to path-formats:

/absolute/VFS/path - a file path in the VFS. :res_type:type_specific_desc - a builtin for a specific type.

So if the path starts with, for example, :tex2: or :mesh: then the resource system just pass all that is right of the :res_type: to a specific create_builtin_callback for the resource-type registered for that type. Then it is up to the loading-code of the type ( tex/mesh/material etc ) to do what it pleases with the rest of the string. The callback for the specific type then just goes ahead an creates the desired resource and returns a handle to it in the exact same way as when it creates the resource from and asset or report an error back to the resource-system on error. I have ended up with just having all these paths ‘_’-separated and starting with a “base type” and followed by parameters, such as :mesh:cube_dim_(1,2,1)_pos_(0,1,0) to create a cube with dimensions 1,2,1 and center at 0,1,0 or :tex2d:solid_col_FF0000FF to create a solid red 2d-texture.

Pros and cons with the system

pros

I.e. you only have to implement “builtins” once for each type and whenever another system reference a resource it works with both assets and builtins automagically. Both “particles” and “renderables” can access builtin meshes via the same code for example. So when referencing a resource by VFS-path it will automagically work with builtins and by that works transparently from content.

You will get all your builtin resources to use the same allocators and the ordinary assets, instance sharing will work ( 2 “things” reference :tex2d:solid_col_FF0000FF and they will share texture-instance, debug-views showing loaded resources will show builtins, getting memory-statistics per container/resource-type works out of the box. In short, if it works with assets from disk it works with builtins.

cons

I would consider this the biggest issue and may make it unfeasible in a AAA-context where most of the times resources are identified by other types of ID:s. For most hobbyists, small-sized and mid-sized projects I don’t see that as a problem however as asset-counts and perf usually is “good enough (tm)” anyway.

This might also be a problem on a bigger team as the parsing need to handle errors well, warn clearly to the user what is wrong etc. Again on a smaller team where team-members work close together and problems ( such as error handling and error-output ) can be fixed quickly I think it should work out well. However take a note that it’s just a guess since my own projects is on a team of size 1 where all members think exactly like me ;)

This might be an issue but nothing I have spent that much time on. As these codepaths might not be that well tested and hardened it might be a simple way “in” for a malicious person if you are concerned by that. In that case you might want to just have this enabled during development.

Conclusion

I’ll just conclude by saying that this is a system/feature that has worked out really well for me on my own stuff and has proven itself to be really useful. As mentioned above it is really helpful to be able to reference “a red texture” or “a cube” directly via assets.

What do you think? Has this been done before? Any other thoughts? Hit me up on twitter and tell me ( if you do it in a civil way of course! ;) )

code  c++  assets