The Ebonheim Chronicle

Development Blog for Chronicles IV: Ebonheim

I posted some gifs of my combat system mostly working which I'm proud of but I want to go ahead and do a little write-up on the mechanics as-designed and talk about plans for the future sooo hit the jump if you're into that.


Philosophy

I really want a combat system that focuses most of its complexity on strategic positioning rather than on numbers and calculations. It's one direction to take Nethack and focus on itemization and +10% bonuses and heavily numbers-driven character advancement but I wanted a deterministic rules-based system that is simple to pick up.

I was heavily inspired of course by Into the Breach with its chess-like puzzle boards but I also really appreciate a similar ethos from Slay the Spire where these games attempt to provide the player with as much information as possible about the outcome of their choices while still being challenging.

Rules of Combat

The sum-total set of rules that govern the above gif are as-follows:

  1. Actors have health (red pips) and stamina (green pips)
  2. When an actor receives damage, stamina is removed before health
  3. When an actor attacks, it also costs stamina
  4. If an actor loses all stamina before acting, their attack will be cancelled
  5. Stamina spent on attacking will recover on the actor's next turn (right before they act)
  6. Stamina lost from damage will recover 2 turns after it is lost (right before the actor acts)
  7. If an actor is being targeted by an attack and moves away before the attack executes, they will take an automatic 1 damage (“dodge cost”)
  8. Actors have speed which determine turn-execution-order (roman numerals)
  9. The player has turn-order priority within their speed category

In the above gif I slowed the execution way down to see all of the parts. White pips are stamina that will recover before the next action. The player dispatches a low-stamina enemy that is faster (moves first) and then suffers dodge cost to reposition around the enemies. They then uses player-advantage to cancel the enemy hits and take them out one at a time before they can act.

EGA UI

My tiles are 14x14 and the entire frame buffer shares a single 16-color palette from the 64-color EGA color space. I don't have arbitrary scaling or rotation. Everything has to fit under these restrictions including UI elements. This proves very challenging when you're making an RPG!

A large part of breaking this down and reducing complexity is to define meaning to specific palette slots. For instance Palette Index #0 is always “Black” AKA the “Background Element Color” and the “Border Color” When creating art for map tiles, UI elements, actor sprites, I always use index 0 for this purpose. That way if I make a new palette, I can change #0 to a non-black and expect a fairly uniform distribution of effect on all of the art.

Next just comes down to the size of UI elements. Displaying health and stamina is shown on the tiles as pips which are, at minimum, 2x4 pixels. So literally I can't have more health and stamina in one row at the bottom of the tile than the tile can hold (7). I have a system to show multiple rows but a lot of these restrictions actually feed back into the simple design of the combat in the first place. I don't expect to have more than 30 combined health/stamina on a single actor just like I don't expect more than 16 actors to be in the turn order (because that's the largest roman numeral I can fit on a tile)

Other UI concepts that go into consideration are things like the pants color of a sprite happening to line up with the pips in such a way that it appears they have more stamina than they do. Another fun one was reducing black border pixels around elements to allow more of an actor sprite to bleed through from below.

Improving AI

My A* solves are fine enough for these gifs but you may notice a recurring concept in that enemies will often arbitrarily block each other trying to get adjacent to the player. This usually blocks their allies who have to go around, allowing the player to exploit the position and pick the enemies off one at a time. This sort of thing happens in Nethack and other dungeon crawlers where the common strategy is to always just back up to a hallway and force enemies into a bottleneck. I don't really want this strategy to always be universally viable.

A big part of the improvement is going to be mapping the possible decisions onto a weighted graph and solving with Dijkstra's. I want allied enemies to give multi-enemy-to-player-adjacency a higher weight. In the future I will also want enemies to block doorways and be smarter about getting into range of attack. The Player Advantage is a really big one because enemies can't react to player action on the turn that it happens. The counter-balance to me is better strategic positioning behavior.

The end-result I hope is a system where 2-on-1 fights are fairly unwinnable with basic combat. Overcoming difficult encounters will need to rely heavily on the upcoming abilities system.

Future Plans

Next up is more complicated attack patterns. I want to implement ranged attacks that don't require dodge-cost to avoid and play with that. My original spec also included a 3rd pip type, armor, which sits between health and stamina and is purely there to mitigate a new stun mechanic where certain attacks can cause action interrupt.

All of this is also building toward the really good stuff which are arbitrary cooldown abilities. I want abilities to make or break encounters because which abilities you have informs your character's build. Abilities will revolve around concepts such as pushing other actors around, repositioning, teleporting, redirecting enemy actions, sneaking / visibility, and bypassing the existing stamina rules.

Once you start thinking of things like side-pushing an enemy so they kill an adjacent enemy on your turn before that enemy attacks, the rest all starts to spill out, it's very exciting!

First Playable

I've reduced the full scope of the larger game project into just being a combat demo. This will be a standalone game that will be a set of a dozen or so pre-made encounters where the player will need to solve the encounter with their weapon and abilities and not die to continue onto the next. I hope with this project that I'll have a very well-fleshed-out combat system before I start moving onto the exploration and roguelike loop systems.

You Made it!

:eggbug: Good Job :eggbug:

:host-love: Thanks for reading :host-love:

#gamedev #chron4 #longpost

| 🌐 | 🙋‍ | @britown@blog.brianna.town

A big part of the elevator pitch for Chronicles is Nethack with Into the Breach-inspired combat. As it turns out it can be really hard to message out to a player what is happening in combat when you have no pixels and no colors!!!

There's just 8 million tiny tweaks and details to make these gifs happen and I'm really happy with them.

#gamedev #chron4

| 🌐 | 🙋‍ | @britown@blog.brianna.town

Feels like I hardly got to touch this over the weekend but did manage to squeeze in the basic system for actor turn-order as well as input-controller player character, camera following, and just the quickest dirtiest A* I've ever cobbled together.

Edit: Also wanted to show off some of the palettes I've been putting together as I try to wrangle standards for palette colors so that UI will still work.

#gamedev #chron4

| 🌐 | 🙋‍ | @britown@blog.brianna.town

Feeling burned out on code this week so took a step back to use all the new tools and try to generate some assets. I get overwhelmed with pixel art but 14x14 tiles with 16 colors is comfortable enough that I can be happy with the aesthetic.

#gamedev #chron4 #pixelart

| 🌐 | 🙋‍ | @britown@blog.brianna.town

I've always had this pipe dream of being able to live-edit all assets in a game project while the game is running and I'm feeling really strong about the progress of this newest project!


Most/all of my personal side-project revolve around C/C++ desktop apps with homespun engines. It's usually as much a journeyman effort for learning more CS as it is a desire to make a game. A big part of solving the issue of finishing a game has to do with having good architecture with a good assets pipeline.

In this example we have:

  • The assets data-catalog is on the top left
  • A running game instance in the top right (can have multiple running in windows independently in the same exe)
  • A tile schema editor for map tiles in the bottom left
  • A homemade pixel image editor in the bottom right.

Any pixel edits to the graphics in the editor live-update anywhere they are used (in this case both the running game and the schema editor) giving you redundancy to test your edits. It also has perfect referential integrity so you never have to worry about your game crashing when an assert comes up missing.

I will have to come up with some thoughtful posts digging into the how's and why's of all of this but the main concepts at play here are:

  • “C-Style” C++
  • Generated reflection code from struct definitions
  • Generic recursive file format
  • Live++
  • Dear ImGui

#gamedev #chron4 #cpp #imgui

| 🌐 | 🙋‍ | @britown@blog.brianna.town