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.
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.
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.
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.
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.
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.
Cell selection improvements. The area of effect is now highlighted and the cell indicator (not just the mouse cursor) is now shown.
15 sound effectsadded.
Next week I’ll take a break from new features to shorten the bug list. Saving and loading is broken again.
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.
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.
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.
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.
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.
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).
Magic and Stamina Potions. Self explanatory.
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.
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
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.
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.
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.
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.
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.
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.
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.
There’s not much of interest to report this week. Last week I implied that there wasn’t much work to do on Cell Context Menus because they technically already exist – the Inspect Panel lists the actions that can be performed on the entity being inspected. However, not all of the actions were listed. I couldn’t simply add the missing items because they are implemented in a different manner than the actions that were being listed. Specifically, the missing actions inherit from the UserCommand class and the included actions inherit from the ActionType class. I decided to simplify things by having actions inherit from ActionType, and limiting the purpose of UserCommand to mapping input to actions. This led to a lot of rework.
Item light sources for non-player actors. Actors other than the player now display light sources from the items they’ve equipped.
Dropped torches. When a lit torch is dropped, it now stays lit and maintains its light source. When the player picks up the torch, the torch is added to inventory as an unlit torch and the light source is removed.
Quick Switch Slot improvement. When no item is selected in a Quick Switch Slot, the deselect option, which is redundant in this scenario, is no longer shown.
Bug fixes. These were mostly issues introduced by this week’s extensive rework rather than long-standing issues.
Refactoring. I used the rework as an opportunity to refactor where it was easy to do. This included cleaning up some classes and method extraction.
Contemplated a name change. “Legend” is the third name that this game has had. I’m considering changing it after recently watching a video on naming your game. My concerns are that “Legend” is too generic, too hard to search for, and has copyright risk. I made a list of words that convey some aspect of the game this week. None of them jumped out at me. I’ll keep adding to the list and playing around with different combinations until something clicks.
Next week, there’s some more rework testing and cleanup to do. I also need to make minor refinements to some of the recently added features.
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.
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.