2022 Year in Review

Legend is now entering its fourth year of development. It took the first two years to build the foundation. Systems were stood up, then overhauled once, twice, or even three times in some cases. In 2022, rework dropped significantly (evidence that systems were stabilizing and meeting design needs), enabling me to focus on refinement and content in preparation for a public release. The release didn’t happen due to the unplanned Map Generation 2.0 work, but the game is much, much closer to this goal.

UI/UX Improvements

With the focus on getting a playable version out to the public, UI/UX received a lot of attention. 

  • Quick equipment switching. Melee weapons, ranged weapons, ranged weapon ammo, and light sources can be quickly changed using slots next to the hotbar.
  • New inventory screen with separate equipment slots, stats, and inventory items.
  • Visual indicators for the cell the mouse is hovering over and the default action that will be performed by clicking on the cell.
  • Improved inspect panel now displays each tile and entity in the cell and actions that can be performed on those.  
  • Status effect icons shown for player and enemies.
  • Improved Select Class screen.
  • Stamina and magic bars.
  • Added a loading screen.
  • Changed the main font to Merriweather. Not sure if I’ll keep it, but it’s preferable to the low resolution, fixed-width font I was previously using because it’s more compact and looks less retro.
Updated UI
Loading screen
Status effect icons
Select Class screen

Visibility

Using the Smart Lighting 2d Unity asset, dynamic lighting, shadows, ambient lighting, and entity light sources were added. In addition to giving dungeons more ambience, the new lighting creates some interesting gameplay. Players should proceed with caution because who knows what could be lurking in the shadows… Lighting example.

One of the trickier features implemented this year was partial wall hiding. This was needed because walls between rooms occupy a single cell. The player shouldn’t be able to see the wall in the other room. Partial wall hiding solves this problem by only drawing the portion of a wall cell that is visible to the player. Partial wall hiding example.

New Content

The slowdown in systems development, and maturation of those systems, made it possible to create a lot of new content. Dozens of new enemies, items, and objects were added. Abilities were finally added to the game as well.

Examples:

Crystals | Torches | Vampire | Eggs | Resurrect Ability | Mass Fear Ability | Summon Giant Rat Swarm Ability | Destroy Undead Ability | Warding Glyph Ability | Kill Touch and Charm Animals Abilities

Map Generation 2.0

At the beginning of November I realized that my map generator was too limited to achieve the game’s vision and that it needed to be replaced. Map Generation 2.0 had four objectives:

  1. New structuring methodology – layout of walls and floors in rooms, corridors, caverns, and other shapes
  2. Sections – map partitioned into separate areas with discrete structures, themes, and content 
  3. Data-driven stocking – replace the existing hardcoded dungeon stocking with a data-driven implementation
  4. Node pattern-based stocking – identify the best locations on the map to place specific types of content using node patterns on the map graph

All four objectives were completed. Much of the code from original map generation was still usable, but had to be repackaged. Some code, such as the BSP code, was scrapped. The new generator is much cleaner and, most importantly, is capable of producing the kinds of maps I originally envisioned (with some more fine-tuning).

New multi-section map structure and map graph visualization improvements

Unity Assets

I acquired some fantastic Unity assets in 2022:

  • Odin Inspector and Serializer – I can’t recommend this asset enough; it’s a must-have for Unity developers. It can greatly increase your productivity when using the Unity inspector. It’s very easy to learn and start using.
  • History Inspector – super handy. It lists recently viewed assets and allows you to go to those assets with a single mouse click. I was spending a lot of time going back and forth between assets and finding assets before I got this.
  • All in 1 Sprite Shader – I used this to make grayscale and frozen versions of sprites. 
  • 3552 RPG Icons Pixel Art – using for ability icons. I doubt I’ll keep these in the final version because I want all the art to be custom.
  • Pro Sound Collection and Ultimate Sound FX Bundle – added to my stock sound effects collection.

