I’ve been playing RPGs on Google Wave for a few months now and I really like the die-rolling bots like randomleetwenty. I decided it was necessary to have a simple command-line script which can read simple die-rolling expressions common to most RPG players and print the result. It’s a simple script I wrote in Python and perhaps if you’re interested in learning Python, it might be a good starter script to read and tinker with.

One thing to note is that this is a very naive rolling script. I didn’t bother getting into writing a die rolling algorithm that simulates a more “realistic” randomness. That might be a topic for another post. Just know that if you use this script, you’re mostly going to get middle-of-the-road numbers and will RARELY ever see a maximum or minimum roll. In other words, I would be surprised if you ever got a crit or fumble from this script.

(Sorry for the column spill!)

Code:
#!/usr/bin/env python

##################################################################
# roll - A naive die roller using a common die expression syntax #
#                                                                #
# (c) 2009, 2010, James King - http://agentultra.com             #
#                                                                #
# Licensed under the GPLv2                                       #
##################################################################

import operator
import random
import re
import sys

USAGE = "Usage: `roll <die expression>`\n\n"
USAGE += "Expressions:\n<num>d<sides>(<operator><modifier>)"

def print_help_and_exit(err):
    print >> sys.stderr, err
    print >> sys.stderr, USAGE
    sys.exit()

def parse_die_expression(expr):
    """
    >>> parse_die_expression("3d6+1")
    (3, 6, <built-in function add>, 1)
    >>> parse_die_expression("3d6")
    (3, 6, None, None)
    >>> parse_die_expression("Hello, world!")
    Traceback (most recent value last):
        ...
    ValueError, I don't understand: Hello, world!
    """

    DIE_EXPR = re.compile(r'(\d+)d(\d+)(?=([+,-,*,/])(\d+))?')
    OPERS = {'+': operator.add,
             '-': operator.sub,
             '*': operator.mul,
             '/': operator.div}

    try:
        (num, sides, oper, mod) = DIE_EXPR.findall(expr)[0]
    except IndexError, e:
        raise ValueError, "I don't understand: %s" % expr

    if oper != '' and mod != '':
            mod = int(mod)
            oper = OPERS[oper]
    else:
        oper = None
        mod = None

    return (int(num), int(sides), oper, mod)

def roll_dice(num, sides, operator=None, modifier=None):
    """
    >>> import operator
    >>> result = roll_dice(1, 20, operator=operator.add, modifier=1)
    >>> isinstance(result, int)
    True
    >>> roll_dice(1, 20, sum, 1)
    Traceback (most recent call last):
        ...
    TypeError: operator must be callable and accept 2 args and return an int
    """
    die_total = sum([random.randint(1, sides) for d in range(1, num)])

    if operator and modifier:

        try:
            result = operator(die_total, modifier)
        except ZeroDivisionError:
            print_help_and_exit('Cannot divide by zero!')
        except TypeError:
            err = "operater must be callable and accept 2 args"
            err += " and return an int"
            raise TypeError, err
        else:
            return result

    else:
        return die_total

if __name__ == '__main__':

    try:
        expr = sys.argv[1]
    except IndexError, e:
        print_help_and_exit('Missing argument!')
    else:

        try:
            (num, sides, oper, mod) = parse_die_expression(expr)
        except ValueError, e:
            print_help_and_exit(e)

        result = roll_dice(num, sides, operator=oper, modifier=mod)
        print >> sys.stdout, result

Just save it to a file, make it executable, and either create an alias to it or add it to your PATH. You will need Python installed of course. Windows users might need to do something extra, I don’t know (I haven’t used Windows in so long that I’m no help there, sorry).

Anyways, I’ll try and get around to posting other little snippets I find useful for enhancing my RPG experience as I go.

Technorati Tags: ,


I found this matrix somewhere and after reading through it, am left with some thoughts.

