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 30, 2022

At the close of 2022, three of the four Map Generation 2.0 objectives have been completed:

  1. Structuring – layout of walls and floors in rooms, corridors, caverns, and other shapes (done)
  2. Sections – map partitioned into separate areas with discrete structures, themes, and content (done)
  3. Data-driven stocking – replace the existing hardcoded dungeon stocking with a data-driven implementation (done)
  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 (in progress)

There’s also an aspirational fifth objective, which is to use generated background stories for each map to select, place, and customize content.

I’ve been working on map generation exclusively for the past two months. It’s been fun and challenging but I’m starting to feel burned out on it. I need to complete objective 4 and switch over to something else.

Accomplishments this week:

  • New Room Type Map Elements: Barracks, Bedchamber, Bone Pile, Corpse
  • New Objects: Beds (Plain, Dirty, Fancy), Prison Door, Blood Fountain
  • Data-driven Map Elements. Map Elements, the procedural generation objects used to stock the dungeon, are now data-driven. Previously, a class was created for each Map Element. For the most part, Map Elements define what objects go in a room, and where those objects are placed. So, a separate class was needed for each room type. Now, new room types can be created from the Unity Inspector. With this new capability, I was able to quickly recreate the class-based Map Elements and add some new ones. Odin has been an incredible tool for this.
  • Expanded object placement capabilities. Objects can now be placed in grids with random element sizes and rows and columns. Objects can now also be placed in clusters, which is useful for objects that typically appear next to each other such as barrels. Parameters have been added to some existing placement patterns for more flexibility. For example, corners can now be offset relative to the edge or the center of the room. Placed objects can now be grouped, with conditions for placing groups (such as minimum room size). Groups can be configured to place all of the objects they contain or a single, randomly selected object. These improvements provide many more ways to populate rooms in the dungeon.
  • Section-based structure. Map sections can now have distinct structures. For example, catacombs sections have longer corridors and smaller rooms.   
  • Map generation performance improvement. The recent additions and changes to map generation really slowed it down. A quick and impactful fix was adding some caching. There’s more work to be done here, but the current performance is tolerable again.

Next week, I’ll start on the node pattern-based dungeon stocking. I believe the design work is done; I’ve cataloged many patterns using the graphs generated during testing. Some pattern recognition already exists, as it was implemented before I had the big picture. For instance, sequences of rooms and required rooms are identified during generation.

Weekly Update – December 17, 2022

  • Map generation refinements. Map sections now connect to each other (most of the time; smarter connecting corridors are still needed). The starting section locations are better spread out across the map. This helps balance the section sizes, but doesn’t eliminate a frequent issue I’m seeing in which a particular section grows disproportionately and blocks other sections from growing. The solution I’m considering is to check the size of each section as the map is being generated and dynamically adjust the growth of sections that are too large or small relative to the other sections.
  • Catacombs and Crypt themes. Map sections can now be themed as catacombs or crypts, in addition to the existing bastion and cavern themes. It’s just a tile swap at the moment, but future updates will alter structure and content.
  • Refactoring. Some enums have been converted to classes that inherit from ScriptableObject so that they can be referenced in the Unity inspector. MapElements, which are responsible for stocking the dungeon, are also in the process of being converted to ScriptableObjects. This will accelerate creating new MapElements, which will soon be needed because the upcoming section-based stocking requires a wide variety of room types.
  • Started using Odin Inspector. On multiple occasions I’ve run into the limitations of the out-of-the-box functionality of the Unity inspector. While it is possible to customize the inspector, a relatively high level of effort is required to do so (coding). I originally heard about Odin from a Jason Weimann video. In the video, Jason said that if you can only get one Unity asset, make it Odin. That set my expectations pretty high, but so far Odin is living up to those expectations. It’s extremely easy to use and is very well documented. In a nutshell, I’m using it to make the Unity inspector more useful, refining the controls and presentation.

