Weekly Update – July 8, 2022

The two days I had off from work this week doubled my available dev time. Note those weren’t full days; they were just two extra 3-4 hour blocks of time similar to weekend work. A wide assortment of to-do’s got done, including minor tweaks and enhancements, bug fixes, refactoring, and some miscellaneous items. The general theme was getting the game to a stable, bug-free experience.

  • New Abilities
    • Turn Undead. Classic cleric ability that causes nearby undead to flee.
    • Heal. Heals the caster.
  • Self-Targeted Abilities. Abilities, such as Heal, can now be configured to target the user by default.
  • Entity collection-specific Abilities. Abilities can now target specific entity or entity collection types. This capability was used to implement the Turn Undead Ability (it’s basically the Fear status effect, limited to undead actors). 
  • Interesting bug fixes
    • Some enemies were fleeing from the player unexpectedly. Upon further inspection I determined that this only occurred when multiple enemies were present. Even stranger, when a new enemy spawned, an enemy that previously attacked the player started fleeing. It turned out that enemies were reacting to the movement events of other enemies. This shouldn’t happen because enemy AI contains an actor tracker component that limits the actors that the enemy will react to (typically, enemies only react to player actions). The actor tracker wasn’t being used by the enemy’s movement generator.
    • I wanted to display bones on some of the spikes so I configured the map generator to randomly add a bone pile actor on top of some of the spikes. When I tested this, ghosts appeared where bones should have been. I knew instantly what had happened. The bones are configured to spawn ghosts when they are destroyed. The spike damage destroyed the bones in the first game turn, causing the ghosts to appear. This was an easy fix. I changed the effect trigger for spikes from Touch, which is applied each turn, to DidEnterCell, which is only applied when an actor enters a new cell.
  • Other bug fixes
    • Tooltips remain on screen when the Inventory and Ability panels are closed.
    • Exception thrown when displaying the Abilities panel.
    • The default player action for Rugs and Summoning Circles was attack.
    • Cracked Eggs stopped hatching.
    • Eggs weren’t changing into Cracked Eggs.
    • Exception thrown when removing the Ring of Invisibility.
    • Heal Ability wasn’t working.
    • Closing the Select Cell prompt ended the player’s turn.
    • Poisonous gas, once spawned, would spread throughout the entire dungeon instead of a limited area.
    • Run Ability wasn’t working.
    • Exception thrown when Fires burned out.
  • Minor tweaks and enhancements
    • Eggs now have 1 HP so they are killed in one hit.
    • Destroyed eggs now  leave behind the corpse of the creature inside the egg.
    • Added descriptions for Cauldrons and Crystals.
    • Grass is no longer damaged by arrows or other piercing weapons.
    • Bones are now randomly added to some spike cells. 
    • When the game crashes before play starts, unusable saved game files are created. These are now automatically removed.
    • The default action type for an Open Door was changed from Close to Move. Having Open Doors close when clicked was annoying because 99% of the time the desired action is to move into the doorway rather than close the door. Closing a door can still be done through the Inspect Panel. 
  • Refactored / cleaned up several classes, including the Cell class, which had gotten up to 1,000 lines. There was a lot of code that didn’t belong in Cell – handling projectiles landing on the Cell and handling actors taking items in the Cell, for example. I pulled this code into new static handler classes. This is a poor long-term solution, but it’s an effective way of quickly extracting code that belongs elsewhere.
  • New automated tests: Ring of Invisibility. I haven’t added any new automated tests in a while. The Ring of Invisibility provides a good set of tests not just for the ring itself but for the Invisibility status effect as well. I intend to write automated tests for all Abilities.    
  • Improved ergonomics (for me). I’ve been having some pain in my right arm lately. I’m not an ergonomics expert, but after identifying the positions that caused my arm to hurt, I concluded that I needed to reduce the rotation of both my forearm and wrist. My mouse was too far off to the side, and I was holding it with a pronated grip (the normal mouse grip). I bought a smaller keyboard (the Logitech MX Keys Mini) to move my mouse closer to me. I bought a vertical mouse (the Logitech MX Vertical Advanced Ergonomic Mouse) to maintain a more natural, neutral grip when using my mouse. I’m very happy with the result. In the first week of use, the pain has mostly subsided.

