Automating Random Tables

Abulafia, if you are not already familiar with it, is a Wikipedia-like site for automating random tables. It allows you to create tools like this page, which is an automation of Patrick’s excellent experimental complex generator. However, Abulafia is not always a good solution. Specifically, it:

  1. Requires the internet
  2. Is not appropriate for automating tables from books that are not free
  3. Needs a human to activate an account
  4. Has a format that is not as elegant as it could be

This is not to say that it should not be used, but just to point out that there is space for alternative tools. This became particularly salient to me recently when I was using Seclusium, which has a large number of tables for each entity generated, on the order of 10 or 20 tables per thing. Rolling dice and pondering at the same time can be a useful technique for creativity, and I don’t want to discount that process entirely, but when there are this many tables I prefer some automation. For this reason, I hacked together an ugly little Ruby script which would allow me to do this locally with minimal hassle.

I created* my own random table format because I wanted minimal syntax. Why should every item require programming language cruft? That is not very accessible to non-programmers. What is my format? One file per table, one entry per line. This ends up being barely any format at all, which is perfect.

Without further ado, here is the core engine of the script. I will explain below how to use it, and provide an example.

<%-
Dir.foreach('tables') do |item|
  next if item == '.' or item == '..'
  instance_variable_set(
    "@#{item}_table",
    File.readlines('tables/' + item).map(&:chomp)
  )
  define_method("#{item}") do
    instance_variable_get("@#{item}_table").sample
  end
end
-%>
<%- # Place template below this line -%>

Now, that may look like a mess, but you don’t really need to understand it. In english, what it does is read each text file in the tables directory into an array, which is also wrapped with a random accessor function (that’s what the define_method call does).

Just download this example, which is an automation of Telecanter’s magic item spur. You will need to have ruby and erb installed** and be willing to open up a terminal. I use the ‘$’ character to denote a shell prompt.

$ unzip telecanter_magic_item_spur-2014-01-20.zip
$ cd telecanter_magic_item_spur-2014-01-20
$ ls tables/
descriptor
noun
power
range
type
verb
$ make open

The “make open” command will generate random results, write them to a datestamped file, and then open that file in your default browser. You should see output like this:

  1. bright clothing that animates shadow of power level 4 (out of 10) with range touch
  2. wondrous/weird clothing that deludes space of power level 6 (out of 10) with range area effect
  3. scarred armor that dispels demi-humans of power level 1 (out of 10) with range area effect
  4. ornamented clothing that evokes earth of power level 8 (out of 10) with range area effect
  5. mundane weapon that conjures animal of power level 3 (out of 10) with range wielder
  6. scarred weapon that shields fire of power level 8 (out of 10) with range touch
  7. bright uncommon item that deludes monsters of power level 9 (out of 10) with range wielder
  8. ornamented armor that conjures mineral of power level 3 (out of 10) with range wielder
  9. ancient clothing that distorts animal of power level 3 (out of 10) with range distance
  10. dark clothing that divines mineral of power level 10 (out of 10) with range wielder

You can also delete all generated files by running “make clean” within the directory (but don’t do that unless you actually want to remove the result files).

To create your own generator:

  1. Copy the zip file to a new file and then uncompress it
  2. Rename the resulting directory to whatever makes sense for your new generator
  3. Create the new random table files within the tables directory
  4. Rewrite the random_table.erb template to reflect the output you want
  5. Zip that new directory if you want to store it as a single file or share it

The template is standard ERB format (you can google that), but the core of what you need to know is that to generate a random value, use:

<%= tablename =>

Hopefully it should be clear from the example random_table.erb file. The full generator-specific code for Telecanter’s magic item spur is, ignoring the loop:

<%= descriptor %> <%= type %> that <%= verb %> <%= noun %>
of power level <%= power %> with range <%= range %>

Given that this is ERB, you also have the full power of Ruby at your disposal if you want to do something complicated.

Remember, there’s nothing special about the random table files. They are just text files with one entry per line. Given that the template generates HTML output, the format of the resulting output can be customized using HTML however you like. You can see in the magic item spur example that it uses an ordered list.

Unfortunately, making this work on Windows is beyond the scope of this post, and for that I apologize. I suspect that all you would need to do is install Ruby though. Similar code in JavaScript would be more portable, but for various reasons the table file format would not be able to be as simple (because of browser security models not allowing direct access to filesystems), and I’m not really interested either in writing JavaScript data structures directly for the tables or in writing a converter.