I’m on vacation for the rest of December and looking forward to making huge progress with all that time. Map generation refinement will be the main focus. If time allows I will also tackle speeding up game turns by enabling all actors to move at the same time.

Weekly Update – October 14, 2022

Play-testing at the beginning of the week produced a long list of improvements and bugs to work through. There is no better method for prioritizing work than playing your game (or better yet having others play it too).

  • Finalized the Death Screen. Consisting of a text message and “Try Again” button, the death screen is basic, but will suffice for the demo release. It looks simple but took some effort to hide and disable things – stat meters, status icons, enemy health bars, hotbar, player input.
Death screen
  • Finalized the Won Game Screen. 
  • Separated actions that entities can perform and actions that can be performed on entities. A few times throughout Legend’s development I’ve unintentionally used an object for multiple purposes. This was the case with the entity ActionTypes collection. Originally this object was used to store the types of actions that can be performed on an entity, e.g. the Drink action for a Fountain, the Open action for a Door. Later, I started using it to also store the actions that an Actor could perform. I’m not sure what I was thinking at the time, but I clearly wasn’t thinking enough, especially considering how simple the solution was – two separate collections.
  • New Map Elements
    • Portal. The Portal appears on the last level. When players step into the portal, they exit the dungeon and win the game.
    • Debris Pile. This replaces the Grass Map Element, which didn’t fit into the dungeon setting. The Debris Pile blocks movement and sight and is destroyed in one hit.
  • Minor improvements
    • Turns remaining added to status effect tooltip.
    • Magic bar is hidden for player classes that don’t use magic.
    • When an actor is healed, the floating text showing the number of HP is now green instead of red.
  • Bug fixes
    • The Inspect Panel doesn’t work. Recent changes broke it.
    • Torch light doesn’t appear when the game starts. When I removed all the starting items from all player classes (many of which were added for testing purposes) and re-added them, I forgot to give each class a torch.
    • Torch light doesn’t disappear when a torch is unequipped. I discovered that the torch game object was being added to the player twice. The torch was being added twice because two different events added torches. Two different events exist because one event is triggered by equipping a torch (needed on level 1, when starting items are automatically equipped) and the other is triggered by setting the quick switch slot (needed on level 2 and after because the torch light has to be re-instantiated and the equip event will not fire because the torch is already equipped). I modified the second event to check for the existence of a torch light game object before instantiating a new one.
    • Inspecting cells with multiple entities of the same type doesn’t work.
    • Finite status effects have one extra turn. I had no idea this was happening; adding the turns remaining to status effect tooltips exposed this.
    • Flames show damage floating text when they burn out.
    • Player is able to open doors that aren’t adjacent.

Next week will look similar to this week. AI isn’t being properly saved/restored across levels or saved games. This will be a pain to fix but is necessary. There’s some interesting map generation work to do too, though I’ll need to be careful to avoid getting carried away with it.

Weekly Update – October 7, 2022

Between unexpected issues at work and a lot of thinking and spreadsheeting rather than coding, it didn’t feel like I got much done this week. My brain is getting fried working out how various numbers will change over the course of a run – HP, damage, damage reduction, stat ratios between no/light/medium/heavy armor, net stats from different equipment combinations (this has especially been a headache; I’m tempted to have a single equipment slot for armor rather than body/head/hands/feet), early vs. late game ratios (to control difficulty), etc. It’s been challenging figuring out where to start because there are so many relationships between stats. My starting point is determining what should be the typical number of hits to kill the player according to their armor category and working backwards from these numbers to determine the stat values. It’s also been helpful to write out different combat scenarios like “how many hits should it take a bandit with a short sword to kill a player wearing light armor.” The model is coming together, but there are still many numbers to plug in. After the model is finished, I’ll create a simple simulator to efficiently test it, and do play testing. 

