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

I threw away a big chunk of the code that I just wrote last week for Stat Modifiers. I made this decision when it became evident that maintaining a running sum of all Stat Modifiers for each Stat Type wasn’t worth the complexity. I originally chose this approach for efficiency; since the modifiers didn’t change that often, it would be more efficient to precalculate and store the values. In practice, however, the values are used infrequently enough that recalculating them every time doesn’t impact performance. The added complexity, primarily due to having to synchronize the running sums with the individual modifiers, increased the implementation effort and defect risk. In general, it’s preferable to store information in one place only.

  • Improved Inventory Panel. The number of inventory slots has expanded from 24 to 32, the panel has widened, and combat stats are now displayed.
Inventory with stats
  • Tooltips for stat bars and status effects. Hovering over the Health, Stamina, or Magic bars, or a status effect icon, now displays a tooltip with additional info.
  • Actor Debugging Panel. A new toggleable panel displays detailed info about active actors, including location, vitals, status effects, and AI state. It’s been very useful for squashing AI bugs. This is a developer-only feature; it won’t be available to players.
Actor debugger
  • Bug fixes.

Next week starts with closing out AI bugs, followed by validating combat calculations (now that Stat Modifiers are in place) and continuing to add sound effects. Also, I’m going to start on interactions between items and objects, such as scooping water into an empty vial from a fountain. 

Weekly Update – September 16, 2022

The first half of the week was solid – new feature development for release readiness, lots of bug fixes, and no scope creep. The rest of the week was consumed by messy rework that slowed progress and, I fear, will produce many new bugs. Automated testing should catch most of the bugs, however.

  • Stat Modifiers. Stat modifications caused by equipment, status effects, and terrain are now defined in lists instead of individual variables. This greatly simplifies the logic for calculating net stat values and displaying modifiers in an itemized fashion (which the Character Panel now does). Stat modifiers are either added or subtracted; multiplication and division aren’t used. This allows modifiers to be applied in any order.
  • Separate visual effects for unavailable drag drop slots. The UI dims drag drop slots to inform users when slots are unavailable. This was initially used to indicate slots that couldn’t receive the dragged object, for example dragging leather armor into a hotbar slot. When ability resource consumption was recently added, the same dimming functionality was used to indicate abilities that couldn’t be used due to inadequate resources. This introduced some bugs because the dimming logic now needed to handle combination scenarios. For instance, if an ability was dimmed because of inadequate resources, it would undim after being dragged because the drag drop logic would reset it. Using the same dimming effect for two different reasons also made the effect ambiguous. I addressed these issues by adding a separate dimming effect for slots with abilities that couldn’t be used and separating the dimming logic for the two scenarios. One visual effect darkens the slot and the other displays the slot contents in greyscale.
  • Many bug fixes

Next week, I’ll complete the remaining clean up for stat modifiers and add them to the character panel. Then, I need to get back to sound effects. The sound effects implementation has to be reworked somewhat. The varying sounds for physical material and item combinations are cumbersome to configure. There’s too much repetition; centralization is needed. I also want to create an in-game tool for understanding what the AI is doing. Much of the AI info is already logged but it’s difficult to wade through it.

Weekly Update – September 9, 2022

It was a highly productive week. 100% of my time went into features and fixes that are required for the initial release (not always the case).

  • Status effect icons. Enemy status effect icons now appear above the enemy. Player status effects are now represented as icons as well, located next to the health bar.
Status effect icons
  • Loading screen. New levels now display a loading screen, complete with a progress bar and text describing what is currently happening. At first, the progress bar was based on AsyncOperation.progress, which tracks the progress of an asynchronous scene load in Unity. The bar quickly got to 90% and then hung for around ten seconds. This delay was, of course, the procedural generation. Luckily, when I made the map generation visualizer last year, I had to reduce map generation into hierarchical, independent units of work – maps are generated by a series of processors, processors are composed of stages, stages are composed of substages, and substages are composed of tasks. The tasks are pre-generated and placed in a queue. This enables the map generation visualizer to display the result of one task at a time and interactively fast forward through substages, stages, and processors. It also makes it easy to calculate the progress percentage. I only had to make a slight modification to make it work with the loading screen progress bar, which was to wrap it in a coroutine and have it yield after each substage so that the UI could update the status.
