Last week I was working on a variety of small tasks. I also started a branch for a major refactoring of the engine’s code base.
The week started with a couple of fixes to how Snowberry passes command line arguments to the engine. After merging the "de2-args" branch, I hadn’t yet touched the frontend to make it use the correct quoting on the arguments. In build 535, I fixed the quoting for Unix and Mac OS X, but accidentally broke it for Windows. Thus I had to make an out-of-cycle build 536 to fix it.
When I added JPG support
, the changes also influenced how PNG images are loaded. Some of the image formats were not being correctly processed after loading, leading to the red and blue color channels being swapped for some images. This was fixed for Friday’s build 539.
I started work on adding support for Hexen v1.0
. While I recommend using the Hexen 1.1 IWAD with Doomsday, having support also for v1.0 should make life a bit easier for people who haven’t or can’t patch their copy of Hexen. There is now a separate hexen-v10
game mode for the Hexen 1.0 IWAD. In a multiplayer game, all players must have the same version of Hexen (1.0 or 1.1) – mixing these is not allowed. There is still a number of glitches with hexen-v10
, though. I only had time to fix one of the biggest issues: the intermission and victory texts were missing in v1.0.
Recently I added window focus events to our window management so that the game can be automatically paused and unpaused when the game window’s focus changes. It has been a bit inconvenient, though, to automatically unpause the game immediately when the focus returns to the window. The new default behavior is that the user has to manually unpause the game after returning to Doomsday. The variable game-unpause-focusgained
can be used to control this.
We are planning to split up
the big Doomsday executable into smaller components. This will make things easier when transitioning toward the 2.0 engine architecture. To get started, I created the “libdeng” branch, where I set up a new shared library called libdeng1. After the branch is merged to the master, we can start moving suitable functionality from the Doomsday executable to the new library. For now I’ve just moved the Smoother class, as it was a suitably independent and isolated class. The current status of the libdeng branch is that I’ve verified that Smoother works correctly on all platforms while residing in libdeng1.
The plan for this week is to introduce libdeng to the master and then continue moving some functionality in the work branch. In practice moving classes is not that easy because of the multitude of interconnections between modules in the engine’s source code. Much of the code relies on the console, file system, GL, and memory subsystems, and moving a single class/module will necessitate moving much of this low-level functionality, too. It is a bit of a challenge to make small, clean moves. However, this also provides a nice opportunity to apply a machete to some of the dependencies to sanitize module boundaries.
Last week I decided to take a break from working on the replacing-walldivs
branch to implement autosaving.
The first job of the week was to enhance the build repository
by adding direct_download_fallback_uri
to the JSON package graphs, thereby allowing Doomsday to use an alternative URI when acquiring an update package.
Now that Doomsday features a useful automatic update
system, it became clear that we now needed a way to save the game, automatically, before installing the update. As I was already familiar with the way this was implemented in Hexen (and the last dev to touch the system) we decided it would be more time efficient for me to continue where I'd left off.
As Hexen already implements autosave functionality, it made sense to use that as the basis for a common mechanism for all supported games. However there were several useabilty issues therein and the save state management itself was rather messy (the game session config and save metadata (name, gamemode, skill level, etc...) being spread over various data objects and structures).
Consequently I decided it would be prudent to spend time improving the system itself before attempting to augment it further. I figured that if I restructured the logic such that all save state metadata is available in one place, through a (serializable) "SaveInfo" class (effectively encapsulating save header IO), that extending the system further would be greatly simplified (and improve robustness in the process).
This refactoring work has progressed well thus far. All games now use the same binary format for the serialized save state header and we now have a preliminary autosave feature in all supported games (save occurs after the current map changes for the current game session). Plus we already have some useful new functionality:
: Variable game-save-auto-loadonreborn
When enabled and the player asks to be reborn; attempt to automatically load a game save state in the "auto
" slot. If no autosave is found then restart the current map (a.k.a. "pistol start"). Default: off
: Variable game-save-last-loadonreborn
When enabled and the player asks to be reborn; attempt to automatically load a game save state in the "last
" slot. Can be used in combination with game-save-auto-loadonreborn
such that the "last" slot is preferenced over the "auto" slot. Default: off
The plan for next week is to continue work on autosaving, implementing that SaveInfo abstraction I mentioned earlier and improving the system to the point where it can be enabled by default in all supported games.