The big news this week is that the Quick Switch Slots and Cell Action Indicators are done. I started on these exactly one month ago. They shouldn’t have taken this long to complete, but did because I had less time than usual over the past month and I underestimated the effort to code the features. They are two of the remaining three major UI features that need to be added (the third being Cell Context Menus).
Completed Quick Switch Slots. Quick Switch Slots are similar to a hotbar, but are used to quickly change weapons and other held equipment, and enable automatic switching of melee and ranged weapons based on the target’s distance from the player.
CompletedCell Action Indicators. Cell Action Indicators tell the player what will occur when a particular cell is left-clicked. An icon representing the action the player will perform is displayed when the cursor hovers over a cell. If the player first needs to move closer to the cell to perform the action, the Cell Action Indicator will display two icons, one for movement and another for the action to be performed.
Player input and action refactoring. The above UI changes touched one of the uglier parts of the code that is responsible for triggering in-game actions from player input. In the interest of finishing this game, I’m being more selective on rework. However, some rework was unavoidable this time. Previously, there were Player Actions (actions mapped directly to player input, which could translate to in-game actions such as moving the player’s character, or UI actions such as opening the Inventory Panel), Action Types (in-game actions), and Actions (instances of Action Types, but still defined as separate classes for each Action Type due to the evolution of the code). It was messy and redundant. I renamed Player Actions to User Commands, which helped me mentally differentiate these from in-game actions. I added a minimum and maximum range attribute to each action so that the Cell Action Indicators can determine whether the player’s character has to move in range of an entity before interacting with it, replacing some hard-coded logic that only worked in certain scenarios. I standardized User Commands and Actions behavior. I moved some methods into more appropriate classes. I fixed all the little issues that cropped up from the changes. I even found a couple of bugs that predated the recent changes.
Wand of Magic Missile. The Wand of Magic Missile was primarily created as a proof of concept for getting wands working, but will most likely stay in the game, and perhaps be a starter weapon for the Wizard class. I’m still deciding how to configure wands in terms of resource consumption. I’m leaning toward unlimited charges, no cooldowns, and eventual destruction from use. Wands will have to be underpowered to support this.
Next week, I’ll start working on the final remaining UI feature: Cell Context Menus. Right-clicking a cell will display a Cell Context Menu that lists all of the possible actions that can be performed on the cell (left-clicking performs the default action, as indicated by the Cell Action Indicator).
I had more available time than last week, but not by much. Still, I was able to get priorities 1 and 2 from last week done.
Finalized and implemented click cell logic. I thought I had this completely figured out a couple of weeks ago, but I ran into complications. The point-and-click control scheme uses rules to determine what the player character does when clicking on a particular cell, based on the contents of the cell and the items selected in the quick switch slots. The purpose of this control scheme is to make the game both intuitive and efficient to play. As such, the action chosen should match the player’s expectation of what happens when clicking on a cell. However, in some scenarios, I didn’t feel that there was an obvious action. For example, if a player has ranged and melee weapons selected, what should happen when the player clicks on an enemy outside of the ranged weapon range? Another example is pushing an object in a cell. If the cell is not adjacent to the player (requiring the player to move to the object and then push it), the direction to push the object can’t be inferred. Both of these examples stem from being able to both move and perform an action by clicking a cell. If players were required to move and perform actions separately, there would be only possible outcome for each combination of cell and action. However, player input would be less streamlined and intuitive with this constraint. My general solution to this problem was to display the combination of actions (e.g. move, then perform melee attack) to explicitly communicate to players what would happen when clicking on a particular cell. I think it works well but I’ll need to get feedback from others. By the way, the solution to the push example above involved having the player specify the direction to push the object in (unless the player is adjacent to the object, in which case the direction can be inferred).
Made shooting/throwing work with quick switch slots. As mentioned last week, shooting had to be reworked for quick switch slots. This involved disabling the select cell prompt and basing the target on the cell the player clicked.
Work is winding down on the quick switch and click cell mechanics. I’m looking forward to doing something different, though I’m still focusing on the UI. After UI, it’s onto visibility, which includes field of vision, fog of war, and lighting. The main tasks remaining in this area are implementing torches and fully integrating FOV/FOW with the recently added dynamic lighting.
It’s been slow-going the past few weeks due to limited free time (the typical reason). I continued to work on the new quick switch slot feature this week. I uncovered another existing capability that needs rework to support quick switch slots: using a bow and arrow. Originally, to shoot an arrow, the player had to click a hotbar slot containing arrows and then select the target cell. Part of my justification for creating the quick switch slots was to make the shooting process less cumbersome. I wanted to limit mouse clicks and mouse movement as much as possible. The rework I now need to do is to bypass the cell selection step and fire the arrow as soon as the player clicks on a valid target in the range of the player’s selected bow.
Cosmetic improvements to quick switch slots. I changed the background color to differentiate quick switch slots from standard inventory slots. I also added an icon for deselecting a quick switch item.
Bug fixes related to the recent equipment changes.
Next week, my priorities are: 1) get bows and arrows working again, 2) finish the logic that determines the action to perform when a cell is clicked based on the selected quick switch items, and 3) get torches working. Time will again be a challenge in the coming week, so I’m not sure how far I’ll get.
The UI work I started last week and planned to finish this week ended up being more difficult than I expected. In particular, the selected cell action indicator (described below) required more coding and some refactoring.
Separated equipment slots from inventory. One of the many things I did to get a working game early on was to display equipment slots in the same grid as the inventory slots. In addition to simplifying development, I did this because I hadn’t determined what the final equipment slots would be. After deciding on the equipment slots, I needed to move the slots out of the inventory grid and into their own area on the screen. Equipment is now displayed in two columns, one for main worn equipment (helm, armor, etc.) and another for accessories (necklace, ring, etc.), with an image of the player sprite in the middle. Note the sprite does not yet reflect the actual items equipped by the player.
Selected cell indicator. The cell that the mouse is hovering over is now indicated by a camera frame icon. This makes it easier to tell which cell is selected when the mouse cursor is in between two cells.
Selected cell action indicator. In addition to displaying the selected cell indicator, hovering over a cell now displays an icon indicating the action that will be performed when left-clicking on the cell. This is useful because the action the player performs when clicking on a cell depends on several factors: the contents of the cell, the player’s proximity to the cell, and the player’s selected melee and ranged weapons. For example, the icon shown over a cell that contains an enemy and is adjacent to the player will display a melee attack icon. Non-combat actions can be displayed, such as opening a chest.
Moved game menu buttons from the bottom right corner of the screen to the middle right side of the screen. This was done to better balance the UI layout, specifically by making the quick switch slots and menu buttons symmetrical.
New Map Element: Lairs. Lairs contain a dangerous beast and are littered with bones. They’re generally found in dead ends in caves.
Next week, I’m confident I can close out the remaining UI work. This was my main goal for February, so I’m a tad behind.
This week, I worked on a single feature: quick equipment switching. This feature allows held equipment (melee weapons, ranged weapons, ammo, and light sources) to be switched without going into inventory. There are many situations in which held equipment needs to be changed. A common scenario is hitting an object that is vulnerable to a particular damage type or effect. For example, a mace, which does bludgeoning damage, will be more effective on a cracked wall than a sword, which does slashing damage.
Quick equipment switching is also used to determine the weapon against an enemy or object. For targets at a distance, the selected ranged weapon will be used. For targets in melee range, the selected melee weapon will be used. This enables the player to use different weapons for melee and ranged targets without having to manually switch weapons. It’s convenient for classes like the ranger that primarily use a ranged weapon but switch to a melee weapon when enemies close in to conserve arrows. Players can also choose to not equip anything in a particular quick switch slot, which is useful if the player wants to use only a single weapon regardless of the target’s distance (if the ranged weapon slot isn’t set, the player will move toward a target until the target is in melee range and then attack).
This feature is 50% complete. I plan to finish the remaining half next week. I still need to make some UI/UX tweaks and incorporate the selected items into the save/load system. I also want the cursor to indicate the weapon that will be used when hovering over a cell.
UI finalization, which started two weeks ago, continued this week. Some questions that have been open since day one, such as available equipment slots, are getting answered because they’re dependencies for completing the UI.
Decided on equipment slots. This is finally done. It was one of those things that I overthought. My original philosophy was to keep things simple and have a single armor slot, and some slots for accessories like rings. My thinking changed as the depth of the game expanded. The final equipment slots are Armor, Helm, Gloves, Boots, Necklace, Rings (2), and Shield (note that weapons are handled in a different manner, to be explained in a future post). Adding the new slots to the actor inventory was easy. I had to do a little bit of rework because of the rings. The original logic assumed that there’d only be one slot per equipment type.
Updated damage absorption and evasion calculations. With multiple pieces of equipment potentially affecting damage absorption and evasion, I had to update the combat calculations. This wasn’t difficult, but balancing got more complicated. I now have to consider mixed pieces of equipment, partial equipment, and class restrictions on each equipment type.
New items: Leather Gloves, Leather Boots, Leather Cap, Wooden Round Shield, Wand of Magic Missile, Necklace of Protection, Ring of Invisibility. These were created to test the new equipment slots. They may or may not make it into the final game. In particular, the Ring of Invisibility, which grants invisibility as long as it’s worn, is too overpowered.
New map elements: Mushrooms and Crystals. Caves are in need of more variety so I added glowing mushrooms and crystals.
Indefinite status effects. Previously all status effects were temporary; after a certain number of turns the effect disappeared. Now, status effects can last indefinitely. This was needed for the Ring of Invisibility and will be needed for all equipment that gives the player a status effect while worn.
Next week, I’m implementing the quick switch slots for weapons and light sources as part of the UI finalization.
It was one of those weeks where most of the time went into thinking rather than doing. Hence, there weren’t many concrete achievements. The thinking was around UI design, specifically how to quickly switch between different weapons, how to automatically use ranged weapons for distant enemies and melee weapons for nearby enemies, how to handle torches, and equipment slots. I wrote out so many different solutions. None of them were perfect; they each had pros and cons. I think I’ve chosen a solution but need to consider how the solution applies to all the possible scenarios. The solution involves an additional hotbar that lets the player quickly change melee weapons, ranged weapons, and ranged weapon ammo, and logic for when the player clicks on a cell that determines whether to use a melee or ranged weapon. It seems sound to me, but only feedback from other players will confirm whether it is intuitive and user-friendly.
I added a few new map elements, which is something I’m trying to do every week to have a wide variety by launch. As always, there were some bug fixes too.
Witch’s Chamber. The Witch’s Chamber map element places a cauldron, a witch, and some bookcases and tables in a room. The witch is brewing something in her cauldron, which emits a blue glow. I need to give the witch some abilities. I’m not sure what I’ll do with the cauldron.
Summoning Chamber. The Summoning Chamber map element places a summoning circle, demon, and summoner in a room. The summoner has just recently summoned a powerful demon in the summoning circle. I need to build out the demon’s abilities and the summoner’s AI (the summoner lets the demon do the fighting and avoids the player).
Also, here are a few examples of the objects added last week:
Next week I’ll implement the UI features I spent this week designing and try them out in the game. This is the next item on the critical path.
Legend has been in development for 2.3 years. It’s hard to believe that that much time has passed since I started working on the game. I don’t know if anyone else has experienced this, but how I felt at the two-year mark was in stark contrast to my feelings at the one-year mark. After the first year of development, I was thrilled with how much I had accomplished and excited for the future. At two years, panic set in. How could I possibly finish at the rate I was going? Was I wasting my time? Was this game even any good?
Ultimately, the mid-gamedev crisis was a good thing. This was my brain telling me to reassess and correct course. That’s exactly what I did in the latter part of the year. The reality was that, at the rate Legend was progressing, it would need at least several more years to release. I don’t want to wait that long (I have more games to do!). I cut a large chunk of planned features while preserving the original vision. I forced myself to make decisions. I have a tendency to postpone decisions as long as possible to avoid limiting possibilities. It’s been a sure-fire way of keeping completion in the distant future.
Development thus far has consisted primarily of building the game system framework, and rebuilding many facets of the framework as my Unity knowledge increased and my ideas crystalized. Heading into 2022, the framework is done and development shifts to using the framework to flesh out the actual game.
What I said I was going to do in 2021:
Replacing the stock art
I’m still using Oryx. I still have some uncertainty about the exact 2D perspective that will be used. I also feel that the art doesn’t need to be replaced until the game is ready for a public release.
A handful of new enemies, items, and objects were added. Every piece of existing content was reworked in some way, for example extracting a parent class for actors and items, and moving from room-based to element-based map generation.
At the beginning of 2021, I never would have expected to accomplish as much as I did in this area. I considered polish something you do at the end of development. That largely is the case, but I’m using “polish” loosely here to refer to any visual and audio effects beyond the bare minimum, and refinement of any sort, such as fine tuning procedural generation and balancing combat. The game looked bad and felt dull whenever I did testing. Even though I knew I’d improve the look and feel before launch, I was still getting discouraged. For my own psychological benefit more than anything else, I added some game juice, including:
This did the trick; I could finally envision other people playing the game.
I posted a weekly dev update on the website and Sharing Saturday on r/roguelikedev. I posted the link to each Sharing Saturday update on Twitter. I occasionally posted videos on Youtube. I have tiny followings on those channels. I continued to spend a minimal amount of time on community in favor of game development.
The new map generator, started in 2020, was finished in January. I built some dev tools for procedural generation analysis, tuning, and troubleshooting: an interactive map generation visualizer and a map graph visualizer. These proved to be very handy.
I made another major change to map generation later in the year with the addition of Map Elements. These are the basic building blocks for populating a map with content after the map structure’s been created. They’re hierarchical and modular, enabling rooms to be constructed from layers of interchangeable components and reuse common components. For example, many room types can include an Abandoned Map Element that adds cobwebs and debris to give the appearance that the room is abandoned.
Maps became both more varied and more playable. Map configuration parameters, which dictate a map’s structure (number of rooms, room sizes, room distances, room themes, etc.) are now randomized. This additional layer of procedural generation increased the variety of maps while maintaining consistency within a map. Map configuration parameter ranges were fine-tuned to avoid problematic maps. Room type probability changed from a linear distribution to a weighted distribution based on rarity to give maps a more logical composition of rooms.
Significant UI work was done. New screens were added, a hotbar was added, and the main game UI was refined.
AI was expanded. Now, actors can have their own AI controllers and behave differently than other actors. AI controllers can be reused across multiple actor types. Actors can now track any number of other actors, enabling them to do much more than charging the player. They can attack, defend, and interact in other ways with tracked actors as dictated by their AI controller. Actors now gain awareness of events based on their vision and hearing ranges and act based on the type of event occurring. Each actor has its own inventory and the ability to pick up items and use them. When an actor dies, other actors can acquire the items it was carrying.
In light of my time constraints and the mountain of work remaining, I made a deliberate effort throughout the year to increase my productivity. The ways in which I did this include:
Reducing and simplifying code.
Moving logic from code to configuration (physical material interactions, game events).
Adding unit testing.
Adding an in-game console for spawning objects to accelerate playtesting.
Adding more granular logging so that I have more information to troubleshoot.
Consolidating test settings into a single design-time editable object.
Finally, code rework occurred throughout the year. Most of it was necessary to keep the code maintainable, but I also know that I am overly eager to rework code and sometimes create more problems for myself than I solve. As the year progressed, the rework did slow down. There are two reasons for this: 1) the framework reached maturity and 2) I became more selective with when I reworked code. Before I make changes or add new features, I now consider what compromises I can make and what I can do within the existing framework to avoid rework.
This year’s goals are essentially the same as last year’s. However, the priorities have changed. An early access release is now the primary goal. Original art, a requirement for the release, is also a top priority. Effort will be concentrated on what is absolutely necessary for public release, including tightening the game loop, balancing, and clearing the bug list.
I continued to work on combat this week, but shifted from core mechanics to “game feel.” After adding particle effects and sound effects, combat is much more satisfying. The game is getting closer to being fun. 🙂
This Week’s Achievements
Combat particle effects. I’ve never worked with particle effects. There’s a learning curve with Unity’s particle effects system, but being able to change settings in the editor and see the effect in real-time helped immensely. Also, I accelerated by learning my buying a particle effect package in the Unity asset store and studying how it worked. I created a few particle effects for when an actor/object is hit with a weapon. The target’s physical material determines the particle effect. For example, when a rat is hit it will spray blood, while a skeleton archer will spray bones and bone fragments. Additionally, the size and number of particles vary based on the amount of damage inflicted.
Improved combat sound effects. I was annoyed with the combat sound effects I chose. They were so quiet and boring. I was going to have to either find better assets, increase the volumes of the assets I had, or use the Unity audio mixer to get better sound. I was also running into an issue where the direction the sound was coming from was wrong. But, that issue ended up being a blessing in disguise because it made me realize why I was having low volume issues: the audio listener was attached to the main camera, which was way up above the player. When I attached the listener to the player, all the volume issues went away (though I haven’t fixed the directional issue yet).
Added hooks for additional sound effects,including dying, taking an object, ambient sound, footsteps, and walking on different types of terrain. Footsteps are challenging. I lowered the volume and slightly randomized the pitch of each step to make them less prominent and repetitive.
Right-clicking does something. Right-clicking on an object will display the Inspect Panel for that object. I should’ve done this a long time ago, but it was overlooked because the original target platform was mobile rather than PC.
Mapping the number keys to hotbar slots. Another basic feature I overlooked – allowing items in the hotbar to be used by pressing the corresponding number key.
Added probabilities to triggered game events. For example, when a pile of bones is destroyed, there’s a 50% chance that a ghost will spawn. This provides some unpredictability and more player choice.
Framework for player notifications in the Inspect Panel. When a player inspects an object, in addition to the description of the object, I want to communicate important gameplay information. For example, if the player inspects an object that is far away, I want to inform players that they need to be standing next to the object to interact with it. There’s now a framework for collecting notifications from various sources and prominently displaying them on the Inspect Panel.
Fixed many combat bugs. There were a surprising number of things that didn’t work or caused crashes. The majority of these bugs were from the last major refactoring.
Next Week’s Goals
Next week, I’ll continue working on “game feel” and small refinements that go a long way. I’m way off track on the milestone schedule, but I feel closer to being done than I think I would have had I stuck with the planned milestones. The additional content I was previously working on wasn’t making the game any better because the core loop was lacking.
September 2021 Goals: Enemy Alerts: 0%; Abilities: 0%; Sound Effects: 0%; Character Window: 30%; Options Window: 100%
This Week’s Achievements
Saving/loading Inventory and Hotbar state. The contents of each slot are now saved when exiting the game and restored when the game is loaded. This was more complicated than expected because the hotbar stores references to items/abilities rather than items/abilities themselves, and abilities didn’t have unique ID’s because they don’t inherit from the same parent class that actors and items inherit from.
Completed the Abilities Window, along with all the supporting classes for Abilities – the main Ability class, an actor Ability Manager, an Ability Factory, an Ability Type scriptable object, and starting Ability Profiles.
Drag and drop visual improvements – using highlighting and dimming to inform the player of which slot is being dragged from and which slots are eligible to be dragged into.
Started and completed the Options Window. This window allows the player to quit to the desktop, quit to the main menu, or return to the game. I’ll add more options later on, such as turning music and sound effects on/off.
Started on the Character Window. This window provides info about the player’s character. I’m still finalizing the layout and contents, but built a basic version with the character image, name, and class.
Associated Abilities with Class Attributes. The benefit of this is that abilities don’t need to be directly mapped to classes; the class attributes determine which abilities are available. For instance, a class with a High Divine Magic attribute has access to the highest Divine Magic spells.
Next Week’s Goals
Next week, I’ll finish the Character Window and add the first group of Abilities.