Day 4 - Trips, Slips and Fireballs


I ended up being quite productive during this day, which was unexpected. I may have cut into my sleep time a little bit, but I think it was worth it overall.

Day 4

There were a few main categories of work here:

  • Input-handling
  • Behavioural Mechanics
  • Targeting Items
  • Descent

Input Handling

I want to be able to support multiple control schemes, because roguelikes often support a few to suit different keyboard layouts. Traditionally you’d use a numpad, but for many laptops that isn’t an option, leading to various alternatives.

A common one is vi-keys, (HJKL for cardinal directions and then YUNB for the inter-cardinals), but there are a few others too.

To handle this, I took a similar approach to how I handled the color palette yesterday: Define the “purpose” of a key, rather than the input itself, and then resolve that to an InputGroup (DOME’s built in mechanism for bundling a collection of inputs together).

I also made it so that a group could be copied, so that multiple directional controls can be overlaid on the basic interface commands. This is probably the most sophisticated input handling system I’ve built to date.

One missing piece is pulling the input from config files, but I don’t think it’s too far a leap in the future.

Behavioural Mechanics

While following the roguelike tutorial, it implements a “Confusion Scroll”, which inflicts “Confusion” on the target. This means I need some way to temporarily override an entity’s behaviour to do the random confusion move instead.

I’ve used a “stack-based” AI system for the last few roguelikes I’ve made, because it makes composing behaviours quite simple, but this is the first time I needed that stack to be mutable, and it lead to some issues I had to resolve. First off, it turns out there was a problem with my engine, DOME’s, stack implementation: you’d always iterate through it from the bottom first, meaning that any new benhaviours added to the stack were ignored in favour of the ones at the bottom. Oops! I will be spinning a new engine release out later today.

After that was resolved, making sure that the condition expired on time was important to me. At the moment, a condition ticks after every action an entity makes, but this doesn’t feel right to me, as it means “faster” entities recover from a status faster. I need to devise some kind of scheduling system for these sorts of effects (I have ideas on how to do this already, as the main game loop utilizes a scheduling queue for deciding which entity acts next.)

The last one is a design issue: I wanted the player to be confusable also, which lead to some refactoring so that it could be considered a special kind of “stack” entity. But I discovered that when the Confusion effect was applied, you’d lose all player agency: it’d just play out the moves of confusion til the effect expires. I’m not sure how I feel about that. I think it’d be nice to have some kind of input from the player instead, but “how” to make that happen is currently not clear.

With those issues identified and systems implemented, I could move onto the meat of the work.

Targeting and Inventory

Following the tutorial, I introduced a few magical scrolls that have different effects:

  1. Lightning Scroll - Targets the nearest enemy at random.
  2. Confusion Scroll - Mentioned above, it confuses a target, but you get to pick one target from within range.
  3. Fireball Scroll - Blasts a group in a small area, which can be positioned at range.

The challenge here was implementing a flexible enough UI mechanism for selecting a target for the Confusion and Fireball scrolls without everything getting very complicated.

UI code in my games is often a bit of a rabbit hole, but I think the eventual solution this time ended up not being too bad.

The cursor you see is actually attached to the map renderer - the renderer knows how to map world co-ordinates to screen co-ordinates, and the cursor needs to do the same.

It also handles hover inputs from the mouse thanks to the “hover” label earlier in the tutorial. co-opting that for targeting is a nice bonus.

The cursor needs to be passed the correct information from the player about where to get positioned, as well as the area of effect, and this all gets passed in through a simple event system.

The logic for doing the targeting itself occurs in one of the scene “states”, which can only handle world co-ordinates, but it can implement all the required rules: how far can a target be? Can we target the floor, or must we go for an entity? Do I have to see what I’m targeting? etc. Once it decides a position is valid, it emits an event which is passed down the UI tree to the cursor, telling it to move. Overall, a nice separation of concerns.

I pushed hard into the night to get the fireball working, it was the last of the scrolls to be implemented. Seeing it working was such a delight.

(A story of two parts)

The last main squeeze was removing my debug shortcuts for using items, and instead implementing a proper key interface for the inventory: items get labeled 1-9 and then A-Z, and pressing that key with the inventory open uses it: it also detects if an item needs targeting and initiates that.

Descent

I managed to make it half-way through the next chapter, implementing stairs for going deeper into the dungeon: this is a big deal for me, I’ve never implemented it before. Thankfully, I made some good decisions about how my framework handles the floors so that things can be easily generated. With some tweaks, I set things up to be generated on demand and we are away. Added some stairs to descend and a new level loads. There are upward stairs too, but they don’t do anything yet.

(You can see the gold down-stairs and maybe the green up-stairs)

What’s Next

There’s a little polishing to do for the descent system: I’d like something printed in the log, maybe some kind of visual transition, not sure.

After that, the tutorial suggests a “level up” system, but I don’t think I need that for my game design, so I’ll move on to the character information display, and then wearable equipment.

What’s a paladin without a suit of armor, after all?

Happy delving!

Files

Windows x64 3 MB
Version 0.0.4 Mar 09, 2023
Windows x32 3 MB
Version 0.0.4 Mar 09, 2023
Mac OS (x64 & ARM64) 4 MB
Version 0.0.4 Mar 09, 2023
Linux x64 6 MB
Version 0.0.4 Mar 09, 2023

Get Acolyte's Pledge

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.