I didn’t end up using:

  • Recently Used Assets – this wasn’t useful because it just tracked assets that changed. History Inspector (see above) is what I was actually looking for.
  • Behavior Designer – this seems like a great tool, but after I bought it I realized I was trying to solve the wrong problem. Legend’s AI meets present requirements, and doesn’t require the sophistication of behavior trees. But, if more complex AI is required in the future I will reconsider this asset.

Ergonomics

I replaced my keyboard with a Logitech MX Keys Mini keyboard and mouse with a Logitech MX Vertical mouse after experiencing pain in my forearms, wrists, and hands. I haven’t had any pain since!

Time Tracking

I wanted to understand how many hours I was working on Legend and what that time was spent doing. In April, I started tracking my time using Clockify.me. Since Clockify integrates with Trello, the tool I use to track my work, the overhead added by time tracking was negligible. 

In 2022, I spent 538 hours working on Legend, averaging 10.3 hours per week. 

Hours per week from April – December

Over half of this time was spent on enhancements (new features, feature improvements). 25% of my time went to testing and bug fixing. While I didn’t track time in prior years, I suspect the refactoring time was much higher in those years compare to the 8.7% in 2022 because I was doing a lot more rework.

Time spent by category

2023 Outlook

I’m confident that more people than me and my kids will play this game in 2023. There’s some work to do to get a public release out, and it will be far from finished (and will very likely still contain the Oryx stock art rather than original art). That work includes:

Improved Dungeon Stocking 

Dungeon stocking using Map Elements is currently done on a per-room basis. I want to add multi-room and multi-level Map Elements to provide more cohesion across levels and the dungeon as a whole. An example is placing a locked door and key in different map locations.

Improved Performance

Playing the game doesn’t feel great currently. It’s clunky and unresponsive at times, especially when there are multiple enemies on the screen. A big issue is the way turns are handled. Actor actions are animated sequentially, so the player has to wait for every other visible actor to move before moving again.

Content Creation

Much more content is needed, primarily objects, Map Elements, and map section types, to ensure that maps are varied enough. Some more enemies and items are needed too.

Balancing

Balancing improved in 2022 but still has a ways to go.

Once these tasks are completed, I’ll distribute the game to a small group of people who are interested in trying out Legend and providing feedback. After incorporating that feedback, I’ll create a Steam page and publish an early access version.

Thanks for reading and Happy New Year everyone!.

Weekly Update – December 2, 2022

Map generation version 2 continued to evolve this week, primarily through incorporation of features from the original map generator. These features include caverns, circular rooms, theme correction, and dungeon stocking.

Example maps:

