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
Biblyon, Highland
Wednesday, March 28, 1990
Jerry Stratton, Ed.
Command-line Die Square—Wednesday, June 27th, 2018
Skull d6

Is it any surprise that a die covered in skulls is biased?

Because Pythonista does not contain scipy, calculating chi-square values using it can have trouble on edge cases. This command-line script can run on data files created by the DieSquare mobile app, and uses scipy to make more reliable calculations.

Specify the DieSquare data file on the command line.

  • $ ~/bin/diesquare "Bronze d20.diesquare"
  • Degrees of freedom: 19.0 X-square: 20.6
  • p-value: 0.359317617197
  • d20 bias is unlikely.

You can also specify the die size and a file of tab-delimited or colon-delimited data. The file should contain two columns: the result, and how many of those results occurred.

The DieSquare file format is:

  • d6
  • 1: 3
  • 2: 16
  • 3: 9
  • 4: 8
  • 5: 6
  • 6: 18

That is, any line beginning with a lower-case “d” is assumed to be specifying the die size; any line with a number followed by a colon and space followed by a number is assumed to be a result. You can also put comments in by preceding the line with a pound symbol (#).

And as you might guess, this die is almost certainly biased.

  • $ ~/bin/diesquare "Skull d6.diesquare"
  • Degrees of freedom: 5.0 X-square: 17.0
  • p-value: 0.00449979697797
  • d6 bias is probable.

The code itself (Zip file, 1.6 KB) is very simple.

[toggle code]

  • #!/usr/bin/python
  • #
  • import argparse
  • import scipy.stats
  • parser = argparse.ArgumentParser(description='Calculate Chi Square p-value using DieSquare data files.')
  • parser.add_argument('--die', type=int, help='die size')
  • parser.add_argument('data', type=argparse.FileType('r'), nargs=1)
  • parser.add_argument('--verbose', action='store_true')
  • args = parser.parse_args()
  • class ChiSquare():
    • def __init__(self, die, rolls):
      • self.die = die
      • self.parseRolls(rolls)
    • def parseRolls(self, rolls):
      • self.rollCount = 0
      • self.rolls = {}
      • for roll in rolls:
        • if not roll:
          • continue
        • if roll.startswith('d'):
          • self.die = int(roll[1:])
          • continue
        • if roll.startswith('#'):
          • continue
        • if "\t" in roll:
          • separator = "\t"
      • if args.verbose:
        • print(self.rollCount)
        • print(self.rolls)
    • def calculate(self):
      • if args.verbose:
        • print '\n# ', self.die
      • expected = float(self.rollCount)/float(self.die)
      • freedom = float(self.die - 1)
      • observed = self.rolls.values()
      • expected = [expected]*self.die
      • chisquare, pvalue = scipy.stats.chisquare(observed, expected)
      • print "Degrees of freedom:", freedom, "X-square:", chisquare
      • print "p-value:", pvalue
  • calculator = ChiSquare(args.die,[0])
  • calculator.calculate()

Half of the code is just parsing the datafile; the actual calculation is a couple of lines using scipy:

  • observed = self.rolls.values()
  • expected = [expected]*self.die
  • chisquare, pvalue = scipy.stats.chisquare(observed, expected)

The variable “observed” is the list of observed result counts. The variable “expected” is the list of expected result counts. For example, rolling a d6 60 times, the expected result count is 10 for each result, so expected will equal “[10, 10, 10, 10, 10, 10]”. And observed will be the actual results; for example, in the above data the die face 1 was rolled three times, 2 sixteen times, 3 nine times, 4 eight times, 5 six times, and 6 eighteen times. This is the list “[3, 16, 9, 8, 6, 18]”. The script, of course, uses the lists it constructed by reading the datafile.

Surprise and initiative in Advanced Dungeons & Dragons—Wednesday, June 13th, 2018
Charles Marion Russell

Initiative, surprise, who knows?

Last weekend I ran an AD&D game at the North Texas RPG Convention, a run through Karl Merris’s Fell Pass from Dragon Magazine 32. Fortunately, I also ran a playtest with my local group, because I’ve forgotten a lot about how AD&D worked. Much of what I didn’t forget was wrong. I’m pretty sure we always used d10 for initiative, for example.

When I started using Gods & Monsters, I planned never to run AD&D again; preparing for this game I began to remember why. It’s not that the rules are overly complex; it’s that they’re explained in bits and pieces, scattered throughout the text, with strangely-ignored edge cases.

Take surprise, for example. Surprise is basically very easy. Roll a d6 for the entire group. If you roll a 1 or 2, the group is surprised, and that’s the number of segments they’re surprised. Individuals with high dexterity can adjust that up or down.

That some characters are surprised only on a 1 on d6 isn’t a big deal either, because the group uses their most advantageous member for the surprise roll. And that some creatures (and characters) have specific rules for when they cause surprise also works surprisingly simply, though it could have been worded better. When a group with special surprise rules meets a group with special not-surprised rules, the range needs to be converted to a modifier from the standard, and then applied to the die roll. It seems like it would have made more sense to have it be a modifier to begin with, but that’s D&D.

But no mention is made of characters who roll a percentile die to be surprised. If their most advantageous character is a Monk, and they roll 19 on d100, this means they’re surprised. It cannot possibly mean that they are surprised for 19 segments, however.

I chose to read the Monk surprise as basically a 1 in d4 chance, so that if the most advantageous party member is a Monk, the party will only be surprised for one segment.

DieSquare for iOS—Wednesday, May 16th, 2018
DieSquare chi-square test on d20

Well, the die is apparently okay. That means it’s intelligent and it hates me.

Ole Zorn’s Pythonista for iOS is an amazing mobile development environment. If you can do it in base Python, you can do it, inside a GUI, on your iPhone or iPad. This makes it a great tool for gamers who are also programmers.

My dice always seem to be conspiring against me, which is a big reason I’m interested in running chi-square tests. R is an amazing tool for doing so, but it isn’t an amazing tool for entering the data. Last week, after yet another accusation from my teammates that my die is clearly biased to roll low—in a D&D 5 game, where high is better—I started to think they might be right. The first time the accusation was made, I said, look, it’s just because the die knows I’m attacking. I’m going to roll it right now for no reason whatsoever, and the die will come up 20. It did. The die isn’t biased to roll low, it’s biased against me. But it just kept failing.

I thought I’d better double check. Because I am a typical superstitious gamer, I have different dice for different purposes, and this is in fact the first time I’ve used this die—I had it reserved for playing rather than gamemastering. It occurred to me that, since I wrote Are my dice random? in 2006, I have acquired both a great mobile device and a great development environment for it. Wouldn’t it be nice to be able to bring up a table of possible rolls, and tap on each possibility when it came up on the die so as to keep track of each count? That would make rolling through a chi-square test dead easy.

I wrote it this weekend in Pythonista. The basic idea is that you choose the die size, and then each possible die roll shows up in a table as a row. Tap the row to add one hit to that result. Slide to remove if you accidentally tapped the wrong row.1 Give the die a name if you want the results saved, and there is an icon to (a) share, for example, copy, the data or results, (b) trash the data and start over, (c) load previously-saved data. Data is automatically saved if you give the die a name. Once you hit a minimum of ten rolls per face on the die (with an absolute minimum of 50 rolls), it calculates the p-value for that data.

Rolling random levels across a range of experience points in AD&D—Saturday, November 4th, 2017
Substandard ability rolls

I’m prepping for a North Texas RPG Convention session, an Advanced Dungeons & Dragons adventure I’m going to run in June, in which the characters should be from levels four through six. I wanted to create these characters completely randomly; the adventure is an old-school adventure designed for old-school characters. This means a random variety of abilities and levels.

Initially, I eyeballed the level range, going from class to class in the Players Handbook knowing that I didn’t want the lowest experience point total in the range to produce a level lower than four, and that I didn’t want the highest experience point total in the range to produce a level higher than six. I correctly calculated that I needed to roll d25,000 experience and add 10,000 to it.1 The easiest way to handle this was to roll d100,000, divide by 4, round up, and add to 10,000. So, on creating each character I randomly rolled a d100,000 and performed the calculation, possibly adding 10% if the character had an earned experience bonus.2

However, reading over the adventure I wasn’t sure if perhaps I might want to make the characters level 5 to 7 instead. This would make the calculation 22,500 plus d100,000 times .375. Since I still had all of the d100,000 rolls, I first just pulled out my trusty Tandy PC-73 and wrote a quick BASIC program to handle the calculations.

  • 10 INPUT A
  • 20 B=A*.375+22500
  • 30 B=- INT(-B)
  • 40 PRINT B

Since 10% is easy to add mentally, it was faster to handle that calculation on my own instead of adding another line of code to ask whether the character merited the bonus.

Nowadays I would usually use Pythonista on the iPhone or iPad rather than the PC-7, but I was in an old-school mode, and I’ve had this BASIC-programmable pocket calculator since I first bought it in 1986, often using it for repetitive game calculations.4

It worked well enough that I decided to keep track of the d100,000 rolls in a text file.

The Prophet is your bitch—Monday, September 11th, 2017

In the Adventure Guide’s Handbook, I suggested that prophets might get prophet spirits when asking for other spirits, so as to be forced to use divine guidance. Afterward, I wrote:

But more than that one spirit manifestation, prophets pray for guidance every time they call new spirits. Their deity will intervene if there's a spirit that their deity wants them to have. Don't hesitate to give prophets spirits other than what the player wanted when there's a good reason from their deity's perspective. Determine one or two spirits that the character should call, and if the character doesn't call that spirit, replace one or two they did call with what they should have. Tell them this when they call the spirits, so that they know their deity has different plans for them.

All but one of the Gods & Monsters archetypes are individualistic. The warrior, the thief, the sorceror, and the monk, are, once the game starts, self-sufficient. They could have an adventure without encountering any non-player characters or creatures.

The prophet must interact with their deity or pantheon every time they request spirit types. As the Adventure Guide, you can choose to have their prayers be answered, or you can choose to have them be refused, or you can choose to alter the request. You decide how and whether their god(s) will act.

Gods & Monsters assumes that prophets are rare, and that they have a direct link to the gods—which also means that the gods have a direct link to them. In a sense, the prophet is a link between the players and the Adventure Guide. The gods don’t know everything the Guide knows, but they do have a wider view than the characters. If an adventuring group contains a prophet, and the group loses track of the objective the gods want them to follow, they can and will let their servant know.

Some game worlds will place restrictions on when and how the gods can appear. An incalcitrant or frightened prophet might choose to avoid those times and places. But there is one spirit which requires them to come to the gods: divine guidance. Divine guidance must be cast in a grove or other holy place, where the gods can influence the world.


As with most spirit manifestations, divine guidance is limited to the level and sphere of the spirit that manifests it.

But the gods are not so limited, and divine guidance brings the prophet to the attention of their god.

How I handle adventure logs—Saturday, July 16th, 2016
Lost City adventure notes

Here’s an example of what won’t be useful three months down the line.

Having recently read the old TSR Adventure Logs AD&D accessory for tracking game sessions, I’ve been thinking about what I do to remember old adventures and keep up-to-date on what’s about to happen.

I keep it pretty simple. I type it up in a word processor—in my case, Nisus Writer Pro. It’s important to use a tool that makes it easy not only to write1, or to search, but also to organize. For me, this means a word processor that supports the-document-is-the-outline. Microsoft Word does this, too, but I find that Nisus is easier to navigate and faster to write with.

The outline ends up looking like:

  • Year
    • Adventure 1
      • Session 1
      • Session 2
    • Adventure 2
  • Year

For example, since they started in the year 991 and investigated Illustrious Castle2, my notes on the last campaign look like this:

  • 991
    • Illustrious Castle
      • Illustrious Castle April 17, 2004
      • Illustrious Castle April 24, 2004
    • Valley of the Blue Sun
      • Valley of the Blue Sun December 18, 2004
      • Valley of the Blue Sun December 24, 2004
  • 992
    • Weaving
      • Road to Weaving April 23, 2005
      • Weaving May 7, 2005
    • Dowanthal Peak
      • Dowanthal Peak June 18, 2005
      • etc.

Having the outline makes it very easy to drill down to a particular session according to when we held it. I’m not sure, but if I were to do it again I might instead use the in-game date instead of the session date. As it is, I have the in-game year at the top level, and then the real session date for each entry.

On the other hand, in-game dates don’t always change per session, so perhaps I’d leave it be.

Each entry basically has three parts: what I expected to need to remember, which I wrote before the session, and then what happened during the session, which I wrote up the day after. Finally, from what happened I made a list of experience-laden events.

Sailing the high seas—Saturday, November 14th, 2015
Galleon over earth horizon

See my earlier article, Silver sail and gold, above a dappled sea, for non-numerical details on the politics and excitement of driftwood ships in the space above Highland.

The summary is that ships ride the gravity flow with driftwood. They catch the solar wind with sailcloth.

Building a driftwood ship

The first step in building a driftwood ship is acquiring the driftwood. Driftwood blocks the gravitational attraction of large bodies, thus making it possible to not fall back to a planet in a spectacular crash. Driftwood grows in rocky, cold environments with thin atmospheres. It grows best on Mars, but can also be grown on high mountaintops on Earth or similar planets.

Driftwood should be cured before use. Uncured driftwood reduces maneuverability by 5. Each year of curing reduces that penalty by 1, up to a maximum of five years curing on-planet. Driftwood can be cured more quickly or more efficiently in space. Driftwood cured in space reduces the maneuverability penalty by 1.5 per year, to a maximum of 7—that is, ships made from driftwood cured for five years in space will have +2 maneuverability.

Space is big. It is very easy to lose track of curing stacks when curing in space.

After curing, the wood should be coated with a varnish of wood resin to preserve the cure. The best resin is driftwood resin. This provides a +1 to maneuverability. Other wood resins do not affect maneuverability, and non-wood mineral oils reduce maneuverability by 1, while tar oils reduce maneuverability by 2.

Without varnish, the wood may become infected and eaten away by insects or other creatures.

Adjustments to ship cost and maneuverability:

Technique Maneuverability Cost Movement
Planet Curing +1/year +10%/year
Space curing +1.5/year +15%/year
Driftwood resin +1 +25% +1
Mineral oils –1 –5%
Tar oils –2 –10% –1

Weaving sailcloth sails

Unlike driftwood, which grows best on Mars but can grow in other places, the sailmoth only produces thread on Mars, and only in the Martian highlands.

Currency and economic policy in the middle ages—Saturday, August 29th, 2015
Edict on Maximum Prices

Emperor Diocletian’s 301 AD edict setting maximum prices.

We live within an abundant and ubiquitous market. From specialist boutiques to supermarkets to sprawling shopping centers, we can easily travel to acquire our hearts desire, or, Acme-like, send a note into the ether and have it delivered to us—sometimes in twenty-four hours. We no longer even need to carry money or the one-to-one representations of it: a credit card will give us the ransom of kings. But if we do want money there is an ATM at the corner 7-Eleven that will dispense what we need. There is no need to go to the banker, the banker is always with us and always ready to say yes. There is no need to negotiate how much of our wheat we must trade for however much butter we need. We sell our time for paper and then trade that paper credit at known prices for what we need and want.

If we don’t like the price on our heart’s desire, someone else makes a different model at a different price. In the best parts of our world, all economic transactions are beneficial to both sides, because both sides are free to take it or leave it, and thus only take it when the trade is at a price they are willing to pay or accept.

This was not always the case, and even today you can travel to places where you are forced to sell or to purchase at prices not of your own choosing1, or where the value of money changes with the corrupt political wind.

Price controls

There are two basic rules of economics:

  • People will trade what they are willing to trade.
  • If there is a profit to be made, someone will find that profit.

These basic rules mean that:

  • Any barriers—natural or artificial—to desired trades increase the profit of those willing to surmount those barriers.

These are laws of nature, just like the laws of gravity. Laws and social pressures can get in their way, but it’s likely to hurt: in reduced quality, increased prices, or hidden costs. They apply to goods, services, and currencies. People will pay the price they are willing to pay, and accept the price they are willing to accept.

Older posts