Biblyon the Great

This zine is dedicated to articles about the fantasy role-playing game Gods & Monsters, and other random musings.

Gods & Monsters Fantasy Role-Playing

Beyond here lie dragons

Flashing Blades: Character Calculation Perl Script

Jerry Stratton, July 9, 2025

I ran Flashing Blades again this year at North Texas, and it required making a bunch of custom character sheets. There are a handful of calculations that are the same calculation for every Flashing Blades character: hit points, encumbrance, and initial skill points. There’s also the combat modifier, which may or may not be different for firearms and crossbows. And characters that have the right combination of Strategy skill and rank have a chance for Brilliant Maneuvers.

Once you start making skill choices Flashing Blades is difficult to program for, but it is very helpful to get those five calculations done automatically to avoid typos. While none of those calculations are difficult, it’s always easy to skip a line on a table or misread a column when doing multiple characters in succession.

I’ve designed the script to use a text file of attributes, using a simple Markdown headline to title each character. Just point the script to that file—or multiple files—and either get all of the characters or just ones that match a search term. Here’s an example of some characters I’ll be using:

  • # Captain J. Tiberius Kirk
  • Strength: 12
  • Dexterity: 10
  • Endurance: 14
  • Wit: 13
  • Charm: 15
  • Luck: 12
  • # Chief Science Officer Spock
  • Strength: 16
  • Dexterity: 15
  • Endurance: 15
  • Wit: 17
  • Charm: 8
  • Luck: 9

If I type ~/bin/flashing Characters/Enterprise.txt Kirk I get:

  • # Captain J. Tiberius Kirk
  • Strength: 12
  • Dexterity: 10
  • Endurance: 14
  • Wit: 13
  • Charm: 15
  • Luck: 12
  • Encumbrance: 12
  • Hit points: 13
  • Skill points: 11
  • Martial adjustment: 1
  • Brilliant Maneuver (requires Strategy): 5

I initially wrote the script to help me avoid mistakes on the Enterprise characters for l’Entreprenante l’Entreprenante but once I had the script it made sense to have it randomly create the French characters the adventure needs. Unlike the above examples, the French sailors aren’t based on “real” fictional characters so it was easier just to generate them randomly at the same time as doing the calculations. Rolling attributes is easy enough, but once the attributes are rolled there’s also determining whether the character has an average, above average, or below average height and build, which itself may or may not affect the character’s attributes. That’s another table lookup, which makes it a good choice for rolling into a script to avoid mistakes.

So I added the --new switch to the script. You can give that switch some text and the script will use that text as the name of the character. Otherwise, it will use the name “Jean Dupont”. The script always provides a headline to make copying and pasting the output easier.

  • % ~/bin/flashing --new
  • # Jean Dupont
  • Strength: 8
  • Dexterity: 17
  • Endurance: 10
  • Wit: 11
  • Charm: 11
  • Luck: 15
  • Body: Short and thin; Dexterity was increased by 2, Strength was decreased by 1.
  • Encumbrance: 10
  • Hit points: 11
  • Skill points: 11
  • Martial adjustment: 3
  • Brilliant Maneuver (requires Strategy): 4

It’s a simple enough script. It mostly runs linearly through the calculations. It recreates the “table” of heights and builds via code, and the progression of bonuses as a simple array. Fortunately, while the bonuses and penalties change depending on what’s being calculated, the attribute thresholds at which the numbers change is the same in each case on each table.

That is, while Strength goes from -2, to -1, to 0, to 1, 3, and then 4, for calculating Encumbrance; and Endurance goes from -1, 0, 0, 1, 1, 2 for that calculation, both change from one modifier to the next at the same attribute number. The breakpoints are at an attribute of 6, 9, 12, 15, and 18.

This means that I’m able to calculate hit points, encumbrance, and skill points using the same subroutine by handing that subroutine the attribute and its list of modifiers:

  • # calculate hit points
  • my $strength = getValue('Strength', -1, 0, 0, 1, 1, 2);
  • my $endurance = getValue('Endurance', -2, -1, 0, 2, 3, 4);
  • my $luck = getValue('Luck', -1, 0, 0, 0, 1, 1);
  • my $hp = 10+$strength+$endurance+$luck;
  • # calculate encumbrance
  • $strength = getValue('Strength', -2, -1, 0, 1, 3, 4);
  • $endurance = getValue('Endurance', -1, 0, 0, 1, 1, 2);
  • my $dexterity = getValue('Dexterity', -1, 0, 0, 0, 1, 1);
  • my $encumbrance = 10+$strength+$endurance+$dexterity;
  • # calculate skill points
  • my $wit = getValue('Wit', -2, -1, 0, 1, 2, 3);
  • my $skills = 10+$wit+$luck;

And the getValue subroutine is:

[toggle code]

  • # convert attribute into it's value on a table
  • sub getValue {
    • my $attribute = shift;
    • my @values = @_;
    • $attribute = $character{$attribute};
    • die("Attribute too low: $attribute\n") if $attribute < 3;
    • return $values[0] if $attribute < 6;
    • return $values[1] if $attribute < 9;
    • return $values[2] if $attribute < 12;
    • return $values[3] if $attribute < 15;
    • return $values[4] if $attribute < 18;
    • return $values[5];

If you want an experienced character, add “experienced” to the --new switch. This will use 4d6 to roll attributes instead of 3d6, throwing out the lowest of the dice in each case.

[toggle code]

  • # roll random 3d6
  • sub d6 {
    • return int(rand(6)+1);
  • }
  • sub rollAttribute {
    • my @stats = (d6(), d6(), d6());
    • if ($experienced) {
      • $stats[$#stats+1] = d6();
      • @stats = sort(@stats);
      • shift @stats;
    • }
    • return $stats[0] + $stats[1] + $stats[2];
  • }

There’s a bit of a trick in rollAttribute. It “rolls” a d6 three times and puts the result in an array immediately. If it’s making an experienced character, it then adds a fourth die roll to the end of the array. It sorts the results so that the lowest number is first. And then it shifts the first number off of the array, leaving only the three highest results.

  • % ~/bin/flashing --new experienced
  • # Jean Dupont
  • Strength: 19
  • Dexterity: 13
  • Endurance: 18
  • Wit: 18
  • Charm: 14
  • Luck: 15
  • Body: Tall and stocky; Strength was increased by 2, Endurance by 1, and Dexterity decreased by 1.
  • Encumbrance: 16
  • Hit points: 17
  • Skill points: 14
  • Martial adjustment: 5 (4 crossbows and firearms)
  • Brilliant Maneuver (requires Strategy): 6

With a 19 strength, an 18 endurance, and an 18 wit, that might be a little too experienced…

The syntax of the command is:

flashing[--help] [files [searchtext]] [--new [experienced] [name]]
files [text]:calculate data from files, matching names against text
--help:print this help text
--new[experienced] [name]: create new character with name, optionally with higher stats

The script doesn’t create complete characters. But it does create the character up to the point that a human needs to take over. While it would be technically possible to fully create random rogues, soldiers, gentlemen, and nobles from the tables in Flashing Blades you would probably have to spend as much time selecting results appropriate for whatever game you’re running as to make it not worth the effort.

In this particular case, I would have had to somehow set the script to create appropriate Captains, First Mates, Chief Gunners, and so on. Further, this part of character creation is enjoyable. So I saw no reason to turn it over to the computer.

Enjoy! (Zip file, 2.4 KB)

In response to Dueling aid for Flashing Blades: Dueling is one of the many fun aspects of the Flashing Blades RPG. This dueling aid will help players choose their opponent, their two actions, and their parrying guess.

  1. <- Flashing Blades Romp