Game changer

Plenty of stuff to unpack this week!

First I’d like to quickly mention that there’s a new type of variable available for use in 3D models that use skeletal animation. It allows controlling the rotation of a skeleton bone programmatically via scripts.

Continuous integration

One of the blessings of the modern web is that there’s so much computing power floating around that people are willing to just give it away: I’ve set up automatic CI builders for both Linux and Windows that get triggered after each commit to the Doomsday GitHub repository. I’m still planning to set up an additional OS X builder at a later time.

GitHub repository readme showing CI build status.

In the past it has been somewhat of a challenge when working on one platform that the build breaks on the other ones. CI builds should greatly alleviate the issue since any problems are caught early. Also, seeing the full build logs, including commands used to configure the build, should be helpful for people who’d like to compile Doomsday on their own machines.

Changing the game

My main focus was in reworking some core aspects of how the engine handles loading and unloading games and their resources.

In my “game-changer” work branch I’ve been cleaning up the procedure of changing the current game. My objective was to incorporate loading of Doomsday 2 packages into this, but it was somewhat difficult to see exactly how and where the integration should be done. The old code for this purpose was basically a blob of spaghetti that called into various other subsystems to release resources and then reload them with the new game’s data.

Separating this tangle into cleaner and smaller routines — segregating shared and application-specific parts — proved quite tricky. I basically broke down the code line by line so that it become clear which sections belonged to the lower level (libdoomsday) and which should be placed elsewhere. Eventually it was easy to see how the package integration should occur.

Now data files are located via the fast Doomsday 2 file system (FS2) index and marked as loaded via libcore PackageLoader, but the old resource subsystem is still being used for loading the data from the files. My plan here is to gradually pull apart the old file management code, dropping obsolete routines, so that the resource loaders can read data directly from FS2 objects.

Faster launch

Doomsday can now launch much quicker thanks to the more efficient file handling. Previously most of the startup was spent poring over the file tree, trying to locate the known data files required by the game plugins. This involved plenty of redundant indexing of files. Now with FS2 there is a single shared index that efficiently recognizes known data files, so by the time the UI is ready it is already known which data files are available.

When it comes to recognizing data files, the engine uses net.dengine.base/databundles.dei as a reference. This Info file specifies criteria for recognizing data files:

  • The basic properties, such as file name, size, and type.
  • List of required lumps for WAD files.
  • CRC32 checksum of the entire lump listing in a WAD file (this is affected by lump names, sizes, and offsets in the file).

These details are checked separately to calculate an overall score for each data file. The idea is to allow some flexibility so files from unknown versions aren’t ignored entirely. The UI will eventually reflect how confident the engine is about the contents of the data files.

Once a file is recognized, a Doomsday 2 package is generated with the provided metadata. This can then be loaded as previously discussed.

I’ve also added a simple splash screen to show something as early as possible, even before OpenGL and the set of essential resources have been loaded. Typically this won’t be visible for very long but the idea is just to give instant feedback that the application is starting.

Data files via Home

The next big task on my plate is redesigning the Home UI so that you can select which data files to use for each game, and create additional custom configurations for later. While I haven’t even begun sketching out my ideas for this, I decided it was necessary to add a simple way to pick PWADs before starting a game. (Granted, I wanted to load Romero’s new map without resorting to the command line. 🙂 )

"Data Files" button

This UI is essentially only for testing purposes. At the moment one can’t even clear the selection of additional data files without quitting and relaunching Doomsday. However, with Snowberry gone, it is nice that there is at least some workaround for loading data files via the GUI.

Thoughts on code cleanliness

My appreciation for rigorous management of code decoupling keeps growing by the day. Much of the week’s progress has been circling around bringing some lucidity to the process of changing the current game.

There is an infectious quality to messy code. New code that needs to interact with it also easily becomes messy — oversight of appropriate decoupling of components very quickly disappears due to pragmatic concerns. This has to be consciously fought against. My approach is to build on a foundation where each component has its well-defined responsibilities and dependencies, so that domains and concerns don’t get mixed up.

Admittedly a large portion of the problem is due to moving goalposts. Over the years, the project evolves, code conventions improve, and perhaps even the programmers’ skills grow. The “right” way to do things keeps changing, so even though code may be functionally adequate it just doesn’t rate very high according the new criteria.