My next step is to devise the actual format of a next-gen (model) package. I am not going to worry about backwards compatibility at this stage, and instead think of a clean-room ideal solution. Existing packages need to be handled separately, or perhaps automatically imported/converted to the new format and rules.
There’s this notion in my head of a self-contained package:
All the files needed by a 3D model asset should be in the same package. Modularity is a great thing: it makes installation and management of packages easy. No need to worry about “auto” folders or some specific location where things need to go; instead, if a package is enabled, it will be used according to its (ScriptedInfo) metadata.
Now, certain groups of model assets benefit from sharing common resources: for instance, they could be using the same textures, shaders, or sub-models. There has to be a way to package common assets and allow other packages to refer to them.
According to traditional lines of thinking in the engine, the solution is to create a bunch of lookup namespaces and use URIs as addresses. However, I’m much inclined to do everything via relative paths. This sidesteps the entire arduous task of having to update the lookups whenever packages are enabled or disabled.
- Textures in model files are specified as paths relative to the model file.
- Shaders and other files are specified as paths relative to the
.deimetadata files (like in the UI style pack and renderer resource packs).
- Thanks to FS2, it is possible to have all active packages visible in the file system at a specific location. For instance, a common package called “drpcommon.pack” would appear mirrored at /packs/drpcommon/ (ok, I haven’t figured out a naming convention for packages; maybe some Java-inspired dot notation is in order?). Any package can then trivially refer to other packages’ contents, and even check if they’re available. As a bonus, this enforces unique naming of packaging; only one can exist under /packs/ at a time.
There should be only a single object (say, a lamp post) inside one package. This way there’s enough granularity to enable, disable, or otherwise configure models for individual objects. Larger collections of objects can trivially be created by putting packages inside a collection package. Metadata tags are another very useful way to handle packages as groups based on traits or any other tagged characteristics.
Since FS2 handles zip and regular folders interchangeably, it will be much easier to create hierarchical packages: a zip is only needed at the top level, while the rest of the packages can be in regular folders inside the archive.
As a practical next step, I will find a suitable test model and start putting together the core of the new package management system so that the test model is visible at runtime. The metadata of this package will contain the model definitions, which hopefully can be integrated into the old model asset management in a sane way.