Alas, holidays are over, and now slowly getting back to reality, playing catchup with work, gamedev and post-holiday photo post-processing. Of course, I didn't manage to keep out of gamedev the entire time, and I ended up sneaking in some refactoring work on a few things that bothered me a lot. It's all about ...

Items

I had a bunch of classes for specifying item lists for various purposes, e.g. for chests, for starting equipment, other containers etc. Organic code growth had resulted in a few classes, doing similar work, duplicating some code and not even covering all use-cases that eventually surface. This is now changed. There is an ItemProvider class that can be specialised to provide items either explicitly (e.g. by Id), or using filters (e.g. pick a random item of type X), or using more complicated filters, based on context. This last bit is important.

Context is important when randomly choosing things in a game with loads of procgen. The simple example that I wanted "cold iron ore" to appear as treasure in cold iron mines. How to do that? I suppose there are multiple ways, so my descent into this solution space led me to using context. I can have a specialised item provider particular to ore. When using this provider to generate an ore chunk, we can use the context to identify where we are, which might inform what ore should we use. My current simple code does "if we're in a mine, choose the ore that corresponds to the mine". This provider can be put in a list of providers for generating contents for a crate in the mine.

Another cool (imo) result of this work was the ability to generate items tailored to players, in a classless system, like what I'm using. As a reminder, my system is skill-based: you choose which skills to master, and that defines what you can do, as skills give you passive bonuses and enable abilities. It's somewhat like a mix of latter Might & Magic games (the first person ones) and Elder Scrolls games. So, you finish a quest and get some treasure from the quest giver. Let's say that treasure is a magic piece of equipment. What equipment should it be? Here's when the rng fun begins: each skill has it's own rng-powered item provider, e.g. a dual-wielding skill would be associated with a provider that can generate weapons that can be dual-wielded. Or even a piece of jewelry that can give bonus to that skill. Given the player's skills, we can assign weights to each of these providers based on the skill value to pick a provider, then generate the item using that provider, given the situational context (which is mostly related to where we are). This is not put into practice yet, and some probable kinks into this plan are that some skills don't match well to items. But let's see.

Item containers

Another bit of complexity here. So, here's part of the conundrum. In a game like Diablo, when you break a barrel or a jug, the contents drop on the floor. There are no generic containers that we can put in and retrieve objects from, except the stash. Of course this is not simulationist, but gamey (these days you also automatically pick up things like gold, because "why would you not"). On the other side of the spectrum we have a game like Skyrim, which opts for the more simulationist approach of interacting with containers to add/remove items. I like both approaches for different reasons. The first approach makes associated gameplay "faster", there's no fussing with containers and the player is not allowed to add/remove items as it would encourage pointless behaviours. The second approach allows for more emergent gameplay, where you can do all sorts of weird things, and manipulating containers for some obscure reason is a part of the game's action vocabulary. Currently I support both approaches. A weapon/armor rack or a jug would use the first approach, whereas a crate, barrel or chest would use the second.

Now, we have a few general containers: crate, chest and barrel. How to assign contents? The current approach is to separate container and contents into different presets (containers are object presets, contents are lists of item providers) but also have presets of containers-with-contents... Confused yet? What's the rationale for this level of overengineering? I like contents being presets, because they can be assigned to different containers: "food" as a content preset could be assigned to a villager, a crate, a barrel, a sack, etc. Containers-with-contents are useful when used with the procedural placement system. I can create a preset of "ore crate", which is effectively a crate object with the ore contents preset. This can for example be assigned to procedural placement rules so that I can generate ore crates in a mine level.

Natural attacks

Through some previous refactoring effort, natural attacks were specified as ... items. Yes, I know, absolute horror. The reason are murky and from organic growth of the code over the years, but it was a clearly terrible state of things that needed changing. The end result is that now natural attacks are declared as "active" abilities, like a spell or other explicit actions that an actor can perform. As such, they have their own requirements (e.g. have nothing equipped if we're using a punch attack), cooldowns (e.g. some special natural attack) etc. Natural attack ammo is still classified as an item, but as a "transient" one, e.g. an acid spit blob.

That's all for now, see you next week!