Next week, and for the near future, stability and bug removal will remain the focus.

Weekly Update – July 1, 2022

It was another light week due to being on vacation for the first half of the week. More bugs were squashed and some new abilities were added. Abilities continue to require a surprising amount of work, including rework and expansion of the supporting systems.

  • New AI Type: Fear. This AI Type causes the actor to select a fleeing action each turn, even when cornered.
  • New Status Effect Type: Changed AI. This Status Effect temporarily changes the target actor’s AI Type. It’s used by the Fear spell to change the target’s AI from attacking to fleeing. When the effect ends, the target’s original AI is restored.
  • New Abilities: Fear and Mass Fear. The former causes Fear in a single target. The latter causes Fear on all actors in the area of effect.
  • Refactoring: Action consolidation. The recent rework on Actions, in which Actions were reduced to a series of Action Steps, made a number of Actions identical. For example, the Eating, Drinking, and Reading Actions consist of a single Action Step that causes the effect of the selected item. Since Actions are uniquely defined by their Action Step sequence, the number of Actions can be reduced to the number of unique Action Step sequences.
  • Bug fixes.

Next week will be more of the same, but I’ll have more time available. There are still many known issues to fix, and many more, I’m sure, that are still unknown. After a few weeks of mainly bug fixing my motivation is waning. It’s been fun creating and trying out new Abilities and I may spend more time on that next week than anything else.

Weekly Update – June 24, 2022

Time was limited this week and mostly went into bug fixing. I add a new map element and a new ability to keep content creation going.

  • New Map Element: Barrel of Water. This is a variation of a standard barrel that contains water. Destroying the barrel will create a puddle. It can be used to reduce the impact of explosions and put out fires.
  • New Ability: Run. The Run ability enables an actor to move across multiple cells in one turn. I’m thinking all or most player classes will get this ability.
  • Item type configuration validation. A few recent bugs were caused by improperly configured item types, for example a ranged weapon having a maximum range of 0. I added some checks to catch these issues when the items are initially loaded.
  • Bug fixes.

Next week, time will again be short and bug fixing will again be priority one. I will squeeze in one or two new abilities too.

Weekly Update – June 10, 2022

Implementing the Vampire’s AI was a lot of work. The process revealed the need for additional capabilities to support more varied and advanced AI. With the new AI framework, creating AI for new enemies in the future will be faster. The Egg, also added this week, is evidence of that.

  • New Enemies
    • Vampire. The Vampire is a dangerous enemy that has the special ability to transform into a bat and flee when its health is low. It returns to Vampire form after its health regenerates.
    • Egg. When the Egg detects the player nearby, it starts to hatch. The Egg can be destroyed in one hit if the player gets to it in time. But, if the player doesn’t get to it in time, a creature hatches from it.
Vampire
  • New Objects
    • Coffin. A Coffin can be opened or closed and can contain a Vampire and/or items, or be empty. 
    • Puddle. This is a single cell containing shallow water. It’s only found in caves. It’s just decorative at the moment. I plan to leverage the existing Physical Materials framework to add interactivity.
  • New Map Elements
    • Coffin Area. This map element places a single Coffin in a significant location in a room.
    • Egg Area. The Egg Area Map Element contains a cluster of Eggs.
  • Built new reusable capabilities. The above features required the implementation of new capabilities including a new action type to move an actor and trigger an effect at the same time (used when the Vampire flees to move away from the player and transform into a bat), a health regeneration status effect (used by the Vampire), the ability to prevent health bars from animating in specific situations (used when a Vampire transforms into a bat and health is transferred), generate particle effects when effect types are triggered (used to display a cloud of smoke when the Vampire transforms), and a new AI for actors that triggers an effect when the player is seen (used by the Egg to transform into a Cracked Egg), with an optional delay (used by the Cracked Egg to hatch after a number of turns).