Aside from all the fun with spreadsheets, I completed a couple of items on the 2022 goal list: finalizing the Select Class Screen and Passive Abilities.  

  • Updated Select Class Screen. Locked classes are now shown as a silhouette of the sprite, with a lock icon (I’d prefer a padlock but grabbed the closest thing I had, which was from the Oryx sprites). Class attributes are now shown in a grid view with the attribute names.
Updated Select Class screen
  • Passive Abilities. Passive Abilities were previously 25% completed. They could be assigned to classes in the designer, but didn’t appear on the Abilities Panel, didn’t have sprites, and didn’t have any effect in the game. These items have now been implemented. Passive Abilities are currently only used to dictate the weapons and armor that a class can use. Passive Abilities that provide other types of benefits will be added in the future.
Passive Abilities
  • Finalized the starting classes. Three classes will be unlocked when the game is installed: Knight, Ranger, and Wizard. Just this week I replaced the Rogue with the Ranger. I wanted the starting classes to be the most straightforward classes to play, representing the core combat styles of melee, ranged, and magic. Additionally, the Rogue’s abilities, and map features to use those abilities, won’t be ready by year-end.
  • Common Ability Group. I decided that all classes should have the Run ability. I added a new ability group called “Common” to contain abilities that are available to all classes. I don’t have any other abilities in mind currently that fit into this category, but I expect there will be some in the future. 
  • Q4 plan. I set goals for the remaining weeks of the year. I don’t usually get this granular with planning, but it is necessary to keep me on track and reach my goal of a playable version by the end of 2022. I’ve set goals by month as well, which are:
    • October: remaining functionality
    • November: remaining content
    • December. testing and polish

Next week, I must finish the initial progression/balancing model. I also plan to finalize the item, ability, and enemy list for the demo release. I’ll also review all of the systems and identify the major improvements/fixes that are needed for the demo release.

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 – September 2, 2022

In last week’s update, I stated that sound effects would be the focus this week. I didn’t touch that. Instead, I wound up spending the entire week on visual improvements.

New ability icons and stat meters
  • Replaced ability icons. I was using effects and item sprites from the Oryx 16-Bit Fantasy sprite set as temporary ability icons. The images were loosely applicable at best, and too abstract to infer their purpose. They were plain and in some cases downright ugly. I didn’t want to see them anymore so I bought a giant RPG icon set from the Unity asset store to replace them. The visual style didn’t quite match the rest of the game, but that’s ok; I still plan on replacing them with original artwork eventually. I wasn’t able to use them “out of the box.” They were 32×32 pixels in size, while item/ability slots were 16×16. My solution was a compromise: I’d crop the icons to 24×24 and increase slot sizes from 16×16 to 24×24. I spent more time on this than I expected. It took a while to find the right icon for an ability, and additional time to find the right 24×24 section within the original to crop. It also required resizing slots everywhere they were used (inventory panel, ability panel, inspect panel, hotbar, quick switch slots). Since the slots use a common prefab, I only had to change the prefab rather than each individual slot, but then I needed to change panel sizes and move some UI elements around to accommodate the larger slot sizes.
  • Increased the hotbar size. This was necessitated by replacing the ability icons. I’m not thrilled about giving up more screen real estate for the hotbar, but I don’t have an alternative because I believe 24×24 is the minimum resolution for an image to portray an ability.
  • Replaced the font. The original font was an 8×8 monospaced font commonly found in early arcade and console games. The main issue with this font was space. It was difficult to read at a small size. I could have increased the resolution for text, but it wouldn’t have looked right to have pixelation at two different resolutions (one for images and one for text). Also, my aesthetic preferences have changed since then. It can be a long road to finding the right font. 80% of my time this week went into searching massive font databases and curated lists, studying screenshots from other games, and trying different fonts out in the game. I could have easily spent the entire week, and many future weeks, on this pursuit. I have a persistent problem with wanting to start with the largest space possible, explore every possibility, and narrow down to the absolute best choice. With something like fonts, there just isn’t a best choice; it’s too subjective. I decided on Merriweather because it’s a serif style but is designed specifically for screen use.
  • New status effect: Charmed. Causes an actor to fight for the caster.
  • New abilities
    • Charm. Temporarily charms an individual actor.
    • Mass Charm. Temporarily charms all actors in a 5×5 square.
  • Improved stat meter visuals. I wanted to make these look a little less plain.
  • Minor improvements
    • On the Title Screen, the Continue button now appears above the New Game button, since the former will be used more often than the latter.
    • Select cell prompt repositioned so that it doesn’t appear over the player or other UI elements.
    • Increased the number of recent log messages displayed from 4 to 8.
    • Reduced the size of tooltips.

