Prefabs and refactoring

Prefab in game: the liquid room
Prefab in editor: specify 4 connections (only 2 managed to be created)

So, the prefab loading work ended up being slower than projected, for a few reasons, one of them is IRL work and things, but the other important factor is just Bad Code that needs to be refactored:

  • I was trying to serialize 2D arrays of layout info in a variety of ways at the same time, and it backfired. 2D Arrays are stored by the game in some optimized form, but I can’t easily create that from from python (where the prefab editor is implemented in). So, eventually I had to create different classes and map from one to the other
  • The super-flexible json level specification is a double-edge sword, as it’s difficult to generate the json from the C# game state, especially if we start including prefabs etc. This is one of the reasons why I’m showing the same dungeons over and over; I’m choosing between a select few configurations . So now I’m slowly fixing that aspect, but I’ll possibly need some long uninterrupted hours to do that, which might be hard to come by.

Nevertheless, I did a few steps towards that direction, so it’s possible to put the prefab as a zone in a dungeon easily, but the dungeon configuration is a bit hard-coded. What’s missing is also the ability to use the prefab as a room type in a rooms-and-corridors generator. I suspect that part will be ready next week, barring any surprise IRL work.

Graves and prefab generator

New interactive level object: grave. Interact with it and get treasure, monsters, or both!

Another week, another step towards prefab dungeon areas. So, 2 main points:

  • Expanding on last week and flexing the underlying systems, I’ve added a new interactive level object, the grave, where if you interact with it, you might get a treasure (automatically transferred to the inventory), and you might also get an undead enemy spawned next to you
  • For creating prefabs, I thought I’d use the Tiled tool to begin with. So, I made a template, loaded some sprites, but the main issue was that the sprite-based nature of the tool made it complicated to integrate any other entities that carry some sort of meaning/functionality, such as the grave or the bookshelf from last week. So that effort went to the bin after a few hours. So, I went back to my default go-to solution for quick-and-dirty GUI: tkinter for python. So, I made a simple tool to be able to create prefabs with 5 layers: floor, blocked, decals, liquid and objects. For objects, since I control the code, I can automatically look up any level object entity configurations (that typically declare sprites) and use those, as seen in the screenshot. What’s also possible is to make up some placeholder entity configurations/sprites with special meaning, e.g. “use whatever could be reasonably generated here based on default dungeon configuration”. But it’s a bit theoretical at the moment, as I’m now structuring the export data and preparing them for use with the game and DLL plugin.
Prefab generator GUI, courtesy of tkinter

Item-spawning dungeon features

Testing bookshelves, aka “The Library Dungeon”

Some backend work this week, to support item generator effects in level objects. An example is a bookshelf. Bookshelves are interactive objects that may or may not contain a scroll or a tome. Initially will appear full of books, but will become empty when searched. If an item is found, it’s automatically transferred to the inventory.

An additional fine point for bookshelves is that they are generated as a single feature in the native plugin that does the dungeon generation and placement work, whereas the C# side generates a cluster of bookshelves centered around the calculated feature position. So, some extra work to make things passable, etc. This is useful as we can do several nifty things if the native plugin generator works in terms of features, and the C# side can instantiate each feature into multiple similar entities. Another example would be a boss enemy with a number of minions, but that will come later on.

Another requirement for this work is to specify some sort of 2-dimensional enum for item types and subtypes, so we can tell the item generator system that we want a “tome” or a “scroll” object that has less-equal item level than some specified.

Another random fix was the AI of ranged attackers, where they would not take into account that obstacles might be in the way of the fired arrow. Well, now they do, and move into a position that provides a clearer shot.

I’ve also started having a look at the prefab support in the dungeon generation, written last summer, as I have to write some tool to generate prefabs to use with generators.

Diagonal movement & thrown bombs

Throwing a delayed-blast bomb, and moving it with Telekinesis before it explodes

More miscellaneous work this week, under the general guise of “emergent gameplay”

  • Adjusted how diagonal movement blocking works, for QoL reasons. Before, if you wanted to move diagonally, both tangent direction had to be unblocked. So that, when moving, you never see the player going over any obstacle. I really, really disliked how that worked in practice, as 8-directional movement stops being fluid. Now, diagonal movement is only blocked when both tangent directions are blocked. This works far, far better and the movement is now very smooth again, without surprise-blocks that don’t seem to make sense.
  • Added support for thrown bombs (well, general category of thrown things that have a particular effect on landing). So that there are more AoE options for non-spellcasters, for example some elemental AoE for fighters, or some smoke clouds for stealth users, etc. I also added support for delayed-blast effects, so that you can have situations where you throw a delayed blast bomb, then it gets moved somehow (e.g. via trap, kick or a kinetic spell), and then it explodes. Russian roulette gameplay could then be to start throwing delayed blast bombs on teleport traps 😀
  • Realised the importance of a GUI for split and merge stacks, wrote some basic placeholder GUI for it, but also realised that I could not fit that somewhere reasonable based on the existing item GUI that I have… To elaborate: the current item GUI logic, which I was proud of, is to always have a pair of containers (player & ground, or player & chest, or player & other container), and you multi-select things in one container, multi-select things in the other container, and do a transfer. To help things, I also had some toggles for all/none selection per container. That’s all great, until we need to split a stack, as that just can’t happen with the multi-select which is binary in nature. So, back to drawing board for how the GUI will work for inventory transfers.
  • Added some initial support for destructible objects and durability. Again, this feature creep is essential, as breaking things is an integral part of roguelike life, as the remains of broken barrels, jars and doors from various games would all attest to. This can creep further into weapon durability, but I’m not going down that route, yet, although the deceptive simplicity of integrating that is tempting.