The first couple of sections are rather useful. I’ve met a lot of programmers who are really good at what they do, but looked at me like I was a talking chicken when I tried to tell them that Python lists are arrays, not lists. Apparently the difference between linked lists and arrays is not too important to some people. Whereas these same programmers could run loops around me in other areas in the matrix that I felt I lacked in. If you are any kind of programmer, I recommend reading the first sections on “computer science,” “software engineering,” and perhaps the first few rows of “programming.”

However, from there it kind of devolves into trivial attributes. Such attributes as “API,” “frameworks,” “languages exposed to,” and worse, “blogs,” make little sense. They don’t really give any sort of indication of competency and instead display only the author’s bias in my opinion. For example, it’s not entirely impossible that your first language could be Lisp or even Haskell. Exposure to these languages basically guarantees at least partial knowledge of functional programming and its related concepts (currying, lazy evaluation, etc). For the “languages exposed to” row, this would put you at level two in the programmer category. Yet you would likely be a level zero in the “languages with professional experience” row. While the distinction between knowledge and experience can be made, in the context of professional versus academic experience the distinction means very little. The astute reader might find more odd entries as the ones I’ve pointed out are just the tip of the iceberg (“IDEs,” really?).

It could be a useful aid though, for those of us who have to interview new programming candidates. Perhaps someone could take the lead and refine this matrix a little more? I would start by removing the frivolous rows and cross-checking inconsistencies between existing rows (professional versus academic as noted above, for example).

Technorati Tags: ,


It took me a long time to cave and get an account in the first place. My excuses for avoiding Facebook were from the elitist (“It only serves to turn relationships into convenient commodities and doesn’t actually improve social interactions in a positive way”) to the ignorant (“It’s for narcissistic wankers”). I can be a bit of a digital curmudgeon.

However, I’ve had an account for nearly two years now. In that time I’ve come to rely on Facebook quite a lot for managing a good portion of my social activity online. It managed to practically replace email and the phone for planning get-togethers and keeping in touch with friends. The speed of communication was probably the most addicting: I could see upcoming events and plan which ones to attend and upload photos of the event during my attendance. I could silently watch what everyone else was up to. By the time I deleted my account I was probably checking up on my Facebook feed every couple of hours.

The one major concern of mine though, for some reason, has been privacy. I resisted getting an account because I was irrationally afraid that my identity could be stolen, that someone might try to stalk me, or that if my activities were not popular with people I was trying to get a job with or get to know that it might affect me negatively in some way. Eventually however I got over it and was pleased to know that at least I could keep my profile private and not share everything with everyone all of the time.

In the last few months things started to change. I began to notice that Facebook hasn’t actually enhanced my social life much and hasn’t garnered me any new friends. In fact, it’s probably had a negative impact on my social life: instead of finding a group of friends that stays tightly knit with weekend plans and hang-outs, we tend to spread ourselves out towards our personal interests. Facebook allows us to pick and choose events that please us — if you said you “might attend” one event early in the week but another event that tickles your fancy pops up, I find most people can’t resist the urge and cancel their earlier plans. This sort of thing has started to happen to me so often that it has become a real put-off. To top it all off, they recently changed the privacy settings so that my profile and some basic information about me is always available and always searchable. My inbox started filling up with emails and friend requests from people I had no intention of adding to my profile. Each person has the same question, “Why haven’t you added me?” Why should I have to explain this to people?

All of this is just too much. Facebook has become a burden on my conscience and it’s no longer worth carrying it. So I deleted my account earlier this week. We’ll see how that goes.

In the mean time, how has life without it been? Anxious, I’m sad to report. I’m left constantly wondering if I’m missing out and that’s probably the greatest nuisance of all. I know in reality I’m probably not missing anything. Just status updates, cheeky comments, and the next viral campaign most likely. So I’m now a digital nomad again, left to my curmudgeonly ways…


