Thursday, March 6, 2014

TableScript

Early February I decided I needed a nice JavaScript project, so I decided to rewrite an old c# application that I had made that was based off of the TableSmith application.  This allows very intricate random tables to be created that can reference sub-tables, which can further reference other tables.

A simple example of this would be a wilderness encounter table where a d8+d12 would be rolled to determine what type of random encounter has occurred.  There might a 10% chance of an encounter that is rolled three times per day, so that may as well be all linked together in the following script:

:Start
1,[PossibleEncounter]
_[PossibleEncounter]
_[PossibleEncounter]

:PossibleEncounter
1-9,No Encounter
10,[RollEncounter={d8+d12}]

:RollEncounter
1-3,[VeryRareEncounter]
4-6,[RareEncounter]
7-8,[UncommonEncounter]
9-12,[CommonEncounter]
13-14,[UncommonEncounter]
15-18,[RareEncounter]
19-20,[VeryRareEncounter]

Where CommonEncounter, UncommonEncounter, RareEncounter, VeryRareEncounter tables would all still need to be defined.  In the above example each roll on the Start table will cause three rolls to occur on the PossibleEncounter table, which in turn only has a 1 in 10 chance of generating an encounter.  In case of an encounter we are overriding the default behavior by passing in the dice that the table should be using, if the {d8+d12} was left off the behavior would simply be to roll 1d20 and use that result.  By overriding this we get a more bell shaped distribution with the common encounters at the center, and the more rare ones on either end.  Notice that even though a 1 is never allowed in our case, we still need to pad the table with it since it always assumes tables begin with 1.

My goal was to recreate this in Javascript, and due to the forgiving nature of the Javascript language I completed the project in about 8 hours, with less than 1/10 of the code I had in C#.  This made me question my C# design with was a bit clunky and somewhat slow considering what it should be doing most of the time.

I realized that my Javascript implementation was less than idea, as every table would have to be retrieved dynamically from the server, which was possible with some Ajax calls, but not only was this slow, it required more plumbing than I wanted the client to have to deal with.  I envisioned an exposed API where a client would call a table and the API would return a fully resolved random answer.

So, I threw away my previous version and used my Javascript version as the template for my new Server-Side version, which took about 3 times the code of the javascript version, but only took another 16 hours to get working.  Then another 16 hours to implement every common TableSmith function and to debug a performance issue.

My TableScript seems to now have all the capabilities of the original TableSmith application and is wired up to a database which stores a library of tables that allow a script to leverage any table within the database.  The tables all have a fully qualified name, which must be used if a table has generic name, but it will attempt to look up a table by its friendly name with a few strategies, which in most cases will find the correct table.

After all this I realized the reason I stopped using TableSmith was not wanting to haul a laptop to the gaming table, but I thought that what I had here would be usable by a simple webpage that a smart phone could access easily from the gaming table, though I still prefer to do my "prepping" in advance, some things such as loot or NPC names or the shop inventory could easily be randomly generated at the table.

I figured the creator of TableSmith might have done something similar to what I'd whipped up in about a week and found these:

Mythosa - TableSmith
http://www.tablesmithonline.com/

Where the KickStarter from last year failed to reach it's funding goal, but seemed to have a decent following, as I know the original TableSmith application did as well.  I also found a few other sites that implemented common TableSmith tables, but essentially re-wrote them in Javascript to generate the results.

The goal is to expose my global tables via an API that is usable by everyone, and those with more ambition can create an account an setup their own tables, written in TableScript that will also be expose via another API.  At this time, I'm debating on keeping these user defined tables private, but only through obfuscation, if a user wants to share a link to some useful tables that they created, then it would be accessible to all with the link.

Also, I've started a dialog with the guy behind the KickStarter, who is open to finishing the frontend demoed on the KickStarter, that would be wired to my backend.  I just need to get my API site hosted someplace, currently looking at Azure as it seems very reasonable...at least in the short term, as I have $150 a month in free MSDN Azure hosting.

No comments:

Post a Comment