Example map

    Generator in action:

    Map generation version 2 (work-in-progress)

    Looping didn’t make it in yet. I got hung up on partitioning the map into sections, which ties into how the looping will work.

    The above examples use the version 1 stocking logic, which randomly populates each room using a weighted randomizer based on room type rarity. The need for more intelligent dungeon stocking is what triggered creating a second version of the map generator. As with looping, sections are key. The plan is to partition the map into several sections and apply content based on the section type.

    Also, map graphs got some minor improvements – corridors have been de-emphasized by removing the node labels and making the nodes smaller. This makes it easier to understand the map structure. Here’s an example:

    Sample map graph with de-emphasized corridors

    Next week, I’ll figure out map sectioning and looping.

    Weekly Update – Nobember 18, 2022

    The algorithm for determining available space is fully working. I really struggled with it. I expected needing a few days to complete it but those days turned into weeks. The algorithm design itself was sound; it was the calculations that drove me nuts. Ample debug statements and code comments helped get the job done. Another useful technique for troubleshooting procedural generation issues is to temporarily increase simplicity, predictability, and repeatability. To debug the algorithm, I disabled the random starting point and instead set the starting point to 10, 10 and the initial feature size to 5×5, simplifying the math. By using fixed values, I knew what the expected values were (I didn’t have to calculate these in my head every time because the starting point and feature size changed each run). Using the same fixed values for every run made it easy to tweak the algorithm until the desired result was achieved.

    Here are a few examples employing the new available space algorithm. Note that these aren’t playable maps; they simply demonstrate the algorithm at work.

    Map generation example 1 (3×3 rooms)
    Map generation example 2 (random rooms and corridors)

    Other accomplishments this week:

    • Room and corridor fine-tuning. The ratio of rooms to corridors was adjusted, along with the sizes. In both cases, I compiled data from multiple hand-drawn dungeon maps and calculated min, max, median, and mean values. The median and mean values were similar when I removed extraordinarily large rooms from the data set.
    • Smarter corridors. Corridors now only connect to other corridors and rooms from specific points, based on the orientation and direction of the corridor. This helps corridors connect to other features in a more logical fashion.
    • Level graphs working again and improved. Level graphs required a few modifications to function with the new map partitioner. While I was in the code, I made some improvements. The new partitioner treats both rooms and corridors as graph nodes (previously only rooms were nodes), so I gave room and corridor nodes different shapes and sizes to better distinguish them.

    New automated tests. I rarely use test-driven development, but there were some situations this week where it made sense. The calculation-heavy utility methods for determining available space were easier to develop and test independently rather than when integrated into the full map generator.

    Next week I’ll continue refining the new dungeon layout. The goal of putting out a demo by year-end is almost certainly unattainable at this point due to the unplanned procedural generation work. But, I am taking a lot of time off in December and may be able to pull it off. 

    Weekly Update – September 30, 2022

    This week’s activities were all over the map.

    • New Abilities
      • Kill Touch and Charm Animals. Kill Touch instantly kills an adjacent target. I need to put some limits on this, such as resistance for stronger enemies. Charm Animals charms all animals in a 5×5 square
      • Warding Glyph. Places a glyph on the ground, visible only to the caster, that harms the first actor to walk on it.
      • Destroy Undead. Destroys all undead enemies in a 5×5 square.
      • Cure. Cures poison.
    Kill Touch and Charm Animals
    Warding Glyph
    Destroy Undead
    • New Item: Poison Arrow. Poison Arrows inflict poison on their target. 
    • New Map Element: Poisoned Fountain. The water in this fountain is poisoned, giving it a green hue. Drinking from the fountain causes a Poisoned status effect. The fountain will have additional future uses (when the functionality is built): pouring a Cure Poison potion into the fountain purifies the fountain, an empty vial can be dipped into the fountain to create a Poison Potion, and a weapon can be dipped into the fountain to give it a temporary Poison effect. 
    • New sound effects. Cauldron bubbling, fountain trickling, egg cracking and hatching
    • Particle effect for conjuration. It’s a slightly modified version of one of the particle effects from the Pixel Arsenal particle effects package.
    Summon particle effect
    • Enemies can open doors. Gone are the days in which the player could flee from enemies simply by passing through a doorway. Enemies can now open doors to continue their pursuit. Whether a particular enemy can open a door is governed by the actions it can perform. Some enemies, such as giant rats, are too unintelligent and/or physically incapable of opening doors.
    • Combat balancing. Several hours went into fine-tuning the damage formula and damage progression in a spreadsheet. My naive original damage formula was [Damage caused by the attacker] – [Damage reduced by the defender]. I liked the simplicity and intuitiveness of this calculation but it didn’t work in practice. I did a bit of research on damage formulas used in RPG’s (in hindsight, something I should have done before any spreadsheet work or coding, because designers have already figured this stuff out) and found some alternative formulas. A common formula is [Damage] = [Attack] * C / ([Defense] + C), where Attack is the damage caused by an attack before applying damage reduction, Defense is a  C is a Constant, usually 100, and Damage is the resulting damage after damage is applied.
    • Assumptions and constraints:
      • Max HP never changes.
      • Max HP only slightly varies between different classes.
      • Each class fits into one of the following armor categories: none, light, medium, heavy.
      • Each armor category has a target number of hits before dying (none:2, light:3, medium:7, heavy: 12). The damage formula and item stats are all designed around these numbers.
    • Tooltips for stats. Tooltips are now displayed when hovering over player stats.
    • New automated tests. Cell area utilities.
    • Fixed AI bugs.
      • Actors don’t track the player’s last seen location in some scenarios
      • Actors sometimes choose to respond to the wrong observation because observation weighting isn’t taking player regard (friendly or hostile) into consideration
      • Player allies sometimes follow the player instead of attacking enemies of the player
    • Fixed other bugs.
      • Inanimate objects, such as stairs, barrels, and doors, are subject to charming. It doesn’t make sense for entities without brains (and some with brains) to be charmed, so they’re now excluded. That said, this bug may inspire a future spell where inanimate objects are brought to life.
      • The Run ability allows the player to run past an enemy.
    • Changing levels and saving/loading working again. The reinstantiation of a previously visited level breaks more often than any other functionality in the game. So many changes break it. Most recently, adding theme-specific sprites for certain objects caused it to fail. 

    With the last quarter of 2022 starting this weekend, I’m putting together a plan to get the first playable version done by year-end. Next week’s goals will be determined by that plan.

    Weekly Update – August 12, 2022

    Adding a new ability to summon a swarm of giant rats nearly derailed my plans for this week (and potentially the next few months) when I tried out the ability and, to my surprise, the rats started attacking each other. I realized that there was no way of indicating that the rats were both allies of the player and each other; I needed to be able to specify relationships between actors. Factions were the first thing that came to my mind. They’re overkill for this single use case, but I’ve always intended to have factions in the game and reasoned that I could use them to solve the rat problem. As I’ve done with other aspects of the game design, I start with a flurry of research and brainstorming. I read up on factions in game design and roguelikes specifically, including a FAQ Friday on the topic, and wrote down all of the ideas and details I could think of. And, as I always do in this situation, I got lost in the subject and created a conceptual design that far exceeded what I likely needed and what I had time to build. That’s not a bad thing, as long as you can quickly pull yourself back into reality and reduce a grandiose design to something practical. I was able to do that in this case. My solution was to add an actor attribute indicating whether the actor is friendly, neutral, or hostile to the player. It’s a compromise, and there’s a good chance it will be thrown away in the future when I add a true faction system, but it’s the right solution right now, because it was extremely simple to implement and I don’t have a clear vision for how factions will work.

    Mass Fear spell
    • New Ability: Summon Giant Rat Swarm. Summons a swarm of giant rats to fight on the player’s behalf. 
    • New Item: Fire Sword. Sets enemies and objects it strikes on fire. It’s overpowered at the moment, but I haven’t decided how to nerf it.
    • Chests and corpse item access. The items contained in chests and corpses can now be viewed and taken from the Inspect Panel. A “Take All” button lets all items in the container be taken at once.
    • Inventory Panel is automatically displayed when inspecting a container. When viewing a container, such as a chest, the player inventory is now displayed automatically. This allows items to be dragged from the container into inventory and vice versa.
    • Weighted observation selection. One of the configurable AI components is the ObservationDecider. This component examines the actor’s observations since the last turn and chooses an observation to react to. There are two implementations of this component, one that selects the first observation involving a tracked actor, and another that randomly selects an observation (used by the Fear status effect). These implementations are primitive. They don’t work well when there’s more than one suitable observation to respond to. To address this, I modified the ObservationDeciders to weight each observation and select the highest weighted observation. 
    • New automated tests: Eggs. I’ve repeatedly broken the functionality of eggs, so this was a great automated test to add. The unique behavior of eggs (turning into a cracked egg upon detecting the player, waiting 10 turns to hatch, hatching a creature at the end of waiting) tests a number of systems.
    • Installed History Inspector from the Unity Asset store. My project asset list has gotten enormous. ScriptableObjects are used extensively, and many of these ScriptableObjects reference other ScriptableObjects. I often have to follow a trail of ScriptableObject references to fully understand how something is working, or go back to the previous asset I was viewing. The time spent scrolling through the asset tree, and the effect of navigating the structure on cognitive load, is impacting my productivity. I looked for a built-in Inspector history viewer in Unity but couldn’t find one. So, I turned to the Unity Asset Store and found the History Inspector asset. It’s already become an indispensable tool that’s saving me a lot of time.

    Next week, I’m play-testing combat and overall level difficulty. I’ll adjust and fix based on what I find. The overarching goal for the year remains getting to a version of the game that I can distribute to others.

    Weekly Update – August 5, 2022

    Testing the Resurrection spell
    Eggs
    • Resurrection ability particle effects. I mentioned last week that implementing Resurrection was simple. However, this week I hit a snag when I tried adding particle effects. The particle effects were triggered to start at the same time that the Resurrection effect itself started. This didn’t look right because the corpse would change to a living actor just as the particle effects were starting. I added a new Action Step for particle effects so that the particle effects could run in parallel with the Effect Action Step. Then I added a delay parameter to the Effect Action Step so that it could start half a second after the particle effects started. Now the actor appears to come back to life half-way through the particle effect emission and looks much better.
    • AI fixes. I fixed some problems that were rooted in my losing track of what the ActorTracker class is supposed to do. Actors are designed to only act when they need to, which is typically when they see another actor that they’re interested in. This is done for efficiency; the game would be too slow if every actor in the level acted on every turn.  The ActorTracker class was created to allow an actor to continue acting after it can no longer see any actors that it’s interested in, enabling the actor to pursue another actor temporarily. At some point, I started using this class to permanently track actors that an actor was interested in, and built logic on top of this new use case. When the player’s actor was instantiated, every enemy in the level added the player to its ActorTracker. That caused every enemy to check if it could see the player at the start of each turn. This is an expensive check when the player is in the enemy’s sight range, because line of sight is used to confirm that the enemy can see the player. Aside from the performance issues, the shift in how ActorTracker was used broke AI. And, ironically, pursuing actors that were no longer visible, which was the original purpose of ActorTracker, didn’t even work anymore. To solve these problems, I went to my best tools for walking through complicated flows: graph paper and a pen. I diagrammed the AI steps, located the logic flaws, and fixed them in the code. I scaled ActorTracker back to its original purpose and added comments to help me remember its scope in the future.
    • Chest and corpse user experience design. One of the oldest items on my todo list is getting chests fully working. This has been held up by incomplete design. Until this week, I hadn’t determined how the player would interact with chests, and how that would translate to the user interface. I’ve been putting off making that determination until I played some other roguelikes and CRPG’s to get a sense of how other games handled this. Downloading, installing, and playing multiple games until I found a chest seemed too time-consuming, so I resorted to watching a bunch of Youtube videos to find examples. The latter was much more efficient. 

    Next week, I’ll get chests fully working and fix bugs along the way.

    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 – April 8, 2022

    I’ve noticed that for at least several weeks, my todo list hasn’t gotten any shorter. I’m adding as many items to the list as I’m removing. The scope of the remaining UI work keeps growing, either because tasks are taking longer than expected or the features that have been added require additional features. It’s been time well spent, however; the UI is critical because one of my key goals is make the game as easy to learn and play as possible.

    • Added text to Action icons. UI best practice is generally to display labels with icons rather than icons alone. 
    Action icon labels
    • Inspect Panel improvements.
      • When inspecting a cell, the Inspect Panel now displays all inspectable objects in the cell, including actors, items, and the cell type itself. This allows the player to see details and perform actions on a specific inspectable in the cell (previously only the top inspectable was accessible). 
      • Actions that can be performed on the object being inspected but aren’t available for some reason (typically the player isn’t close enough to the object) are now displayed so that the player can see all potential actions.
    Inspect Panel improvements
    • Tooltips for empty hotbar, Quick Switch, and Quick Switch Deselect slots. Hovering over one of these slots now displays a tooltip indicating what the slot does and how to use it.
    • Code improvements/rework
      • Actions that can be performed on an item or actor are defined as lists that can be edited in the Unity editor. This worked well until I created a new action that applies to all items. Since most items have the same actions, I created a ScriptableObject called ActionCollection that contains a list of actions and replaced the entity action list with a list of ActionCollections. This allows changes to be made quickly to the core set of items, enemies, or other related entities, while still allowing for variation.
      • Actors in a cell are stored in a typed list. Likewise, items are stored in a separate typed list. This was implemented before I modified actors and items to inherit from the same parent, Entity. Having two separate lists caused some problems. One of those problems was that the order of an actor relative to an item couldn’t be determined. The logic that occurred when a player clicked on a cell checked actors first and items second. So, if a cell contained a table and there was a health potion on the table, clicking the cell caused the player to hit the table rather than take the potion. I solved this problem by combining the actor and item collections into a single entity collection. This was easy to do because the interface remained the same.
      • The recent rework made it possible to use a data-driven for some actions that were previously hard-coded. For example, each item now has a Take action, replacing logic that automatically performed a take action if an entity was an item.
    • Started tracking my time with Clockify.me. It integrates with Trello, the tool I use for planning and issue tracking. I’ve started tracking my time to become more aware of how much time I’m spending on the project and where the time is going (enhancements, bugs, etc.).
    • Thought more about a new name. I came up with one name that I like and a short list of decent names. This process is going to take a few weeks at least.

    Next week will likely consist of more UI refinements. 

    Weekly Update – March 26, 2022

    Cell Context Menus were the top priority this week, but most of my time went to implementing torches. I had a rough time getting lighting and extinguishing torches working. The implementation is probably overengineered; it provides more flexibility than I’ll likely ever need and, consequently, has a high complexity cost. It’s also on the messy side – multiple SOLID principles are violated. After writing the code, it took several hours to figure out why it wasn’t working because the sequence of events in the code was difficult to follow. I just got it working today, which held up my weekly update.

    • Item light sources. Items can now add light sources to actors. This capability was needed to support torches and other light source items. It will also be used to radiate light from certain magic items.
    • Torches. Torches now work properly. When the player selects a torch in the Light Quick Switch Slot, the torch will automatically light and illuminate the area around the player. Deselecting the torch will remove the illumination and extinguish the torch.
    Torches
    • Moved game buttons to the right of the hotbar. Originally the game buttons were in the lower right corner of the screen. I later relocated them to the right middle area. Now, they’re back at the bottom of the screen, but next to the hotbar. I did this to get them out of the way of the Inspect Panel’s new location.
    • Moved Quick Switch Slots to the left of the hotbar. These were originally on the left side of the screen, mirroring the game buttons. To maintain symmetry with the game buttons, and consolidate buttons and slots, the Quick Switch Slots were moved to the left of the hotbar.
    • Quick Switch Bar improvements. The currently selected item was being shown twice, once in the Quick Switch Slot, and once in the Quick Switch Bar. This was confusing and redundant. Now the selected item is excluded from the Quick Switch Bar.
    • World building. Although the dungeon is procedurally generated each game, the world in which the dungeon exists is fixed. Each generated dungeon will reference some world events, historical figures, peoples, places, deities, etc. Gradually, the player will learn more about the world, which will make the  references more meaningful and factor into gameplay. This week, I started fleshing out this world.

    Cell Context Menus didn’t get enough attention to warrant a bullet in the above list. However, this feature technically already exists. The Inspect Panel, which is displayed when the player right-clicks on a cell, provides a description of the cell contents and buttons for actions that can be performed. The buttons correspond to the items that would appear in the Cell Context Menu. Next week, I’m going to move the Inspect Panel from the center of the screen to the right side and add icons that match the Cell Action Indicator icons. I’ll also continue to work on the next major milestone, visibility.

    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).