December 29, 2022

Combat Simulation I

My party has just run through their first combat. It went well, especially considering this was their first combat in Authentic D&D. Over the holiday, I had some time to think about that combat, and whether or not I could use any algorithms to offload any of the work in running the NPCs, particularly dumb ones with simple motivations. In any case, an exploration of that project is sure to be enlightening in itself.

I'll make the code available here.

Another advantage of a system like this is that we can capture a combat in a repeatable (and version-controllable) way. At least to a degree: the beauty of D&D is that a rule system never fully captures the range of human ingenuity, and so to some extent the rule system must always be fluidly updated to match feedback from actual play.

We can break combat action at its simplest level down into:

  • move somewhere
  • attack something
  • interact with something

These actions can be done more than once per turn in any order, depending on the available action points and circumstances, with the goal of breaking the enemy's will through death or morale collapse.

Every action taken by an active participant in the combat should be in service of this goal. Participants who are more intelligent or better trained will select better options than others. [we can also invert this selection function to simulate the actions of PCs, who will choose the worst option in any possible circumstance]

I'll start by tackling movement, which I thought would be the easiest of the three actions. That turned out to not bode well for the others.

Let's consider a battlemap with no obstacles and two actors. We'll play with the actor on the right, giving it 3 AP and the ability to move according to the Authentic D&D rules. Without considering other constraints, this means that for each AP, the actor can move between 1 and 8 hexes in a straight line. This generates the following possibility space:

Movement possibilities: darker hexes mean more possible paths to reach that hex

However, there are several constraints we must add, which proved to be non-trivial to program. The actor can only change speed once, they can only rotate left or right 60$^\circ$ at the end of each AP, and they can't move through obstacles (in this case, that is only the other actor). That reduces our space to the following:

Possibility space with constraints added

The space is still mostly symmetrical, but we can also see the disruption caused by the presence of another actor. Keep in mind also that this is the possibility space for exactly 3 AP; in many cases our actor would only want to move one or two AP, or perhaps even look ahead multiple turns.

Movement in 1 AP, darker hexes are a higher stride

For example, if the actor on the right wants to attack the actor on the left, they will move at stride 2 for 2 hexes to enter melee and then have 2 AP left to attack. In this way, we can build up a desirability score for each possible hex, and take an optimal or near-optimal combination of actions as a result.

I'm not quite done with movement yet. Right now, we only avoid obstacles of other actors. I'll need to do some thinking on how to add simple static obstacles such as walls or buildings.

5 comments:

  1. I think that you've let what was a simplification turn into a complication here by constraining yourself to 60-degree angles. Every hex within the actor's radius of operation has the same number of ways to reach it when you ignore making 60-degree directional increments and contain the simplification to landing within a hex at the end of movement. Those unreachable triangles around the fringe ought not to be there. I understand that you are trying to replicate the manual movement rules in which direction may only be specified in 60-degree increments, but that's a simplification intended to make movement easily calculated by counting hexes. Why endure that constraint in a program when you can instantly determine the final hex the actor could reach in any direction instead?

    ReplyDelete
    Replies
    1. Sterling, that's an excellent point.

      The reason I began with those constraints is that I intended (as a first step, anyway) to use this as an aid for physical game-running. Obstacle conditions (which I begin to look at in Monday's scheduled post) are checked for on a hex basis, not a pixel one. Maybe this will turn out to be a bad choice. Or maybe it will turn out that the original system can be improved.

      But it should be trivial later on to modify the path algorithm to find the necessary steps to an arbitrary hex within range. Thanks for drawing my attention to it.

      Delete
  2. You might want to take a look at the combat simulator done by Dan of deltas dnd for oed. Different rulesystem(basically original dnd) but his methods might lead you somewhere. I believe he puts everything on github

    ReplyDelete
    Replies
    1. I think I remember reading his stuff a long time ago. Thanks for the reminder.

      Delete
  3. There is also https://github.com/matteoferla/DnD-battler

    ReplyDelete