Next week, I plan on adding a loading screen (the presently inefficient proc gen freezes the game for ~10 seconds per level), enemy status effect icons, and sound effects time if time permits. 

Weekly Update – August 26, 2022

After literally years of research, brainstorming, analysis, and procrastination, the types of resources consumed by abilities have been determined. This decision has been drawn out by many dependent questions regarding Legend’s underlying resource management design: are resources finite or infinite? Is there a hunger clock? Do health, magic, etc. regenerate? Not all of the questions have been answered. I aspired to find the perfect solution, but the model is too complex to assemble, and I no longer believe a perfect solution exists anyway. I increasingly aim for solutions that are good enough, solutions that don’t offer complete flexibility, but are flexible enough. I embrace the resulting constraints, for they shrink the answer space, and foster creativity. And thus, at the end of the ability resource design journey, I arrived not at revelation but convention, with the health/stamina/magic trinity, a staple of the PC RPG.

  • Ability resource consumption design. Abilities may consume stamina, magic, health, and/or items. Magic fuels spells, stamina powers physical feats, and items are needed for specific skills such as picking locks. Like health, stamina and magic are represented in points. The quantities of resources consumed by each ability will be fine-tuned during balancing.
  • Player magic and stamina meters. Stamina and magic meters now join the Health meter. I reduced the dimensions of the meters so that they cover up a smaller screen area.
Redesigned health/stamina/magic meters
  • New Action Step: Consume Resources. Luckily, I didn’t have to implement a new system to handle resource consumption; it fits nicely into the Action Step framework, becoming another building block for constructing actions. This was the most logical solution, since abilities essentially just invoke actions.    
  • Added Action Source to Actions. Actions are defined using the following structure: [Actor] do [Action Type] with [Item(s)] on [Target] in [Context]. For the Consume Resources Action Step to work, it needs the source of the action (the ability that invoked the action), so that it knows which resources, and how much of each resource, to consume. The action source has been added to the actor structure, making the structure now: [Actor] do [Action Type] from [Source] with [Items] on [Target] in [Context]. This required a lot of changes in the code, but was done quickly using global search and replace (which is surely an architecture smell).
  • New items
    • Magic and Stamina Potions. Self explanatory.
  • New abilities
    • Health to Magic. Recover magic at the cost of health. No class with healing abilities will be able to use this, since it would be possible to have unlimited health and magic.
    • Magic to Stamina. Recover stamina at the cost of magic.
  • Visual effects. While looking for a way to modify sprite colors at runtime (I need to display grayscale versions of sprites and make sprites appear frozen when they are hit with an Ice spell), I came across a Unity Asset, All in 1 Sprite Shader. It does far more than I need (at least currently), but it was very popular and highly rated (and on sale) so I bought it. Of all the Unity assets I’ve installed, this asset is probably the easiest to learn; simply add the component to a gameobject and, using the component’s UI, select the visual effects you want to apply. However, I don’t think I’m using it in the intended way. I didn’t want to add the component to the dozens of actor and item prefabs because I didn’t want the visual effect to be always on, and I didn’t want to maintain an extra component for actors and items. So, I just used it to make materials, and I’m applying the effects at runtime by changing the sprite material.
  • Improved random Map Element selection. Previously, all Map Elements were assigned a rarity level, which served as the weight in a weighted randomizer. The problem with this is that the rarity distribution changes depending on the number of Map Elements of each rarity level. I’ve now split the selection into two steps. The first step selects the rarity level using a fixed set of probabilities. The second step selects a Map Element from the list of Map Elements of the selected rarity level. This ensures that Map Elements are correctly chosen based on the rarity distribution.
  • Bug fixes
    • Quick Switch and Hotbar slots still interactive after the player dies
    • The action indicator cursor still appears after the player dies
    • Enemies stop moving when the player moves out of sight
  • Minor improvements
    • The Escape key now cancels the Select Cell prompt. My goal is for the game to be completely playable using a keyboard and/or mouse.
    • Ability resource consumption support
      • Preventing abilities from being used if there are insufficient resources
      • Dimming slots containing abilities that can’t be used due to lack of resources
      • Tooltips indicate why ability slots are dimmed