`Next week will be a mix of new content and bug fixing. 

Weekly Update – May 20, 2022

This week’s focus was on expanding Action Steps and Abilities. A big chunk of time went into solving an issue with Action Step sequencing. An action’s Action Steps are instantiated and queued when the action is instantiated. A manager class then executes the Action Steps in order. This is a problem when an Action Step depends on the outcome of a previous Action Step, for example selecting a cell. I solved this problem by passing the action to each Action Step constructor and using the common properties in every action to pass values (every action has an actor performing the action and optionally, a target entity and entity that the action is performed with). It’s an imperfect solution but I needed to move on.

I also resumed the practice of adding at least one new Map Element each week.

  • New Ability: Charge. The Charge ability causes an actor to move up to several cells in a straight line and perform a melee attack within a single turn.
  • New Action Steps: Move and Melee Attack. These Action Steps enable an action to move an entity to another cell and perform a melee attack, respectively.
  • New Map Element: Spikes. Spikes simply cause damage when an actor walks on them. The player will have different ways of dealing with these, and they can also be useful in some situations, for example pushing an enemy onto them. They’re currently placed in a random row or column within a room. 
Spikes
  • Refactoring. Redundant parameters.

Next week’s goals are undecided. I’m due for a round of bug fixing; there are a number of known issues that I’m able to work around during playtesting but must be removed before release. I also need to keep the pixel artist search moving forward by posting in a couple more places and contacting the best artists from the original post.

Weekly Update – April 30, 2022

I got off to a great start last weekend, but the weekdays were consumed by my full-time job. I now have four weeks of time tracking data and will share a separate post on that in the coming week.

  • New ability: Fireball. This ability shoots a projectile at a nearby cell and creates fires in the 3×3 area around the cell. Much of the implementation effort involved supporting code rather than the ability itself. The Create Actor Effect was extended to allow actors to be created in multiple cells at once. I consolidated the Effect.Cause(Actor) and Effect.Cause(Item) into one method, Effect.Cause(Entity) (the Entity class was introduced as a parent of Actor and Item after writing the Effect code. I fixed existing bugs – items in cells weren’t being destroyed by fire, the select cell prompt was wrong, etc. All this work will make implementing other abilities that are projectile-based spells easy to implement. In most cases, this type of ability can be created exclusively in the Unity editor.
  • Refactoring: StandardMeleeAttackAction class. Melee-based abilities vary in terms of targeting, area of effect, sequence of events, animation, and stat modifiers. I’m still determining how to architect a solution that enables melee abilities to be easily created, modified, and maintained. The starting point is the StandardMeleeAttackAction class, which is responsible for executing standard melee actions. It actually does much more than it should, and the things it does are the building blocks for the melee-based abilities. I cleaned up this class and moved a lot of the logic into other classes for better reuse.
  • Pixel artist job ad. I’m at the point where I need to start getting original art in place. It’s going to take some time to find an artist (or artists), and much more time to create the new art assets. I wrote a job ad for a pixel artist and will post it in a few places next week..

Next week, I’ll finalize how melee abilities will be implemented and build out one or two melee abilities. I’ll also post the pixel art ad.

Weekly Update – March 18, 2022

The big news this week is that the Quick Switch Slots and Cell Action Indicators are done. I started on these exactly one month ago. They shouldn’t have taken this long to complete, but did because I had less time than usual over the past month and I underestimated the effort to code the features. They are two of the remaining three major UI features that need to be added (the third being Cell Context Menus).

  • Completed Quick Switch Slots. Quick Switch Slots are similar to a hotbar, but are used to quickly change weapons and other held equipment, and enable automatic switching of melee and ranged weapons based on the target’s distance from the player.
Quick Switch Slots
  • Completed Cell Action Indicators. Cell Action Indicators tell the player what will occur when a particular cell is left-clicked. An icon representing the action the player will perform is displayed when the cursor hovers over a cell. If the player first needs to move closer to the cell to perform the action, the Cell Action Indicator will display two icons, one for movement and another for the action to be performed.
Cell Action Indicators
  • Player input and action refactoring. The above UI changes touched one of the uglier parts of the code that is responsible for triggering in-game actions from player input. In the interest of finishing this game, I’m being more selective on rework. However, some rework was unavoidable this time. Previously, there were Player Actions (actions mapped directly to player input, which could translate to in-game actions such as moving the player’s character, or UI actions such as opening the Inventory Panel), Action Types (in-game actions), and Actions (instances of Action Types, but still defined as separate classes for each Action Type due to the evolution of the code). It was messy and redundant. I renamed Player Actions to User Commands, which helped me mentally differentiate these from in-game actions. I added a minimum and maximum range attribute to each action so that the Cell Action Indicators can determine whether the player’s character has to move in range of an entity before interacting with it, replacing some hard-coded logic that only worked in certain scenarios. I standardized User Commands and Actions behavior. I moved some methods into more appropriate classes. I fixed all the little issues that cropped up from the changes. I even found a couple of bugs that predated the recent changes.
  • Wand of Magic Missile. The Wand of Magic Missile was primarily created as a proof of concept for getting wands working, but will most likely stay in the game, and perhaps be a starter weapon for the Wizard class. I’m still deciding how to configure wands in terms of resource consumption. I’m leaning toward unlimited charges, no cooldowns, and eventual destruction from use. Wands will have to be underpowered to support this.
Wand of Magic Missile

Next week, I’ll start working on the final remaining UI feature: Cell Context Menus. Right-clicking a cell will display a Cell Context Menu that lists all of the possible actions that can be performed on the cell (left-clicking performs the default action, as indicated by the Cell Action Indicator).

Weekly Update – February 11, 2022

UI finalization, which started two weeks ago, continued this week. Some questions that have been open since day one, such as available equipment slots, are getting answered because they’re dependencies for completing the UI.

  • Decided on equipment slots. This is finally done. It was one of those things that I overthought. My original philosophy was to keep things simple and have a single armor slot, and some slots for accessories like rings. My thinking changed as the depth of the game expanded. The final equipment slots are Armor, Helm, Gloves, Boots, Necklace, Rings (2), and Shield (note that weapons are handled in a different manner, to be explained in a future post). Adding the new slots to the actor inventory was easy. I had to do a little bit of rework because of the rings. The original logic assumed that there’d only be one slot per equipment type.
Equipment slots and new items
  • Updated damage absorption and evasion calculations. With multiple pieces of equipment potentially affecting damage absorption and evasion, I had to update the combat calculations. This wasn’t difficult, but balancing got more complicated. I now have to consider mixed pieces of equipment, partial equipment, and class restrictions on each equipment type.
  • New items: Leather Gloves, Leather Boots, Leather Cap, Wooden Round Shield, Wand of Magic Missile, Necklace of Protection, Ring of Invisibility. These were created to test the new equipment slots. They may or may not make it into the final game. In particular, the Ring of Invisibility, which grants invisibility as long as it’s worn, is too overpowered.
  • New map elements: Mushrooms and Crystals. Caves are in need of more variety so I added glowing mushrooms and crystals.
Crystals
  • Indefinite status effects. Previously all status effects were temporary; after a certain number of turns the effect disappeared. Now, status effects can last indefinitely. This was needed for the Ring of Invisibility and will be needed for all equipment that gives the player a status effect while worn. 

Next week, I’m implementing the quick switch slots for weapons and light sources as part of the UI finalization.

Weekly Update – February 4, 2022

It was one of those weeks where most of the time went into thinking rather than doing. Hence, there weren’t many concrete achievements. The thinking was around UI design, specifically how to quickly switch between different weapons, how to automatically use ranged weapons for distant enemies and melee weapons for nearby enemies, how to handle torches, and equipment slots. I wrote out so many different solutions. None of them were perfect; they each had pros and cons. I think I’ve chosen a solution but need to consider how the solution applies to all the possible scenarios. The solution involves an additional hotbar that lets the player quickly change melee weapons, ranged weapons, and ranged weapon ammo, and logic for when the player clicks on a cell that determines whether to use a melee or ranged weapon. It seems sound to me, but only feedback from other players will confirm whether it is intuitive and user-friendly.

I added a few new map elements, which is something I’m trying to do every week to have a wide variety by launch. As always, there were some bug fixes too.

  • Witch’s Chamber. The Witch’s Chamber map element places a cauldron, a witch, and some bookcases and tables in a room. The witch is brewing something in her cauldron, which emits a blue glow. I need to give the witch some abilities. I’m not sure what I’ll do with the cauldron.
Witch’s chamber
  • Summoning Chamber. The Summoning Chamber map element places a summoning circle, demon, and summoner in a room. The summoner has just recently summoned a powerful demon in the summoning circle. I need to build out the demon’s abilities and the summoner’s AI (the summoner lets the demon do the fighting and avoids the player).
Summoning chamber

Also, here are a few examples of the objects added last week:

Pots and varied rubble
A rug
Grass and statues

Next week I’ll implement the UI features I spent this week designing and try them out in the game. This is the next item on the critical path. 

Weekly Update – January 28, 2022

It was a solid week with lots of smaller, but important, improvements and fixes. I added a few new map features and need to make sure that I do this every week, because map content variety is one of the key aims of the game.

  • Fibonacci weighted randomization. This is an extension of the existing weighted randomizer that adds the capability to automatically set weights based on fibonacci numbers. I created this because I kept needing a random number generator where each outcome was less common than the outcome before it, and the number of possible outcomes was variable. Fibonacci numbers naturally worked for this. I start at the second 1, so the outcome weights are 1, 2, 3, 5, 8, 13 and so on, and the weights are assigned in reverse order so that the most common outcome has the largest weight. I use this primarily for rarity-based random selection.
  • New sound effects. I added sounds for hitting webs, stalagmites, and bones and an ambient looping sound for braziers. The physical material-based sound effect configuration, in which the sound played is based on a combination of the weapon used and the physical material of the target, is becoming unwieldy. I will probably remove weapon-specific sound configuration and create a global configuration based on combination of weapon damage type (slashing, chopping, bludgeoning, piercing), weapon physical material, and target physical material.
  • New Map Elements. Added statues, grass, pots, and rugs.
  • Removed redundant Map Elements. Some common patterns emerged as I continued to create new Map Elements and it became evident that I could combine some of the elements. For example, there were dedicated elements to place a single actor such as a fountain or a shrine. The only difference between the elements was the actor. So, I removed these variations and created a single Actor Map Element that takes an actor type as a parameter.
  • Rubble tile variations. I got really tired of seeing the same rubble tile everywhere. I bought the Oryx 16-bit Sci-Fi sprite set primarily because it has two more rubble variations (that’s how much I like making my own art). The variation helps, but some of the rocks are too big. I’ll live with it because all the artwork is going to be replaced anyway.
  • Player corpse. When the player dies, there’s no visible indicator beyond the “Game Over” message. So, I made a corpse sprite (for the Knight; I still need to do the other player classes). As with the enemy corpse sprites I made, I used a simple process of rotating the sprite 90 or 180 degrees, slightly shearing it, and dropping the blood sprites above or below. The results are ugly but serviceable. Now when the player dies, a corpse will be displayed.
  • Animated Bones improvements. Animated Bones, which are piles of bones that come to life when the player approaches them, were improved. Now they animate when the player is diagonally adjacent to them and when the player attacks them from a distance with a ranged weapon. 
  • Equipment hotbar design. Over the past few weeks, I’ve been thinking a lot about how melee weapon switching and ranged weapons should work from a UI standpoint. This week I finally figured out how this should be designed. I still need to implement the design to validate it.
  • Added unit tests for select utility classes. I practiced some test-driven development this week, which is a rarity. I found some issues with the Fibonacci randomizer right out of the gate, so the new unit tests already paid for their effort. 
  • Bug fixes. Fixed ~10 issues that directly affected gameplay, which felt very satisfying.

Next week, I expect to mostly work on UI, specifically the melee and ranged weapon hotbars.