Loading screen
  • Cell selection improvements. The area of effect is now highlighted and the cell indicator (not just the mouse cursor) is now shown.
  • 15 sound effects added.
  • Bug fixes.

Next week I’ll take a break from new features to shorten the bug list. Saving and loading is broken again.

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

This week, I started on the next milestone, abilities. Abilities include special attacks, spells, utility skills, and passive effects. I have a list of around 90 abilities currently and expect the final count to be between 120 and 150. Each actor (player classes, NPC’s, enemies) will start with zero or more abilities. Players can gain more abilities over the course of the game. I haven’t worked out all the details, but the ability acquisition will be integrated into gameplay (i.e. they can be found like items, or learned from an NPC) as opposed to a skill tree. Like items, the abilities placed on the map get stronger the deeper the player goes. The abilities available to the player depend on the player’s class. Each class has a set of attributes and a maximum proficiency level for each attribute (basic, intermediate, advanced). Each attribute proficiency level is associated with a set of abilities. A class is able to use the abilities defined for each of its attributes, at or below the proficiency level defined for that attribute. For example, a Ranger has a Weapons (Intermediate) attribute that allows use of the abilities associated with the basic and intermediate proficiency levels of the Weapons attribute.

  • Reworked abilities and attribute classes. Basic ability and attribute functionality was already in place to display attributes on the class selection screen and display abilities available to the player. To fully support the ability system, the underlying code had to be extensively reworked. Most of this week’s time went into this rework. Active and passive abilities were split into separate classes inheriting from a common base class. Relationships between attributes, attribute proficiency levels, and abilities were rewired. Attribute ScriptableObject assets were condensed from one asset per combination of attribute and proficiency level to one asset per attribute to directly group abilities for each proficiency level (this is useful because classes have access to abilities for a maximum proficiency level and all proficiency levels below the maximum).
  • Improved Abilities Panel. The Abilities Panel previously displayed all available abilities in a single grid. Now the panel has a tab for each Actor Attribute and the abilities for the selected attribute are grouped by proficiency level.
  • Miscellaneous ability-related enhancements
    • Starting abilities automatically added to the hotbar.
    • Abilities can be inspected like entities and cells.
  • Contemplated replacing abilities with items. This is more of a side note than an update, but midweek I stopped development and seriously considered implementing abilities as items. The origin of the thought was my struggle to determine how resource consumption will work with abilities (I still haven’t figured this out, by the way). One option was to simplify and consolidate resource management to inventory. Players would find items that did the same things that abilities would do – a scroll to cast a spell, lockpicks to pick a lock, etc. This idea appealed to me because clever use of what you find is key to success in the game, and it avoids using time as a resource (waiting to regenerate mana/stamina). But, there are drawbacks: 1) the desired player behavior is to frequently use abilities, but having a finite number of uses and uncertainty about how many future uses the player will have encourages hoarding 2) it’s difficult to allot uses of large quantities of items over the course of the game. Because of the drawbacks, I rejected the idea and resumed work on abilities as planned.

Next week, now that the abilities system is complete, work will begin on the abilities themselves. The big challenge here is implementing many abilities in a scalable manner. I want to avoid creating a separate class for every ability, and I want to leverage existing objects like actions and effects as much as possible.

Weekly Update – April 15, 2022

More UI improvements were made this week. They were relatively minor; there are no major pending improvements. I continued using clockify.me to track my time. I’ll share stats after accumulating a month’s worth of data.

  • Action icon size reduced, resolution increased. I originally made the action icons larger than desired because the game’s low base resolution (640×360) 
  • Arrows displayed in between action icons. This better depicts that the displayed actions are performed in a sequence.
  • Tooltips for game buttons (inventory, game menu, etc.)
  • Small adjustments. Changed from a left click to a right click for inspecting items in inventory (for consistency with the rest of the UX); improved Inspect Panel button layouts; enabled the Inspect Panel for hotbar and Quick Switch Slots.
  • Improvements that were reverted. I added displaying tooltips when hovering over cells but removed it because it seemed too redundant. I also added code that would reposition the action icon when it appeared over the player, but it didn’t benefit the experience and created an inconsistency. 
  • Bug fixes. These addressed issues created by the recent changes.

I’m still determining the direction for next week. It’s time to tackle the next item on the roadmap, which is the main game loop. This involves player visibility and combat. I need to build out some abilities to truly playtest combat.

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.