code, game, github

Ufora: Generating a Population of Commoners

Recently, I’ve become interested in the so-called “funnel method” of character creation in the RPG Dungeon Crawl Classics. The funnel is a process of deriving your 1st-level character by running a handful of 0-level commoners through a dungeon and seeing who comes out the other side alive. A group of players would need to funnel 20-30 commoners through a dungeon to generate a standard adventuring party.

I also came across this interesting twitter thread from Sigrid Ellis concerning how many food-producing “commoners” a village needs to have to support a single swordsman, librarian, clergy, locksmith (or D&D character if you will).

So in addition to the 20-30 commoners you’d need to funnel to create your adventuring party, you’d also need 400-600 commoners in a village to have enough infrastructure to support the creation of food, crafts, clothing, weapons, armor, supplies, etc. This number seems to jibe well with information found in Notes on Medieval Population Geography, Medieval Demographics Made Easy, and other scholarly sources. There were anywhere from 5-30 extended families (at a 90% marriage rate) in each village (let’s say 3d12) with a fertility rate of 4-8 children and a childhood mortality rate of roughly 25%. Using these numbers generates a very plausibly sized village of 200-800 commoners.

Let’s take the funnel method up a notch and generate every single commoner in a village large enough to support an adventuring party.

You can view the code here

If you’d like to try it out, make sure you have Node.js installed. npm install the project then run node village inside the project directory.

I took the opposite approach as the Medieval Demographics site for generating populations. Instead of starting with a kingdom and working down, I started by generating people’s names and working up. It generates a name, then a 3d6 based stat block with hit points and occupation, then a family of a husband/wife plus children, then a kinship group of grandparents and their children and grandchildren plus inlaws, then 5d12 of these kinship groups living in the same area.

Here’s a somewhat small sample village of 320 commoners.

This village, the village of Janwynne (a name also randomly generated), should theoretically support an adventuring party of 6 characters.

Next steps and ideas:

  • make the occupations more realistic to the geography. E.g. more fishers in coastal areas, more miners in mountain areas.
  • Have genetic lineages through populations by making attributes heritable. E.g. child inherits intelligence score from mother, strength from father.
  • Generate physical characteristics
  • Have inlaws in one family come from other kinship groups in the village. Currently, inlaws are just outsiders
  • Simulate battles to actually funnel these commoners into their hero roles. Something like the python-based D&D Battler would work well for this — or perhaps a node rewrite of the battler to work with the village generator.
  • Use the villages to form sections of towns. Use those towns to generate districts within cities.
A guide to the files

dice.js – a simple dice roller for standard polyhedral dice. dice.d6() rolls a six-sided die. dice.d12() rolls a twelve-sided, etc.

namer.js – accepts two parameters, gender and surname, both can be undefined. Provide ‘male’ or ‘female’ to specify a gender and a specific surname. Or leave either black to have it randomize. Chooses first names for boys and girls plus surnames from a huge list of fantasy sounding names.

character.js – Also takes gender and surname as a parameter and returns a character object with name, attributes rolled as straight 3d6s, computed hp, and mod values

family.js – Takes father’s name and mother’s name as parameters, calculates number of children, then generates characters for each child. Returns valid json of children

kin.js – Generates a random grandfather and grandmother, computes family for them, marries off their children to outsider inlaws, generates the next generation of children, and can potentially marry them off as well (disabled by default, leaving the grandkids as children)

village.js – Rolls 3d12 and generates that number of kin groups for an entire village

Finally, a note about gender and traditional marriage roles. I followed a strictly male/female binary and man-woman pair bonding since this usually produces generations of children — and it’s also less complicated to simulate. This is not to discourage non-binary gender roles or non-traditional marriage. There are also many other circumstances in which children were born and raised, such as through infidelity, rape, orphaning, etc. If you’d like to add more non-traditional forms, I am very open to pull requests!