I also know this is pretty janky beta-level code, and there are probably many ways to break it, but it has been really useful to me so I thought I would share it in any case.

One known issue: don’t include strange characters in the ERB file directly, as Ruby has some Unicode issues. Strange characters should be fine in the random table files, but may look ugly. You have been warned.


* “The nice thing about standards is that there are so many of them to choose from.” — Andrew S. Tanenbaum

** This should be true on all Macs with a relatively recent OS, I think.

Thanks to Josh Symonds for answering a few Ruby questions.

14 thoughts on “Automating Random Tables

  1. Joshua Macy

    You might also be interested in my Roll M Chrome extension: you install it in Chrome and it gives you a button you can use to roll on anything that looks like a table on any web page (tables, lists, bunches of divs that might contain images, such as what’s returned by Google Images). It ,might be a useful adjunct to your script, since while it doesn’t generate new combination, it can pick from any combinations that you’ve, say, saved and posted to a blog entry.

    https://chrome.google.com/webstore/detail/roll-m/noljjhcdpkdlkjbmfkoilmhmhncelolm

    Reply
  2. Dave Bapst

    It shouldn’t be too hard to something like this in R, which would then be useable on all systems.

    …And now that I’ve said that, maybe I’ll try my hand at it.

    Reply
    1. Brendan Post author

      @Dave

      …on all systems that have R installed.

      Is there something that you feel makes R more portable than Ruby (or any other scripting language)?

      I don’t mean to discourage you; more tools are better. Just curious.

      Reply
  3. Brendan Post author

    I tried this on Windows 8 with the Ruby installed by whatever is newest on http://rubyinstaller.org/ and it seemed to work fine though I had to type stuff on the Windows command prompt.

    This does what you would expect:

    cd path\to\unzipped\dir
    c:\Ruby200\bin\erb -T – random_table.erb >out.html

    You could probably associate erb files with a batch script to make this doable from the GUI.

    Maybe I should use rake rather than make for portability, as that seems to come with the Windows Ruby distribution.

    Reply
    1. Brendan Post author

      @Matthew

      I considered using spreadsheets (Logan has some good examples of using spreadsheets for similar tasks in the ods files here). However, I prefer the simplicity of text files for table format and the flexibility of a full template language for output.

      Also I am far from a spreadsheet wizard.

      A how to use basic spreadsheet commands for dealing with random tables would be a useful tutorial, I bet.

      Reply
      1. Brendan Post author

        @Matthew

        I think that all of these methods have their own drawbacks, and unfortunately all of them are still too arcane and/or not portable enough to really catch on in a general way, I suspect.

        The spreadsheets method suffers from not insulating the user from all that ugly syntax. Those formulas are really a mess, and I think it would be quite an undertaking to put together a spreadsheet to automate a somewhat complicated collection of tables meant to work together (such as the Seclusium magical item example), or something with any kind of conditional logic (if the result of table 1 is X, then roll three times on these other tables, else do Z, etc).

  4. Matthew

    I didn’t see this before posting the sample – valid reasons, but i still prefer the ease of use and sharing of the spreadsheet.

    It can involve a lot of trial and error to get the formula right, but the one i provided should give anyone who wants to learn a good start.

    Reply
    1. Brendan Post author

      That’s totally valid, and the ease of sharing as a single file that is a commonly known file type is definitely a point in favor of the spreadsheet approach.

      Reply
    2. Brendan Post author

      Also this spreadsheet example you are working on looks like it could be a good resource. Can you think about how to make it support multiple tables in an elegant way?

      Reply
      1. Matthew

        I have a wacky mega table spreadsheet compiled from many different sources you can look at here: http://goo.gl/4MrvKV

        The Combined sheet compiles the results of many other tables, including Land of Nod’s random Idol Generator and the reaction tables from Mentzer, among others.

        Several of the tables cross-reference each other, for instance, the Dungeon Dressing table produces magic mouths with personality traits taken from the Wampus Descriptors as well as its own subtable of small items that can appear in randomly located holes.

        (It was designed for quick inspiration to fill dungeon geomorphs in a weird hex-crawl/dungeon crawl hybrid game i run. You might go mad if you try to use it as a “how to” – sorry.)

  5. Pingback: Random Acts of Kindness

Leave a Reply to Brendan Cancel reply