National Novel Writing Month. I had first heard about it in 2005. The marketing was catchy and lulled me into a false sense of security. It was a charitable way to kick-start my creativity and get my writing career going. However, that first year I don’t think I made it past 5000 words. Subsequent years (2006, 2007) saw that word count increase, but only marginally. Despite all the encouragement and slogans (“No plot, no problem!”) I still couldn’t get to that fabled 50 000 word mark. I didn’t think I would bother with it again after that.

My slogan it seemed was, “Don’t bother, quit early. Go out for beers. People will forget about it soon.”

However for one reason or another I decided to try again this year. I wasn’t as busy as last year, I had friends this year who were interested in doing it with me, and this time I was a little older and more keen. I think having friends along for the ride really helped. It kept the enthusiasm going. We had someone to brag to and someone to compete with. It gave us an excuse to go out for brunch on Sundays and drink coffee all afternoon. This year was a lot different than the previous years.

I think I learned something about writing novels too. I had bought a copy of Booklife by Jeff Vandermeer after reading some reviews. In it there are a few gems on the process of writing novels. The debate for many is whether to write it all at once with little planning or to spend time up front structuring your novels and then filling them in. Now far be it from me to explain to you how all arguments end in two sides, but after getting through this grueling November throwing words to the proverbial page like a coked-out Pollock I have got to say: there is a third alternative. If you have a kernel of an idea just try the NaNoWriMo approach: set a hard word limit and a deadline and do everything you can to just vomit forth your idea regardless of form, structure, or good sense. But do not for the love of all that is sacred try to edit that mess. You’ll probably toss most of it. That’s what I’m going to do. I don’t have a complete novel by a long shot after blasting out 50 000 words. What I do have is a good beginning. I have characters, interesting relationships, neat situations, and a fun setting. I took the time to just follow my characters around and play with mixing things up. I finger-painted in words essentially until I saw a form in the background… and now that has become my goal. Now I am ready to chip away at the idea until I have a fully realized novel.

So be a little free-form and spastic at first. Then go back and try to find the themes, structures, and such. Then start over and really hammer it out. That’s the idea I got. I’ll let you know how it works out.


Uniformity

I’m tired of quirky syntax rules, operator precedence, and programming style guides. I hate wasting time thinking about the formatting of my source code. Some people are obsessive-compulsive about this aspect of the craft of programming. Some mistake it for “beauty” when they read program source. But syntax and formatting are tedious and boring details that only frustrate and annoy when they get in the way.

Lisp makes my life easier. It has an extremely… symmetrical syntax (is that the right word?). All those parentheses that annoy some programmers are actually what makes working with Lisp such a breeze as far as managing the syntax and formatting of source code. My editor can treat Lisp code as data structures it can manipulate and thus take care of the formatting and syntax in a uniform and deterministic way. I don’t have to think about it. That leaves me more brain room for thinking about programming.

But all those parentheses!

If this is your major complaint, I have an exercise for you: using a decent source-code editor like emacs, load up some Lisp code and modify the syntax highlighting to change the color of the parentheses to the background color (or maybe just a few shades shy of the background color). The parentheses are still there, but you don’t have to pay attention to them. Any decent editor will automatically balance them for you and format your source code so that it is legible. No need to nit-pick about spaces, commas, delimiters, infix operators, precedence, and the slew of other problems that infix notations and delimited-statement languages present. None of it.

Abstraction

I’m not even an intermediate Lisp programmer yet, but just reading about and seeing examples of macros was really enlightening. I can’t even count the number of lines of Python code I had to refactor over the last few years simply because the same patterns keep appearing in my programs. I keep getting repetitive boilerplate code, refactor it out, and move on; the cycle continues until I feel like I’m done — but it always feels like I’m sweeping dirt under the rug. Well six rugs actually and some rugs only act as interfaces to the other rugs. Macros on the other hand allow me to remove boilerplate code up front without creating another layer of indirection. They also have the pleasant side effect of becoming an embedded domain-specific language for my program.

