Tablescript.rb

This is a Ruby Gem that helps RPG-playing nerds like me generate random things from tables.

For example, a Dungeons & Dragons wandering monster table like this:

Wandering Monsters (d10):

1-5: d6 orcs
6-9: 3d6 ancient red dragons
10: a cuddly bunny

can be automated in Ruby-ish ways like this:

table :wandering_monsters do
  f( 1..5 ) { "#{roll_dice('d6')} orcs" }
  f( 6..9 ) { "#{roll_dice('3d6')} ancient red dragons" }
  f { "a cuddly bunny" }
end

puts roll_on( :wandering_monsters )

Syntax

Tablescript.rb is a simple DSL built on Ruby that helps to define and roll on tables.

Define a table as follows:

table :table_name do
  ...
end

Roll on a table as follows:

roll_on( :table_name )

Table entries define blocks that are returned if the die roll matches the entry. Entries can be simple text:

f { "a cuddly bunny" }

complex/interpolated text:

f { "#{roll_dice('3d6')} cuddly bunnies" }

or arbitrary Ruby code:

f { { :effect => roll_on( :random_limb_loss ), :damage => roll_dice( '4d10' ) }

Table entries are either "f" or "d" for "fixed" and "dynamic" respectively.

Fixed entries are defined for specify die rolls. For example:

f( 1 ) { ... }

defines the result for the roll of 1.

f( 5..9 ) { ... }

defines the result for a roll of 5, 6, 7, 8, or 9.

f { ... }

defines the result for the next roll. If it's the first entry, it defaults to 1. Otherwise, it's whatever the previous entry was + 1.

The :wandering_monsters example table above defines 3 entries: 1-5, 6-9, and 10.

Dynamic entries are defined for groups of rolls. For example:

d( 10 ) { ... }
d( 50 ) { ... }
d( 40 ) { ... }

defines 3 groups of results. The first is for rolls of 1-10 (i.e. the first 10). The second is for rolls of 11-60 (i.e. the next 50). And the third is for rolls of 51-100 (i.e. the next 40). In this case the total number of entries works out to 100, so the entries are effectively 10%, 50%, and 40%.

Entries do not have to total 100. For example:

d( 1 ) { ... }
d( 2 ) { ... }

defines 2 groups of results where the second has twice the chance of the first. Tablescript will effectively roll a d3.

Reference

Tablescript includes the following global functions:

table( name, &blk )

Defines a table, as in the above examples.

roll_on( name )

Generates a random number from 1 to the highest defined entry, and returns the corresponding table entry from table named name.

roll_on_and_ignore_duplicates( name, times, *args )

Rolls on the name table times times and ignores duplicate rolls.

lookup( name, roll )

Returns the entry from table name corresponding to the roll roll as if that number had been randomly generated.

roll_dice( dice )

Returns a random number generated by the dice described by dice.

The following formats are acceptable:

dX: rolls a single X-sided die
YdX: rolls Y X-sided dice and returns the sum of all rolls
YdXdl[Z]: rolls Y X-sided dice, drops the lowest Z rolls, and returns the sum of the remainder
YdXdh[Z]: rolls Y X-sided dice, drops the highest Z rolls, and returns the sum of the remainder

choose( options )

Returns a random selection from the passed array of options. For example:

puts choose( [ "red", "green", "blue" ] )

is equivalent to:

table :temporary do
  f { "red" }
  f { "green" }
  f { "blue" }
end

puts roll_on( :temporary )