Roguelike Games created by Thomas Biskup, the Creator of ADOM

Tag: combat system

Realms of Ancardia (Weekly Update 8)

It’s vacation time… so for the next couple of weeks things will slow down quite a bit. My current goal is to start having something that resembles a game… e.g. something that allows you to do a few things.

But I expect serious work on the game to commence starting with the update #9 on the 6th of August. In the meantime we enjoy paradise and regroup creative energies…

A little work still got done before vacation time started though:

Settlements are a big focus in Realms of Ancardia and I want them to feel extremely detailed and vivid. Thus the first activity opportunities will focus on settlements. Since we need to test the combat system this will probably bring you into contact with local law enforcement. Which brings me to the primary focus this week:

Law enforcement generation

Realms of Ancardia already has a framework for crime and punishment. But so far I did not spent any time thinking about the makeup of local law enforcement in settlements.

This could be anything from a single old sheriff in some hurthling hamlet to a legion of undead guards led by death knight generals in a dark metropolis ruled by an undead necromancer (and lots of other setups inbetween).

I devised a complex system to determine the types of beings used in settlement watches and militia, determine their training level, morale, composition and equipment quality. All this factors in settlement sizes, dominant races, alignment and naturally government types.

As a side effect more than 50 new monster types were added (although the stats still need to be worked out).

Total size of the codebase after this week

  • 37,361 LOC in 625 files for the actual Realms of Ancardia game
  • 24,280 LOC in 408 files in my own underlying TBRLAPI framework library supporting my most recent roguelike games
  • plus extra external configuration files, images, tilemaps, audio files, etc.

The running total is available here.

State of our internal ticket system

We use YouTrack to manage ideas and bugs that pop up. The listings are by no means complete – it’s more of a “don’t eventually forget to fix this bug / add that amazing feature” pipeline that gives a little structure to our development process without turning it into a managed project 😉

  • 132 open issues in total
  • 56 closed issues in total

Realms of Ancardia (Weekly Update 7)

This week was focussed on finally getting a little game ready to be played. For many things it’s still too early but a lot of basics needed to be finished and/or improved.

Soon vacation time starts and during the summer holiday I probably will work a lot less (if at all) on the game. So weekly updates 8, 9 and 10 probably will be much shorter – if they happen at all (or they will happen later). Should there be a brief period of silence, fret not – regular updates will return.

Random talent category selection improved

If you select random talent category selection during character creation the game now tries to create a variety of more sensible builds for the character. There are certain primary talent categories (arcane, combat, thievery and religion) and all the others are marked as secondary. In most cases the game will try to distribute the available talent points to a limited number of categories. It also ensures that (in most cased) one or more of them are selected from primary categories.

Skill selection implemented

Random skill selection was implemented. To achieve this a lot of things had to be done:

  • Skills had to be associated with talent categories (e.g. grouping all knowledge skills, all combat skills, etc.). Currently we have a total of 80 skills in 10 talent categories.
  • An experience cost system had to be implemented mapping initial skill points to levels.
  • Weapon types had to be mapped to combat skills.
  • Lots of layout issues were wrestled.

Skill selection tries to be smart:

  • Each category has some primary (more important) skills that are handled preferentially.
  • Available weapons and armor are taken into account to select the most useful combat skills.
  • Generic skill points from the ‘Skills’ category are distributed on more important skills.

Skills now are distributed across three tabs (yet unstyled):

Combat skills
Primary skills
Secondary skills

Started work on the extended combat system

If you look at the combat statistics for Realms of Ancardia in their current state you will notice more values than in ADOM:

  • DV: Dodge (or defense) value. I can’t decide on naming. This number needs to be surpassed by the attack roll in order to hit a being.
  • PV: Protection value. The amount of damage absorbed by armor, tough skin, magic or whatever whenever a being is hit by a damaging attack.
  • #P: The number of parries per combat turn. Each time an attack hits the defender gets a chance to parry the blow for as long as he still has parry attempts available. Note that you can’t parry blows from attackers two size categories larger than the defender. Usually weapons grant one parry attempt (rapiers grant two). High weapon skills can modify this.
  • PB: The parry bonus. A bonus to the roll to deflect an attack. If the parry roll is equal to or greater than the attack roll is blocked.
  • #B: The number of block attempts per turn. These are granted by shields but rules-wise work like parries. Small shields grant one block attempt per turn, medium shields grant two and large shields grant three.
  • BB: The block bonus. Larger shields grant higher bonusses. As well as high shield skills, magic, talents, etc.
  • H: Hit points. You are dead when they drop to zero.
  • P: Power points. Energy used to charge arcane spells.
  • F: Faith points. Like power points. But for miracles. Godly magic is intended to be quite different from arcane magic in Realms of Ancardia.

