• Weekly Update – May 17, 2024

    Bugs continue to emerge in the wake of the recent UI, audio, and observation system changes. They made this week a grind. On a positive note, the new sound propagation feature is working well and has improved gameplay and immersion. Sound effects only play if the player can hear them, and play at a volume based on the distance of the source and dampening objects in between. Enemies often hear the player coming before seeing the player and react sooner. I can easily implement stealth mechanics now simply by lowering the player’s footstep volume when in stealth mode. 

    The demo MVP status is as follows:

    • Play Test 3: 100%
    • Performance optimization: 100%
    • Minimap: 100%
    • Major UI/UX issues fixed: 90%
    • Major bugs fixed: 50%
    • Missing liquid content: 50%
    • Missing sound effects added: 50%
    • Balancing: 40%

    Next week, with the sound manager completed, I will have time to add the remaining missing sound effects.

  • Weekly Update – May 10, 2024

    Adding sound effects has become the vehicle for demo scope creep. It started with adding an audio manager and continued this week with sound propagation. The latter involved major rework of the observation system. 

    • Sound propagation. Sounds now propagate through the dungeon level based on their initial loudness and nearby obstacles. Actors within hearing range can react to the sound through the observation system. Sounds only play if the player can hear them, and the sound volume is adjusted according to the volume when the sound reaches the player. 
    • Improved observation system. The observation system generates observations from game events and determines which actors receive those observations. Actors use observations to determine their actions. The message log uses observations to log messages. Previously, observations indicated the game event, e.g. “Door Opened”. There was an assumption that all observations were perceived visually. To support observations from sounds, I added a Sense attribute (sight, hearing, etc.) to observation types and created separate observation types for seen and heard game event types. As a result of the rework, game events and observations are cleaner and more flexible. Instead of generating observations directly, the code now generates a game event, and the observation system gets the observation types for game event type from data.   
    • Fixed many, many bugs originating from last week’s UI improvements. This activity consumed half of this week’s time.

    Next week, I’ll tie up the loose ends in the observation system rework and add more sound effects.

  • Weekly Update – May 3, 2024

    It was a productive week despite my normal time slots (early morning, between end of work and dinner, and long weekend mornings) being disrupted by work travel and family visiting over the weekend.

    UI Improvements

    • Terrain combat modifiers displayed when hovering over a cell. This helps the player determine which cells have combat advantages and disadvantages.
    Terrain combat modifiers
    • Text Alert Panel. This is a UI panel for important text alerts, such as an item breaking. The panel disappears on its own after a specified number of seconds.
    Alerts
    • Out of range actions appear in Context Menu. The Melee Attack action, for instance, will appear even if the player is too far away to perform the attack. Selecting this action will move the player to within the range of the melee attack and then perform the attack.
    • Particle effect in item slot when the item in the slot breaks. 
    • When performing an action requires moving closer to the action target, the movement icon is no longer displayed. I originally believed that explicitly indicating actions preceded by movement was beneficial. In practice, it was unnecessary.
    • The Move action no longer appears when hovering over a cell that the player can’t move to. Previously, the player could click on a wall, and the pathfinding algorithm would route the player to the available cell that was closest to the wall. It was more intuitive to prohibit the player from clicking on an unavailable cell than it was to enable the player to click anywhere and pathfind as close as possible to that location.

    Bug Fixes

    • Quick switch slot doesn’t clear when item in slot breaks.
    • Right mouse clicks pass through the Inventory Panel to the map.
    • Error when the Character Panel is opened when the player has no melee weapon equipped.

    The demo MVP status is as follows:

    • Play Test 3: 100%
    • Performance optimization: 100%
    • Minimap: 100%
    • Major UI/UX issues fixed: 85%
    • Missing liquid content: 50%
    • Missing sound effects added: 50%
    • Major bugs fixed: 45%
    • Balancing: 40%

    The demo backlog is dominated by audio-related tasks at this point. I’ll work on these tasks next week.

  • Weekly Update – April 26, 2024

    There was some scope creep on the demo MVP this week. I hadn’t planned on adding new enemies or rooms for the demo, but I encountered too much repetition during playtesting. I also hadn’t planned on adding an audio manager. But, to get the missing sounds into the demo and fix the issues with the existing sounds (both of these objectives were in scope), the audio manager was necessary.

    • New content
      • New enemy: Snake. It has a 50/50 chance of causing Poison and is best fought at a distance.
      • New rooms: Snake Den, Rat Nest, Crates, Shrine of Carnath.
      • New sound effects: UI Panel Open/Close, Game Over.
    Shrine of Carnath
    Snake Den
    • Miscellaneous enhancements
      • Some Crates contain Snakes.
      • Skeletons have a chance of carrying random items.
      • Bats and Spiders no longer appear as random enemies (they’re too weak to be challenging individually).
      • Starting weapons take longer to break than they previously did.
    • New audio manager. I previously used Unity’s built-in audio along with a utility class I wrote to play and spatialize audio. This setup had known limitations and bugs – certain actions couldn’t be synched with sounds, some sounds were cut off before they finished playing, concurrent sounds sounded horrible. When I started this project, as both a Unity and game audio novice, I didn’t know how to best handle audio. I have a better sense now of what works, what doesn’t, and what’s needed. A new audio manager technically isn’t in the demo scope, but it will resolve a number of bugs that are in scope. I considered writing my own audio manager and using a commercial solution. I chose the latter, specifically FMOD. FMOD is widely used in the game industry and provides a strong audio framework, which helps compensate for my inexperience in this area. To use FMOD, I had to create a new project in FMOD Studio, import all existing audio assets, and swap all uses of Unity audio with the FMOD equivalent. The last step was the most work; there were hundreds of ScriptableObjects with AudioClip fields. The AudioClip fields were changed to AudioResource fields. AudioResource is a custom class that contains an FMOD Event Reference. This approach decouples the audio implementation; if I later move away from FMOD I can do so without having to update all of the ScriptableObjects again. Unfortunately, I didn’t have the forethought to do this originally, and had to individually update the hundreds of audio fields to the correct AudioResource using the Unity Inspector. Once that was complete, I tested the migration. There were a few simple bugs to fix, and I missed setting some of the AudioResources in the first pass. All things considered, moving to FMOD was easy.

    The demo MVP status is as follows:

    • Play Test 3: 100%
    • Performance optimization: 100%
    • Minimap: 100%
    • Major UI/UX issues fixed: 65%
    • Missing liquid content: 50%
    • Missing sound effects added: 50%
    • Balancing: 40%
    • Major bugs fixed: 35%

    Next week, I’ll add more sound effects and add missing actions to the context menu.

  • Weekly Update – April 19, 2024

    I only had five hours this week because I was visiting family.

    • Enemy equipment is now shown in the Inspect Panel. The Inspect Panel used to only show inventory items, not equipped items. This was an issue when inspecting the corpses of slain enemies that wore equipment. Extending the Inspect Panel to also show equipment in the inventory slots involved a surprising amount of rework. The quick fix was to make actors unequip their worn items upon dying. However, this wasn’t logical and it caused a new problem: it disabled actor light sources because torches are automatically extinguished when unequipped (you wouldn’t want to put a lit torch in your backpack). This new problem brought back the bug mentioned last week. I evaluated various workarounds to my original workaround but ultimately chose to implement the proper solution – displaying equipment in the Inspect Panel. I had to completely change the panel’s layout to display the equipment slots. I also had to add conditional logic to resize the panel based on the elements displayed (some actors have equipment and inventory, some actors have inventory only, and some actors have neither equipment nor inventory). It sure was a lot of work just to keep torches lit when an actor died. I may further leverage this feature in the future for new game mechanics such as stealing an equipped ring or slipping a cursed ring onto an enemy’s finger.
    • Message displayed when the player tries to take an item with a full inventory. I’d like to also add a visual cue when this occurs, but it’s not part of the demo MVP.
    • Increased frequency of Health, Stamina, and Magic Potions. The supply of these potions didn’t match the player’s need for them.

    The demo MVP status is as follows:

    • Play Test 3: 100%
    • Performance optimization: 100%
    • Minimap: 100%
    • Major UI/UX issues fixed: 65%
    • Missing liquid content: 50%
    • Balancing: 40%
    • Missing sound effects added: 40%
    • Major bugs fixed: 35%

    Next week, I’m focusing on sound management and adding more sound effects. I’m considering using fmod.