Generating NPC stats

When my players go looking for henchmen higher than level 0 to recruit, I like to start by rolling randomly for the class (and then using the templates from the player’s companion). The problem I run into is that when I go to roll stats, there’s no guarantee I’ll get at least 1 stat block that makes sense for a particular class. I’ve been trying to fudge this by using chantofwaves’ stat roller for 10 or 15 stat blocks and using that to fill out an entire months worth of henchmen, but I’m beginning to realize that this is creating a few too many henches with impressive stats, which the PCs naturally gravitate towards.

So, to my question: does anyone have any good ideas for randomly generating a set of stats that, while a little bit more balanced and closer to the average, make more sense for a particular class? I may eventually try to math something out, but I wanted to see if anyone has already “solved” this problem.

Some ideas for solutions:

  1. Roll 3d6 six times and assign the scores in a way that makes sense.
  2. Don’t let your players know henchmens’ stats (at all, or until they’ve been hired - the former seems bothersome in play, the latter seems like common sense).
  3. Don’t bother giving henchmen ability scores; assume they’re average in everything. (Or that they’re at +1 or +2 in one prime requisite, whatever).
  4. Use Excel or OpenOffice Calc to create a ton of stat lines (or just 10-20), and assign classes and adjust the values (at the usual 2:1 for prime requisites only ratio), then take out the line when the stats are used for a NPC/henchman.

I use 4. myself, with OOC. I’ve got a file saved with a line of six cells, each with the script =RANDBETWEEN(1;6)+RANDBETWEEN(1;6)+RANDBETWEEN(1;6) in it, and I just paste that over and over when I want to create a pile of stats. If I want the results a bit above average, I paste them in groups of five and take the best 3 lines out of the 5 (you can easily add a sum function to the end of the line you copy-paste to see the total of the scores).

Ignore those tags, obviously - forgot to choose that pesky Filtered HTML…

hmmmm, i wonder if there would be an easy set of logic that i could put on that excel sheet to say “these stats are best for fighter, these for assassin, this one for elven nightblade, etc. etc.”. Although now i’m imagining the table in my head and I can see this rabbit hole going much deeper than it probably should :stuck_out_tongue:

I’ve just been eyeballing them and going a bit randomly. Really, most sets of stats can work very well for many, many classes: the prime requisites are the main thing, and it’s usually very easy to lower a few ability scores by 2 to raise the prime requisite to 16. (Harder with two.) Plus I think sometimes you should get smart fighters, dextrous mages, etc.

But you could definitely create some sort of set of checks on the ability scores that gives you a list of classes they’d suit well. I just haven’t felt it worth my time.

Hmm… this would not be a hard thing to add to my henchman generator. Currently I generate n sets of stats and assign each a ‘reasonable’ class; I could instead generate statblocks until I get one of class x. Will take a look at adding this functionality when I get home from work.

i’m not sure i’ve seen your utility. where do you host it?

also, do you mind sharing what your criteria for picking classes is?

I just roll the stats in order, and then, if I feel like it, I’ll move their highest stat to their prime requisite. Or not. Sometimes you just get crappy NPCs.

My ACKS scripts are at . The ones of interest to you are, which depends on,,, and (minimally for this purpose) the classes file. It’s all command-line, python 2.7, and tested on linux, but it should work on windows or mac as well.

As for class selection, I do something like this:

  • Generate stats
  • For each class (as described in the classes file), generate a number of ‘shares’ based on how high your prime reqs are for that class.
  • Sum all shares of classes for which you are qualified (prime reqs and minstats all >= 9), and choose in a weighted random fashion.

So a character with Str 18, Int 9, and all other stats 8 might receive 10 shares towards Fighter for his +10% req, 1 share towards Mage for his 9, and 1 share towards Spellsword (currently it uses the minimum of your stats to determine share values for multi-req classes, IIRC, so min of 10 and 1 is 1). He’d have a 5/6 chance of being a fighter and a 1/12 chance of being either a mage of a spellsword. In practice the function to assign share weights is somewhat more complicated (which is to say, I’ve forgotten exactly how it works since I wrote it), but that’s sort of the general gist of it and the share amounts it generates usually strike a balance between “everyone always does what they’re best suited for” and “oh man that was a terrible class choice”.