Damage indicator added

We now have a nicely pulsing frame for the screen when the PC gets damaged. The frame gets thicker and thicker the more wounded the PC becomes. And the rate of pulsing increases as damage gets more serious.

Item statistics in the inventory

I spent way more time than I had planned or expected on displaying items in the inventory. Realms of Ancardia is pretty close to ADOM in the amount of statistics structurally (and has even more details like damage types, different but cumulative damage ratings and some other details) and it took quite a while to get the display of item statistics into a somewhat decent form. Here is a sample:

Equipment view
Backpack view: Here more work is open (e.g. item stacking, grouping, …)

The bad thing is that I will have to completely refactor this because I noticed too late that the current approach prevents me from using that data in messages. Doh!

There are also some details to be fixed (e.g. the coloring with the weapon damage entry). And graphical glitz will eventually be added. Also more statistics (like e.g. seeing the full combat values for the stuff you equipped, etc.)

Character creation modifier infrastructure

I created infrastructure in order to allow subtle and less subtle character (or game state) modifications during character generation. Currently this is being used for

  • handling hurthling special starting conditions
  • ensuring that mist elves have all-mithril equipment
  • very religious characters have guaranteed blessed equipment

In the future the same infrastructure will be used to e.g. handle special starting conditions due to date circumstances and other factors.

Time wasted on sucky Apple Silicon support

Apple really fucks up many great projects with its Apple Silicon move. Despite Apple Silicon being great. But so many good libraries simple don’t work because the hard-pressed communities spending their time, love and energy on these projects seem to be stretched too far by Apple Silicon requirements.

Our project was hit by the fact that LibVLC (at least to my knowledge) does not have any working support for arm64. At least I couldn’t get it to run after spending many hours trying to get this fixed.

As a consequence of my switch to Apple Silicon for the Apple version of Realms of Ancardia we no longer can play videos. Which sucks.

This caused me to switch to SkiaSharp as my new framework for video display. For now this seems to work (fingers crossed).

And Death rejoices…

Character generation is (mostly) complete

Except for some minor details (beautification, more starting equipment, saving defaults) character generation now is complete. It has (for now) four modes (random/deterministic world, random/deterministic player character) and you can select race, gender and talent priorities. Specific skills and starting equipment are selected by the game. Also the character generation screen has become a lot more interactive and smarter…

Character generation screen for an aspiring dwarven hero

Miscellaneous minor changes and additions

  • The skills tab on the ‘i’nformation dialog was split into “Combat skills”, “Primary skills” and “Secondary skills” as we ran out of room trying to put everything into one tab.
  • Combat skills now provide a lot of extra infos.
  • Added seven new skill definitions (climbing, mountaineering, consecration, compel undead, artificing, sacrifice, summoning).
  • Items now can be blessed, uncursed or cursed.
  • Three new items have been added.
  • The keys 0-5 now can be used to instantly alter talent category levels during character generation.
  • We now have functionality for string input (e.g. names).
  • The inventory and back now show more detailed item descriptions.
  • Fixed various small bugs.
  • Added a number of missing translations.
  • Krys designed tons of great graphical enhancements and detail improvements and I yet need to find the time to add them all. Our issue tracker (see below) is filled with them. For now we have decided to add a little more gameplay to see how certain things will work and stabilize before doing a grand graphical update development sprint (probably: several sprints).

Total size of the codebase after this week

  • 36,186 LOC in 615 files for the actual Realms of Ancardia game
  • 24,280 LOC in 408 files in my own underlying TBRLAPI framework library supporting my most recent roguelike games
  • plus extra external configuration files, images, tilemaps, audio files, etc.

The running total is available here.

State of our internal ticket system

We use YouTrack to manage ideas and bugs that pop up. The listings are by no means complete – it’s more of a “don’t eventually forget to fix this bug / add that amazing feature” pipeline that gives a little structure to our development process without turning it into a managed project 😉

  • 132 open issues in total
  • 56 closed issues in total

Realms of Ancardia (Weekly Update 2)

After week 1 went really well the focus of week 2 was to get an initial encounter and encounter battle map up and working. While doing that I tried to finish many loose ends in the Realms of Ancardia engine.

Encounter handling implemented

