Larg(ish) combats take two: Off-screen fights

In my Council of Thieves game, the PCs lead a group of lower level rebels. They’ve used them throughout the AP, sending them off on side missions, using them to make up for skill gaps, or bringing them along when the PCs have a large combat.

Recently, the group decided to use them as a distraction. The rebels would keep part of the guard engaged while the main group orchestrated a jailbreak. Due to the layout of the prison, the players wouldn’t be able to directly communicate with the rebels, meaning I would have to simulate what was going on above ground.

True, I could have hand-waved it, but I try to avoid that when it comes to plans like this. Also, the dev in me can’t resist a chance to whip up a script to make things interesting.

The simulation

At first, I thought about writing up something that would take into account hit points, AC, chances of hitting, damage, etc. I decided that was going to be too high effort, especially for a single combat.

Instead, I went with a ‘wound’ system (Note: not the alternative rules from Unchained). I figured a wound would represent a bit of fortitude or luck, like access to healing or a chunk of hit points. Losing a wound point would be akin to getting hit and not having a potion / healer on hand or getting hit especially hard. Running out of wounds would mean your luck had run out.

Combat would work like this:

  • For every two levels an NPC has, they would get one ‘wound’ level. This would be the max number of wounds they can take.
  • Every round, half a wound would be dealt to a random NPC on each side.
  • Once an NPC’s taken their max number of wounds, they are out of the combat and can’t receive more wounds.

For this combat, I decided that being out of wounds didn’t mean the NPC was dead: They’re just unable to fight anymore. Anyone who was at zero wounds would have some sort of injury that would require a heal check and time as well as some magical healing to overcome (like a bone fracture, a bruised rib, a deep wound, etc). While a bit harsh, I wanted to simulate what it was like to be in a combat where you can’t run when it seems dangerous: You have to stick around until you can’t possibly fight anymore.

I also decided that the rebels would scatter as soon as they were down by half. If they waited longer, they may not have enough hands to help the seriously wounded escape with them. In my simulations, this took somewhere between 25 and 30 rounds. I liked that range because it would make things interesting for the jailbreak team. If they took too much time, they might have a second wave of guards descending upon them. If they moved quickly, they might be able to completely take over the prison and guard house.

I decided that the guards wouldn’t retreat as quickly. After all, they’re right by their stronghold, and the ones in the street are working off the assumption that they have back-up coming any second now.

Because it was possible that the main party might come upstairs and clean house, I decided that I’d simplify combat for those left standing. Rather than worrying about hit points, I’d just worry about landing hits. One hit means dealing half a wound (or maybe a full wound if the damage was high enough). When it comes to mopping up, I don’t generally like to split hairs.

The script

In theory, I could have just a rolled a die every turn and kept track of wounds on paper. I wanted to be able to run the simulation a bunch of times, though. This is cumbersome if doing it with pen and die, but trivial when running code. Running the script a bunch of times helped me adjust the numbers so that the fight was interesting without being impossible.

In fact, the multiple simulations are why half a wound is dealt out rather than a full wound: It made the numbers work how I wanted. It also helped me brainstorm how I might interpret the end results.

This script requires Python 3. Also, you need two CSV files, which I included examples of in the repo. Each line is the NPC’s name, how many wound points they have, and how many wounds they start the combat with (generally zero).

[Script] – [CSV file 1] – [CSV file 2]

How’d it go?

When it came time for the combat, I warned the players that I had a script going that would be simulating the battle above, so they should keep that in mind. I felt it was fair to give them a heads up, since I’d been hand-waving much of the off-screen activity of the rebels.

When the combat started, I fired up the script, advancing it at the end of each round. The players mowed through the combat downstairs, and around round 17 ran upstairs and mopped up the guards the rebels had been fighting. By that point, there were two wounded rebels.

Because they knew time was of the essence, I felt like the players pulled out all the stops to end the combat quickly. At the start of the combat, they had no idea if my script was going to hurt people or outright kill them, which seemed fair. They’d never been in this sort of combat with the younger rebels before, so they couldn’t really predict the outcome.

Afterwards, I explained the mechanics of the script. I felt that the PCs could get a rundown from the rebels as to how it went, so a bit of meta-gaming was fine. They didn’t push back on the consequences, and accepted that the rebels that were wounded were going to be down for a day or two. Heck, one even pointed out that one should be out longer!

Future plans for the script

The script was written for a specific combat, so I knew the damage flying back and forth would be somewhat close. In the future, though, I may want to vary the damage output, making one group weaker or stronger.

I also may want the damage dealt to shift as the groups change. Because my simulations showed the groups always being about the same size, I didn’t worry about this, but I could see a future combat where this might vary quite a bit.

Finally, I may have make the script lethal, especially if my players decide to overthrow all of Cheliax…

Leave a comment