For example, I just generated 5 9th-level thieves (with the command ./ -n 5 -c ./classes -f Thief -l 9) and here’s what I got (where the bracketed values are Str Int Wis Dex Con Cha):
[13, 11, 14, 13, 8, 10], L9 Thief, HP: 13
[10, 8, 6, 10, 3, 14], L9 Thief, HP: 12
[11, 8, 9, 15, 14, 12], L9 Thief, HP: 30
[10, 11, 11, 12, 9, 5], L9 Thief, HP: 21
[14, 11, 12, 15, 8, 12], L9 Thief, HP: 14

And those are all reasonablish thief statblocks (3 Con though, man).

Wow! I don’t know anything about Linux or Python but I’ll find out to use these apps!

ok, I remember now. I’ve had your git page open for a while, but I’m a .NET man and I don’t code much off-hours so I’ve been avoiding futzing with python. That being said, reading what you just wrote has me seriously reconsidering my position! I think your shares method is pretty spot on, now that you’ve explained it, so I think I’ll be working off of that.

Here’s what I use for all classed NPCs:

Ability Scores:
NPCs start with Average Joe/Jane array (12,11,11,10,10,9), arranged to suit.
Roll d20 for each of the NPCs prime requisites. If the result is equal to or less than the NPC’s level, then that ability has at least a +1 bonus (1-3 13, 4-5 14, 6 15).
Roll d20 for each of the NPC’s ability scores that have a +1 bonus. If the result is equal to or less than the NPCs level, then that ability has at least a +2 bonus (1-4 16, 5-6 17).
Roll d20 for each of the NPC’s ability scores that have a +2 bonus. If the result is equal to or less than the NPCs level, then that ability score is 18.

Magic Items:
Roll d20 for each category (Scroll, Potion, Rod/Staff/Wand, Sword, Misc. Weapon, Armor, Ring, Misc. Magic Item). For each category for which the die result is equal to or less than the NPC’s level, generate a random magic item of that type. If the NPC can use the item generated, then they have it.

I also use a variation of Telecanter’s Hireling Spur to flesh them out, which can modify one other ability score.

In my experience, the player’s have been more interested in having henchmen with useful proficiencies than one’s with exceptional stats.

These are amazing! How could we work with you to make these web-enabled tools on our site?!

That’s really sharp. It’s best to keep it a bit fuzzy so you get a high-INT elf that’d rather have been a dentist (fighter).

Glad you think so! Unfortunately I don’t know the first thing about web development. Koewn and I were talking about working up a simple (ugly) CGI-style frontend for these sort of tools, but nothing has come of it yet. Let me know who I need to talk to and what needs done to make them usable with’s setup in a manner similar to the treasure generator (which appears to be down? It’s throwing “PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table ‘autarch.auttools_treasure_types’ doesn’t exist: SELECT * FROM auttools_treasure_types; Array ( ) in TreasureGenerator->load_data() (line 117 of /home/web/drupal/public_html/sites/all/modules/acks_treasure/”)

It just seemed like a logical system. And yeah, I mainly chose python for these because they were intended as knock-em-out-in-an-afternoon scripts written in my off time. Definitely not production-grade… (Also if you’re going to go read the shares implementation in, I must warn you that I did something rather foolish with entirely too many lambdas in that part of the code)

Those do happen, but not usually with 18s. Looking back at last campaign, [8, 15, 13, 10, 15, 9] ended up as a bladedancer, for example.

Probably overkill to go learn linux just for those. The windows python 2.7.6 installers at should probably work, and python’s pretty OS-neutral for the most part (the only thing I can think of going wrong would be path separators ("/" vs “” in directories, and the only thing that might break with that will be some of the default arguments). Let me know if you run into difficulty and I will attempt to assist.

Hi all,

I use several Python scripts to generate NPCs as well. Basically, I go two ways: The first way involves rolling the stats and then choosing a class based on the highest 1 or 2. The second way involves choosing a class, rolling stats and then bumping the prime stats up to a minimum of 12. I also have a minimum threshold that can be set for NPCs. Minor = minimum 50 points in all stats, Adventurer = minimum 60 points in all stats, Hero = minimum 70 points in all stats.

Indeed. Start of semester threw me off my stride.

What I can do really depends on how tied into the Drupal infrastructure Autarch wants it to be; I can pop out a Perl/CGI thing that’ll handle the front end for the scripts, but it may not necessarily be pretty, or have the look and feel of the rest of the site.

Linux/Unix admin by trade, I only lightly brush up against various web techs as I need to troubleshoot them for other people. (and the treasure generator error makes me itch)