Probably more important and fundamental than macros are symbols! The ultimate abstraction. A symbol can be used to identify nearly anything in Lisp whether its a value or some function. They’re kind of like how symbols work in mathematical notation and are just as useful in expressing our thoughts clearly.

Expressiveness

Well written Lisp programs do more than describe the mechanical implementation of a solution. Those details are hidden behind a high-level language that can be reasoned about independent of the computer. The verbs, nouns, and grammar are not bound to the machine or compiler that reads them. The programmer is free to add, redefine, and supplement the language to suit the problem. When a Lisp program nears completion, it begins to read more like a description of how to solve the problem rather than how to tell a computer how to solve the problem. Find some good Lisp code, download it, read it. It’s a rather pleasant experience and easier than it seems at first.

Technorati Tags: ,


chrism makes a good point: backwards compatibility is what will keep people developing on and updating the 2.xx series of Python interpreters.

It’s the key feature that is preventing most developers from adopting 3.x. Python 2.0 was released in October 2000 which makes it nearly a decade old. Lots of software was written on it since. There were a few bumps along the way, but that was to be expected. 2.6 is a very stable release and will only get stronger. Migrating all that code or re-writing it entirely generally isn’t an option for working programmers. We’d rather find the most painless way to keep our software running and maybe get a few performance or platform patches in along the way.

I still haven’t done any serious Python 3 development. I really don’t see the point. The only really cool language feature can just be imported from __future__. I haven’t really been compelled to try and port any libraries or systems I use as I don’t really see the benefit yet. All my Python 2 code works just fine as is and why fix what isn’t broken?

It’s not necessarily a case of “worse is better,” but one of cost and benefit. There isn’t a good enough benefit to go through the pain of porting large systems and libraries over to Python 3 yet. Maybe we’ll see it when they get to 3.6 or 3.7… in about 10 years or so. Until then I’m not really worried. Python 2.x will continue to be developed and improved in that time as well. Who knows? Maybe Python 3 will be the obsolete version.


I got invited to Google Wave on the weekend. Finally. I was skeptical of Wave at first as I am with all things Google. I watched the presentation and was left thinking, “Yeah that’s neat but what is it good for?” Planning trips and chatting with my friends doesn’t need a radical new Internet protocol. To say the least I was rather “under-whelmed.”
google wave
Being the nerd I am, I thought about RPGs. I’ve read about a few early experiments on Wave and the prospects looked good. Certainly better than play-by-post and less chaotic than a chat room. Wave itself may be hard to explain as a concept but for playing games it suddenly became clear. Since I didn’t have any invites to bring in my own friends I decided to take the plunge and GM my own Wave.

The decision of what game to play was pretty easy for me. I’ve been wanting to play some of the “retro-clones” of Dungeons and Dragons for some time now. I’ve just had trouble convincing my gaming group to give it a try. We’re all invested in the latest shiny edition and don’t want to let our hard earned dollars collect dust. So I picked Swords and Wizardy.

I had tried Microlite 74 to many groans one evening when half our group decided not to show up for our scheduled game. I had thought that it would be nice to try because it had such a small little booklet that learning the rules to get a quick session going would be painless. Boy was I wrong. I still like the concept, but the rules were just a little too vague and left glaring omissions. The players kept turning to me with questions that I couldn’t find answers for. Naturally I winged it, but they’re all reasonably intelligent adults and saw through it. We had a bit of fun, but it was really hard to tell whether we were “doing it right” or what. Too much confusion.
sw_small_cover_1
I picked Swords and Wizardry because it was still rules-light despite the core books hefty 100+ pages. Chgowiz, an RPGBN and one of the players in this new Wave game, wrote a Quick Start Guide for S&W which would ease new players in. Two birds with one stone and the rule book is pretty clear and easy to follow. No omissions as far as I can tell.

