It was a great finish to the year. The main gameplay loop is coming together, levels are more balanced, changes have gotten easier.
- Dungeon level-based equipment drops. Each dungeon level now contains equipment appropriate to the player’s power curve. Prior to this change, dropped equipment was random. A player on level one could find the best armor in the game, and a player on level twenty could find a copy of the short sword that they started with. Now the player will typically get equipment on the power curve, occasionally equipment one tier above or below the curve, and rarely equipment two tiers above the curve.
- Map element placement overhaul. Previously, map elements were added by calculating the number of elements to place based on the number of map nodes and then randomly selecting a node and an element for each iteration. This was quick to implement but it unevenly populated the map with elements. I changed this to iterating over each map node to guarantee that it received one and only one map element. Additionally, I moved enemy placement responsibility from the map generator to the map elements themselves because the available enemies varies based on the map element. I also added a way to control the relative frequency of map elements, so that some occur more or less often that others.
- Map element hierarchy. After creating many map elements it became evident that there’s a natural hierarchy – some elements define an entire map node while other elements perform a subordinate function such as decoration. I organized the folder structure and added inheritance into the classes. This also helped identify which map elements should be used directly by the map generator and which ones should be used by parent map elements.
- Most destructible objects are now destroyed with one hit. Walking into a room full of barrels and crates and having to hit each one a few times to destroy it was realistic but tedious. I made these and similar objects destructible in one hit. Some objects that are not routinely destroyed and should require some effort, such as wooden doors, still take multiple hits.
- Combat modifiers for standing on corpses. Standing on a corpse now causes a slight combat disadvantage, the thinking being that an actor can’t maneuver as well. More importantly, it adds another tactical option for combat.
- Enabled Unity’s Universal Render Pipeline. I honestly didn’t know about this (embarrassed to say that with two years of Unity experience under my belt now) and stumbled upon it while researching lighting in Unity. To use some of the lighting features, the URP was required. It wasn’t too difficult to enable. I had some issues with materials in a couple of third party assets. I’m still fuzzy on the URP but it seems like the right choice given that I have an aspirational goal of releasing on multiple platforms and the game is 2D. Ironically, I ended up using a lighting asset from the Unity Asset Store rather than the built-in lighting because the latter didn’t have all the functionality I needed.
- Added lighting, then removed it (temporarily). I set up basic lighting (darkened dungeon, player visibility, torch light) using Unity out-of-the-box lighting and it looked pretty good, but I ran into some limitations. I bought a Unity asset, Smart Lighting 2D, to get more functionality. I got it partially working, but I’m still learning how to use it. I had to put it on hold because I had some more important things to do this week. I’ll pick it back up in January.
- Fixed some bugs that had been hiding for a long time. I discovered a few bugs that causing problems I didn’t even know the game had! For example, one of the methods for fetching cells in a pattern was returning all of the cells in a map node rather than the room inside the map node. This explained the occasional mysterious placement of objects outside of a room. I also realized that enemy AI was executing some of the code for handling player clicks. This was ultimately benign, but still totally wrong so I corrected it.
- Increased the frequency of enemies and items for the standard room. Most rooms use a generic map element that sometimes adds enemies and items. Sometimes wasn’t enough; there were too many empty rooms, and maps often felt dull. Simply by increasing the frequency of enemies and random items, the game was funner to play.
Next week, I’m making some more minor tweaks to gameplay and map generation with the end goal of making level one challenging and fun.