This post originally appeared on Reddit’s /r/roguelikedev Sharing Saturday. Original post.

My week’s development was slowed down by a head cold, and going over some of what I wrote while feeling under the weather – it was awful, and needs reworking. So, I clocked a bunch of Cogmind hours (and submitted some hilariously low scores while playing on Nyquil!). Cogmind on Nyquil is still surprisingly satisfying, but not a good way to get to see the lower levels!

Anyway, work on the 0.11 release is really close to done. I’m down to one issue in that card column! Changes this week:

  • I finished up the pervasive materials task. That is, materials stick around through every item or construction’s lifecycle. An ore may be of the type hematite_ore, and that type is applied to the resultant ore when you dig it out. When smelted, the raws are checked and iron comes out. Build a knife with it, and the result is an iron knife(recycle the knife, using stuff that isn’t in the game yet, and you get iron again). Likewise, if you build a wall, it’s now an iron wall – knock the wall down, and reclaim your iron. This simplified the tech-tree a LOT, since there’s no more messing around with tags like bronze_dagger, copper_dagger, etc. – just dagger and a material tag.
  • To support the above, reactions and building tasks have a filtering system in the raws. So you can specify that the inputs for a given task are blocks, but now you can also add tags that match by exact material (so this reaction only works with clay blocks), or you can specify a category (so this reaction only works with metals).
  • Sentients who spawn (which is defined in the populations.lua file) have changed their descriptors from bronze_dagger to dagger/bronze. The first half is any item, the second is the name of a material to apply. Since game-created items don’t have the same heritage (their building is abstracted), this lets me keep the same system but fuzz the inputs a bit.
  • Materials now directly affect armor and damage bonuses for clothing/weapons respectively. Right now, it’s a simple bonus/penalty – but very soon it’ll be category based. So dense metals can be better for crushing damage, while not so great for slashing.
  • Fixed an issue whereby the planet wasn’t being saved as part of an autosave, so it would save correctly but civilizations would forget how they felt about you.
  • Notify the user when autosave happens, so you don’t wonder “where did my fps go?”
  • Added a kiln building, and the ability to bake bricks from clay blocks.
  • Rogue Mode (control a single character) now has tooltips, just like the main game. It was meant to have had them before. Oops.
  • Support windows. A tile being opaque and being solid are no longer the same thing. This was relatively easy, because I’d already stubbed in support – I just had to switch a couple of things around to make it work. Added some windows to the spaceship template.
  • Finally fixed the logic determining which glyph appears for a wall, relative to its surroundings. I’d missed a case, and picked the wrong glyph in a case. It uses a bitmask approach (sum of 1 for solid north, 2 for solid east, 4 for solid west, etc.).
  • Added a slow_tick message, which fires at 1/10th of the normal frame-rate. Hooked particles to it, so they stick around long enough not to be an odd flicker.
  • You can now click on sentients and grazers, select them from the menu, and see an information screen describing them.
  • When there are multiple objects on a tile, rather than just showing one, it cycles between them. This also uses the slow_tick.
  • When you build a solid wall on a tile containing objects, the objects are moved out of the wall.

The remaining issue is one of serialization. I’ve repeatedly run into cases in which save games don’t work quite right, and previously these have been a slow process of matching calls to serialize/deserialize up to find what I missed. That takes too long, and every time I’d find myself saying “man, this is ugly code”. So I’ve started work on a much better system:

  • The lowest level was already pretty good; the ECS knows how to save object IDs and call out to components to save their state. There are already some handy template functions to let me issue serialize(file, data), pick up the type and do the right thing. So that level is good.
  • Added in some mid-level functions such as serialize_vector, serialize_map and serialize_optionalthat do the grunt-work (save size – or existence for optionals -, and callback to handle saving of the data inside the container). That’s already been a big improvement in terms of readability.
  • Started adding in “canary” tokens to tell me where something went wrong.
  • Started moving logic into its own chunks; rather than a giant stream of serialize…serialize…serialize, it’s more like serialize_vector(file, vec, { serialize_building_order }). It’s reducing the cognitive load required to fix this massively.

I still wish C++ had better reflection options, but c’est la vie. I understand why it doesn’t, so I’m not mad about it!

A gnomish cook – sentient information window.

Light streaming through the windows.