I also chose it because the older versions of Dungeons and Dragons were far less reliant on grids and miniatures. Until some interesting extensions become available to Wave, it feels more condusive to stay in the text realm. Instead we can use our imaginations and just ball-park the unique situations with hand-drawn sketches. With the ability to create new sub-conversation threads on the fly and to edit any text in a Wave, I think we have all the tools we need to collaboratively move the game forward with minimal fuss.

So what is playing on Wave like?

Well I don’t know yet. We’re still rounding up players, generating characters, and formulating the background of the adventuring party. However, Wave has certainly made even this aspect of the game much easier. It is sort of like being at the table: the dice bot rolls all the dice in a blip in a Wave and real-time conversations can happen to discuss various aspects of character creation as they surface. Waves can get pretty cluttered fast with all the conversations inter-mingling with the documents you’re creating; so we’ve found that pruning your Wave becomes a necessary evil. Fortunately it’s not hard but it could be easier. Either way, we’ve yet to get to the gaming part but so far so good.

I decided to follow a couple of guides in setting up this adventure. You can think of them as emerging standards or formats for roleplaying on Google Wave. I think I’m going to end up cherry-picking ideas from the lot into my own game. I’ll report the results as we progress here.

Playing on a Wave
The Waves the Thing


Lawrence Lessig recently penned an article stating the case against total government transparency. It is a dense read that tends to flip-flop along the way so I managed to find an paraphrased and annotated version which summarizes it quite nicely. The summary contains links to the relevant sections, but I haven’t had time to comb through and verify the author’s interpretation of Lessig’s article. Reader beware.

The salient point that stood out the most to me was the claim that, “Transparency projects that track the flow of money and influence are particularly bad.” The reasoning goes on to suggest that unfiltered access to information allows the public to make biased correlations between money, influence, and corruption. Moreover, those correlations are harmful because they might lead people to misunderstand or just ignore the information they receive.

I’m someone who wants to see the public have unfettered access to not just campaign finances, but to government spending, budgets, and so forth. While some people might make biased or misguided correlations and derive accusations of corruption or manipulate public agendas, I think the benefits outweight those concerns. Understanding where and how our tax dollars are being spent by the government should be the right of every citizen. We also haven’t seen a project of this nature evolve and doubting its benefits before even giving it a shot is like cutting one’s nose to spite one’s face.

Income taxes are a necessary evil in our modern society. They allow the government to take the money they want from the fruits of our labour and leave us what they think is a suitable amount to live on. This was a suitable arrangement when the world was assailed by world wars compounded with stock market crashes. The government spending on social assistance and public infrastructure programs really dragged us through the mud. But we haven’t needed that kind of assistance for at least the past thirty years. That corruption has become so common place as to not even warrant front-page news anymore is a glaring sign of this for me. If we cannot repeal income taxes this far along we should at least have the right to inspect how far our dollars are going. One thing we cannot forget is that the money the government collects from us is a debt they owe to the public and as creditors we should have the right to inspect the books to ensure they aren’t cheating us.

This kind of transparency hasn’t been achieved before. Its consequences could range from nirvana to chaos and it’s too hard to predict the out-come without even trying it. Total transparency cannot be achieved over-night, but there must be some way we can experiment with the idea. We could start by building a computerised system to track the expenses of a handful of agencies and open access to the public. Maybe when we have some really solid evidence of whether fiscal transparency works or not we can make some substantial judgement calls. Until then claims against its efficacy amount to hot air in my opinion.

Lessig is a very smart man, I have no doubt. But I find his extreme cautionary approach to fiscal transparency disheartening. We’ve come to a precipice where the need for government accountability has never been more desireable. We can’t just sit here and let things stay as they are. We have to do something and can’t be doubting solutions before we’ve had a chance to try them out.