Next week, the major task is reassigning sound effects. I’ve purchased several collections from the Unity asset store, but I recently pulled the files out of the Unity project because they were making project snapshots huge. Now, I need to bring only the sound effects that the game is using back into the project. Beyond that, there will be more play-testing and tightening things up. 

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 – July 29, 2022

  • New items
    • Ring of Protection. Improves the wearer’s damage absorption.
    • Ring of Evasion. Improves the wearer’s chance of evasion.
  • New abilities
    • Resurrection. Resurrects a targeted corpse. I was pleasantly surprised by how easy it was to implement this. It was 95% accomplished in the Unity Editor leveraging existing capabilities.
  • Fear now works on the player. The Fear ability, implemented several weeks ago, only worked on enemies. It needs to work on the player too because an enemy may have this ability. Also, I debated whether the caster should be affected if a Fear spell’s area of effect included the caster. I decided that gameplay would be more interesting if the caster was also affected. This forces the caster to be more careful about choosing the area of effect.
  • AI can now be applied to the player. This enables status effects that temporarily take control of the player, such as Fear. This required a lot of work to implement. I originally assumed the player wouldn’t need AI, and that assumption was reflected in multiple code locations that needed to be modified. This enables some interesting potential future capabilities. For instance, an AI could be written to simulate playing the game.
  • Fixed several bugs related to torches. Torches have been the source of many time-eating bugs. The underlying logic is undoubtedly overengineered. Torches are designed to be lit when placed in a Quick Switch Slot, and extinguished when placed back in inventory. When in a Quick Switch Slot, they generate a light tied to the carrier’s position. Lighting and extinguishing torches is handled by a Convert Item effect, which destroys the original item and replaces it with the new item. This effect is triggered by moving the torch in or out of the Quick Switch Slot. I’ve spent far too much time getting this all to work. Bug fixing has been arduous because it requires tracing through a sequence of triggered events rather than walking through code line-by-line. The implementation had to be simplified, even if that meant hard-coding. I settled on changing how Convert Item worked. Instead of replacing an item, Convert Item now keeps the original item and changes the item type and some other item attributes. It’s not as clean, but it gets rid of item destruction and creation (and the logic triggered by those events). It’s also preferable from a performance standpoint, but that was a minor concern.
  • Changing levels is fully working (again). I’ve been play-testing on a single level for months and broke most of the functionality around changing levels (example: going upstairs to the previous level placed the player on the upstairs cell rather than the downstairs cell). To support the new way that actions work, I had to add Ascend and Descend actions. I discovered some functionality that had never been implemented, for example preserving Quick Switch and Hotbar slots. This was a little tricky because the Quick Switch slot state is part of the standard actor inventory (as selected items, decoupled from the UI), while the Hotbar slot state is housed outside of actor inventory as it’s only needed by the player.
  • Automated tests added for potions, scrolls, and rings.

Next week, I’ll keep fixing the known bugs and play-testing to find more bugs. This will continue until the game is in a state where I can play it for an extended length of time and not encounter a single error in the log or exception. I’m getting there…