While I’m probably going to add tons of stuffs during further development a pretty strong combat encounter framework is now in place and work. Let me explain with our first example: Because I had lots of fun during the setup of the system to toy with our settlement generation system (which we needed because the surface world in the game is huge and contains hundreds of settlements ranging from small hamlets to huge metropolisses (is that a word?)) I decided that the first test case for a combat encounter would be attacking citizens (because why not – nobody said that Realms of Ancardia is against game for heroes only 😉 )

To be able to attack citizens the following things were on my implementation plan:

  • Citizens needed to walk around the city. CHECK. We already finished this last week.
  • Citizen encounters needed to be variable. For that I set up a so-called ReactiveEncounter on each street tile. Reactive encounters are activated as soon as the player character enters the given position. My SettlementInhabitantsEncounter has the sole task to monitor the flow of citizens (selecting crowd volumne and a dependent number of random settlement encounters chosen from a large table [well, the table will be eventually large, right now there is exactly one entry – an encounter with simple commoners]). CHECK. The SettlementInhabitantsEncounter also was finished last week. Now the fun started.
  • I had to set up an actual encounter:
    • Encounters in Realm of Ancardia are modal (while e.g. in ADOM you only could encounter single monsters per tile). An encounter in RoA can be anything from a single monster, a trap, a text, a feeling or an army lying in ambush (and everything in between).
    • An encounter needed a way to define beings and the options it entails.
    • The encounter with commoners is a passive encounter (meaning: the citizens ignore you unless you interact with them). So I needed to implement an encounter lifecycle (which now has four stages for four basic types of encounters). Passive encounters are phase four (phase 1 are reactive encounters, phase 2 are combat encounters, phase 3 are active encounters [that activate automatically] and phase 4 are passive encounters).
    • I also added that failing to solve an encounter in phase x can stop you from reaching encounters in phase (x + 1). So if e.g. there is a treasure encounter that is guarded by a dragon combat encounter you won’t be able to reach the treasure until you solve the dragon combat encounter (which most often probably means killing your opposition).
  • Encounter handling raised interesting detail questions:
    • If you encounter e.g. 8 commoners, attack them and kill 3 of them – what happens to the rest (answer: I implemented an encounter state management that keeps a tally of the opposition).
    • Initiating encounters can have recriminations. E.g. attacking commoners in the city will flag you for committing a crime (Assault).
  • Here new ideas spawned:
    • First of all I needed an API to add reactions and workflows to encounters. The basic framework now is there and as first examples I implemented OnDeath and OnAttack handlers.
    • Now that crimes were accounted for (affecting your reputation and activating the underlying criminal justice system) the unsolved question was: How does the settlement react to crimes?
    • So I came up with the idea for settlement events that could be posted to the settlement and would propagate from there throughout the settlement (or at least parts of it).
    • So I added a means for posting settlement events, the first being a CrimeOccurred settlement event.
    • After that was done I pondered event propagation and for Realms of Ancardia this is rather easy:
      • There are small settlements with scattered homes. Here I implemented a circular propagation where after each time frame the event spreads further outwards from its origin.
      • In larger settlements events actually spread following the streets.
      • It becomes interesting whenever an event reaches a special building (the non-boring buildings in settlements). Special buildings consume these events and react to them. So if e.g. a CrimeOccurred event reaches a CityWatchStation special building, this in return might spawn a city watch patrol that heads for the location of the crime. And eventually reaches it. When it reaches a raging combat encounter the guards actually might join. If you finish the fight before they reach you, they will track you (at least for a while).
    • Then it dawned on me that there could be more interesting mechanisms than just spreading events:
      • Realms of Ancardia has 21 government types (some of the more interesting being the Magocracy (being ruled by wizards), NecrocracyCouncil (a group of undead ruling the city), NecrocracyTyrant (a single undead ruler) or Theotechnocracy (being ruled by an actual [demi]god living in that settlement). It would make a lot of sense for these government forms to create different reactions to events:
        • A magocracy might react by casting spells at you (while you are still fighting in a totally different encounter) to punish you. Maybe with a little delay because they need to agree on a course of action first. And if they take too long they might summon some demons or elementals or blink dogs (depending on their alignment) to hunt you.
        • An undead tyrant might immediately summon undead from the ground that join the battle (and in general: if the crime is severe enough).
        • An undead council might summon a lot more undead that a single tyrant – but maybe they again need longer to react because they will have a discussion first.
        • A (demi)god ruling the settlement might send (un)holy guardians to the battle site… or whisk you away immediately… depending on his domains, power level, etc. If you are particularly dangerous to the settlement the (demi)god might even decide to appear and handle the issue by trying to cause divine massacre.
        • And so on and so forth. Even the more mundane government forms will have different troups, reaction times and so on and their disposal.
        • And we are just talking about violent crimes here.
      • So I implemented a SettlementEventPropagator pattern which depends on the type of goverment of the settlement and implements different strategies to react to events.
  • But back to the beginning: To attack citizens you need the option to do so. There is no “moving into enemies to initiate attacks” in the normal movement mode of Realms of Ancardia because each position in theory can hold an infinite number of encounters. And you can move through them (usually) for reasons I maybe will explain in some other post (if anyone cares). So I needed a system to offer variable options for interactions to the player (depending on the specific encounters). So I implemented a means for passive encounters to return a list of potential interactions.
  • Then I needed code to group these interactions (e.g. if there are ten different encounters you might be able to attack this in the first step is consolidated under a single “Attack” interaction and only when you choose that you get the list of ten potential targets to select the right one (and I’m still pondering if starting a fight on a settlement position immediately should draw all beings into that fight).
  • Interaction options needed lots of details:
    • Texts (all translated naturally).
    • Checks to see if they are available NOW (e.g. a ‘c’hat option should not pop up if the player is deaf).
      • Why BTW prompted a new sidetrek because I had not yet any states (like deaf, asleep, paralyzed, …) to beings.
      • And when I added state I also needed to add state arithmetics because state (like attribute scores and other data) is accumulated across innate values, equipment, skills, talents and other factors.
    • I had to add dynamic binding and unbinding of keyboard commands to represent the shortcuts to the interactions.
    • I needed grouping, sorting and filtering of options.
    • I had to create a simple initial dialog system to present sublists and select them.

And then this lead to…

Refactored the movement system

And I am still working on it and foresee another day or two of work with this. Previously most movement was faked – now there are the outlines of a complex movement routine which caused me more trouble than expect due to having to cope (depending on map type) either with abstract encounters or specific beings on a map.

C# generics are no little part of the challenges and I will continue to work on the movement system next week. Right now there are still broken code pieces and various bugs. But as they say: TANSTAAFL.

Combat encounter implementation started

This is one of the core components of the future game and as such probably will see fiddling and extensions over years to come while we add more and more detail. The basic idea is that once a combat is initiated you zoom into a combat map defined by the encounter type and environment (e.g. for fights in a settlement a map is derived from the surrounding streets and buildings). The enemies are placed on that map and a turn-based combat ensues.

The basics for this have been implemented although tons of details still are missing (inventory handling, other items, special effects, lots of details for the combat system and so on).

Here’s the video of the very first battle in Realms of Ancardia filmed:

There is a ton of stuff that needs improvement but I’m actually pretty proud of a number of things that already work in the background (like automated encounter roster management on the right side, automated crime management in the background, automated setup of various rules for executing the encounter and more).

All this needs a lot of fleshing out over the months and years to come but it’s a great start.

UI Details

Various small things happened, like the message log having a gradual fade out:

The sections to the right now have headlines:

Beings structured

Beings are the central data structure for any living, unliving or undead things (basically anything that kind of lives) in Realms of Ancardia. I wrestled for a long while on how to design them:

  • In ADOM all monsters are pretty primitive flat data structures full of special cases. And inventories have somehow been grafted onto that in a Frankenstein like architecture. Not really recommended anymore.
  • In Ultimate ADOM every being had (almost) the same structure and complexity. Mind-boggling complexity (remember amputating and grafting limbs as a feature?). Not really recommended anymore.
  • In Grog the player data structure and the monster data structure uses the same interface. But for monsters the underlying implementation is very very simple (almost ADOM-like, just better designed). Only for the player there are the special cases about inventories and stuff (Grog being very simple there actually is not much). Felt good and I still like it but it does not seem to do the planned complexity of Realms of Ancardia justice…
  • For Realms of Ancardia I for now differentiate three levels of detail:
    • Simple beings – basically just hard-coded statistics blocks like in ADOM (e.g. most animals and almost all standard monsters will use this)
    • Complex beings – basically almost everything in data that the player character also has (items, skills, talents, …). Reserved for henchmen, (some) rulers of settlements and very important NPCs.
    • Player Character (even more statistical details like number of moves, reputation in each settlement, etc.). Only for the player character.

Map tile meta data structured

For map tiles a lot of meta data exists:

  • Can the tile be accessed by any being?
  • What is the movement cost for moving to that tile?
  • Does it require special abilities to access?
  • What is it’s description?
  • Can it be damaged?
  • How much damage does it take to destroy the tile?
  • If the tile is destroyed what happens then? (and what is the replacement?)
  • etc.

While I’m not yet finished yet I have implemented the generic infrastructure for handling this meta data for our various map types (surface world map, settlement map, dungeon map, settlement encounter map so far).

Rumor system added

I have added the outline of a rumor system to the game. It needs more dynamic components for the future but I will fiddle with those aspects once I have implemented a dynamic quest generator at some point and various interactive story lines are in the game. For now these rumors can be part of a chat with other beings running through the game.

Actor system

Realms of Ancardia uses a pattern I first made up for JADE: Actors. Actor in this context is the term for something that happens at a specific point in time. The interface currently looks like this:

    public interface IActor : IStorable, IUnique
    {
        long GetActionPointInTime();

        void Act(IRNG rng);

        void ActAgainAfter(long time);
    }

All actors are managed in lists (one for beings/encounters per map, one for global events that take place at some point in the future).

I added a lot of infrastructure to make all beings actors, to find the next actor that is going to act, etc. This is the backbone of all interactivity in Realms of Ancardia and thus a pretty important architectural step.

Related to the encounter system the actor system is what makes all enemies / non-player characters in an encounter move, fight, flee, etc.

Goal system added

All beings in the game have an agenda and act accordingly to it (see actors above). To manifest a specific agenda each being has one or more goals (like flee, move randomly, kill enemy, …). When a being actor is allowed to act it uses the current goal to determine the specific course of action.

Goals are managed in a stack and can invalidate due to circumstances. Then the next lower goal becomes the current goal until no real agenda is left (coursing beings to just wander randomly until attacked, etc.).

Wilderness encounter architecture added

One of those sudden and unexpected sidetreks. Krys needed material for drawing monster tiles so I spent some time creating an architecture for our wilderness encounter system (which I wanted to tackle next anyways next week so that wilderness travel starts getting exciting).

I now have finished the general architecture for encounter tables and encounter setup and also defined a lot of stubs for specific encounters.

Talking now is possible

The basic infrastructure has been implemented and you can talk to normal people. The rumor system has been integrated. More architecture is needed for complex conversations but that’s future work.

Miscellaneous minor changes and fixes

  • I ported over the racial attribute modifiers from ADOM (with minimal changes).
  • The right hand sidebar now has dynamic categories and category headlines for better readability.
  • Encounter flags have been added for greater customization.
  • I have designed some parts of what I call “the saga system”. The idea here is that a number of complex storylines will run in the background, altering the world and potentially affecting the player. I have outlined the first such saga called “Rolf’s Saga”. The gist is that the storylines will mostly just require code of low to medium complexity and still create the impression of “huge things happening” (and not just impressions) thus making the world a lot more lively.
  • I had to do a major refactoring of my internal architecture both for maps and for beings/encounters the reason being that Realms of Ancardia has to levels of interaction: encounters (abstract high level) and beings (usually combat). This has a lot of technical advantages during implementation and hopefully also will feel nice (although it is not quite roguelike). As I started implementing the first type of combat encounter during this week suddenly all the infrastructure for actual beings needed to come to life and that required a number of changes that cost me about 1,5 days of design and implementation time. But now everything feels right 🙂 Important groundwork.
  • Refactoring of the time system to be more fine-grained. While last week we still worked with systems we now use ticks. One second has 1000 ticks. This gives us great leeway in determining the costs of actions (especially in combat) and the initiative order.
  • Committed crimes now are reported in the message log.
  • The right hand side statistics bar now shows some player statistics.
  • Added gender, race and name to the PC (currently purely random).
  • Added a name generator for being names (including shopkeepers and dragons as special cases).
  • Added infrastructure for enemies.
  • Krys has added a lot of stuff on the graphics but I was too busy to integrate it yet:
    • Animated main title image (it’s gorgeous)
    • Ideas for beautifying settlement encounter map tiles
    • A bold version of our font (I still need to see if and where we will be using this)

Total size of the codebase after this week

  • 24,516 LOC in 398 files for the actual Realms of Ancardia game
  • 19,012 LOC in 303 files in my own underlying TBRLAPI framework library supporting my most recent roguelike games
  • plus extra external configuration files, images, tilemaps, audio files, etc.

© 2025 My Roguelike Games

Theme by Anders NorenUp ↑