I recently came upon an issue whilst working on a project written in Python that was kind of interesting. After having nearly completed an API to a third-party service, I discovered that their system was sensitive to the order in which the fields appeared. They had given us some API code in Perl and PHP, but no message format specification. So I threw up a small Python web server that would just capture all of the POST data sent to any URL and fired all the example API code I had. From there I went about creating a Pythonic API that I would be happy using and used the captured messages as my target. I decided dictionaries were going to be my primary data-structure since they mapped well to the message format I would have to serialize to. I went on my way and implemented the most simple solution possible and within an afternoon had it all ready to go. And when I started pointing my new Python API code at the test servers provided by this third-party service I kept getting the wrong responses.

Once I had narrowed down the problem to the field ordering issue, it became apparent that Python’s built-in dictionaries were not going to cut it. The update method of the standard dictionary object does not guarantee the order of the items added, ruining the order of the fields as I serialized them. Normally the serialization format should be agnostic to field order, but this is a situation where practicality beats purity. I did a quick search and found an ordered dictionary implementation in Python within a few minutes. Then I realized that I wasn’t going to just be able to import it and re-run my tests. Throughout my code I had assigned “bare” dictionaries…

It wasn’t too hard to run a couple of regular expressions to replace all those assignments with explicit “dict” objects, but if I had used it in the first place I would’ve saved some time. Here’s what I mean:

Code:
def my_method(arg1, arg2, arg3):
    a_dict = {'my_long_name_1': arg1,
                  'my_longer_name_2': arg2,
                  'my_pretty_long_name': arg3}
    req_str = dict_to_message(a_dict)
    response = server.do_request(req_str)
    return response

However, I had a lot of methods that looked like this. Mainly because I didn’t want to just use kwargs for the sake of being terse. This was an API after-all and it should be easy to identify what each parameter is and what its for (in theory). But when I found that plain dictionaries weren’t going to work out, I couldn’t just add an import line to the module and go. However, from now on if I’m creating dictionaries in my code I think I might prefer using “dict” directly rather than relying on the syntax. Here’s why:

Code:
from odict import OrderedDict as dict

def my_method(arg1, arg2, arg3):
    a_dict = dict(my_long_name_1=arg1,
                      my_longer_name_2=arg2,
                      my_pretty_long_name=arg3)
    req_str = dict_to_message(a_dict)
    response = server.do_request(req_str)
    return response

And this way if I find that my initial design isn’t sufficient, I’d just have to change the import line to change the data type. It’s a small thing, but it should save me some editing time. Any thoughts or suggestions are welcome of course.


Another early preview screen with the import dialog running

Another early preview screen with the import dialog running

Thanks in large part to Pat Lynch and is DDMWarbandTool, Skirmisher now has a complete database of miniature card data and images for both the cards and the figures themselves! So if you haven’t yet, go check out his great tool (will require Windows/.NET though) and give him some kudos for his hard work. It’s much deserved!

My recent work has been to integrate the data import into the Skirmisher application interface. This will allow me to distribute the application without the data in order to avoid all of my previous concerns and allow end users to import the data without resorting to running my scripts manually at the command line. When all is said and done it should work on all the major desktop OS platforms out there.

The new database is nice! It now covers all of the sets and includes all of the card images. The data is finely grained and probably can’t get much better. I’m really happy with it.

I guess that’s it for now. I might follow up on this post with a technical article on working with python, GTK, and specifically progress bars. Getting past that part was a bit of a hurdle because there were so many choices and the documentation one can find on the Internet is pretty sparse. My future plans for Skirmisher include some UI improvements, a preferences panel, PDF generation (for printing out war bands), and finally… the game.

I’ll leave you with a bit of a teaser: I’ve been working on a game engine. Originally just a state tracker for a single player on the table, I’ve found that it’s pretty trivial to track multiple players on the table. This in turn became a rather crude game engine for playing DDM skirmishes on my computer. I hope to expand it out into a full system with maps, network code, and the whole nine yards. Though no word yet on when I’ll even have an alpha demo available any time soon…