blog.2wycked.net


Using a YAML DSL For a Game Dialogue Engine (Part 1)

I've always had a passion for programming. My dad was was/is also a software developer, to a certain extent, so it's just something I've grown up with. Like any impressionable kid at the time with a computer, I wanted to be make games, so I started down the road of learning to program. First in C, then in Perl and Python. I learned Python specifically because I heard it could be used to script and extend game engines, and I guess the rest is history, as they say. Anyways, as things go, I eventually realized that game making is a hard and thankless job, and eventually lost interest as I had to deal with school and then working.

More recently, in the last few years, I've been playing a few role playing games recently (mostly Fallout 2 and nethack) and have always been in awe of the brilliance and depth of both of these titles. Then I thought, man... how fucking awesome would it be to pour some of my unspeakably insane ideas into a game? Specificially, a role playing game (RPG). So the brain juices got to flowin.

Around the summer months of this year while reading the Fallout fansite No Mutants Allowed Il became aware of a nascent open source game project, with the name Post Apocalyptic RPG or PARPG for short. It's a top down isometric game in the spirit of Fallout, written in Python, using a C++ game engine FIFE.

I just couldn't resist. So I started submitting patches. A lot of patches.

Around the time I got commit access a few weeks later, there was discussion as to how dialogue and quests were to be implemented in game. There were some important considerations, such as it should be scriptable, easy to extend, and be easy for non technical users, such as writers. We tossed out the idea of doing it in pure Python, as writers shouldn't be expected to know how to program to add new content. We considered writing our own syntax and parser, but honestly this scared the shit out of me. Writing parsers almost always leads to a yak shaving marathon and is not something to take lightly. It would also be really annoying to have to build a GUI out of this, as now you'd have to have your GUI serialize the content to our custom grammar. This would take a long time and possibly not be done in time for us to release our planned tech demo (aiming for late 2009, early 2010). So in the spirit of agility and doing the simplest thing that would work, I suggested YAML-based DSL. YAML, for those who don't know, is a serialization language (think JSON) with a very easy to hand-write syntax.

I recalled that a few friends and old co-workers (konobi and Michael Nachbaur) had used YAML in the past as a DSL (in their cases for automation and test case management). I pitched the idea, and then without waiting to hear back, started hacking on a prototype. Even if we didn't end up using it, I thought it was a sweet idea and ran with it.

Essentially, how it works is, each non-player character (NPC) can have associated with them a YAML dialogue file. This file defines what the NPC says to the player, and what the player's possible responses are. Here's part of a dialogue file.

Here's what a sample dialogue file written by our game mechanics guru, zenbitz:

And here's what the GUI I made for it looks like (very basic):

As you can see, dialogue files consist of dialogue "frames", which often are just some NPC speech and possible responses. Each response can have a condition associated with it. This condition determines whether the response is displayed to the user.

There's a very basic dialogue wiki page that covers the syntax. It's a bit outdated right now, as these thigns tend to change from week to week.

In my next post, I hope to cover how the dialogue engine actually works and turns our dialogue file into scintillating NPC conversations!

Posted by orlando at 17:05:04 24-Nov-2009
Tags: games, rpg, parpg, yaml, dialogue, python

Deploying Catalyst Applications with SCGI

Like with any good framework, there are a few ways to serve a Catalyst application. When it came time to think about how I was going to keep this site up in the long term I had a chance to read up on a few of these options and thought I would share the knowledge.

I've just started playing around Catalyst. Learning a new web framework is pretty boring if you're just reading the manual and building an aimless, unfocused web app. So I decided to build a very simple blog. I know that's a completely unoriginal idea, judging from the number of different blog implementations on GitHub. However; I had another motive. I've been meaning to start documenting interesting things I play-with/learn/read about, just as a way to give back to the Internet and OSS community that's been so good to me and having a blog I could work on while I used some new tech seemed appealing.

As of this post, there are a few popular ways of deploying a Catalyst application:

mod_perl

mod_perl embeds the Perl interpreter directly in the HTTP server. This has been the traditional way of deploying Perl web applications, typically with the old standby, Apache. Embedding the interpreter in the server is a fundamentally flawed solution to the problem. Apache is big, and Perl is big. Each worker needs a copy of the Perl interpreter, which could consume a lot of resources. That's not even counting all the packages your application will need to run. In a nutshell, the webserver should be like a ninja: lithe, secure, agile. Your server should only serving or forwarding requests. It should not be doing any heavy lifting.

See mod_perl

FastCGI

FastCGI is another popular solution, if not the most popular, as it side-steps the problem of embedding the interpreter. How it does this is by starting a FastCGI daemon that accepts connetions from an upstream server and proxies information to and from the web application via socket or pipe. Most current web servers support FastCGI out of the box or with a bit of tweaking. This wouldn't be a terrible solution if not for one problem: FastCGI is a complicated binary protocol that can sometimes be hard to debug.

Behold the FastCGI spec

SCGI

SCGI stands for Simple Common Gateway Interface. Conceptually it's quite similar to FastCGI. You launch a daemon that is external to the HTTP server, and talk to the web application via a socket. The great thing is that writing or maintaining an SCGI engine is orders of magnitudes easier than FastCGI. As proof, contrast the protocol specifications for FastCGI and SCGI. All things being equal (performance, resource utilization) I would much prefer a simpler solution. It makes sense that SCGI may well be more performant than FastCGI. But, like any other benchmark, please take it with a grain of salt.

The SCGI spec

Deploying Catalyst with the Cherokee HTTP server

I was introduced to SCGI while I was researching deployment options for Pylons apps. During this same time I was exposed to the super awesome Cherokee web server. Cherokee is one of the new breed of super small agile web servers, comparable to Nginx and Lighttpd; it's written in C, has ton of features and is crazy fast. I really can't recommend it enough. The other interesting thing about Cherokee is that it is configured through an Web 2.0 GUI. Now I can hear you say, configuration GUI's are for pussies, what kind of hacker are you? Well, after wasting countless hours fucking around with Apache config, getting a site up and running exactly how I want it in literally 10 minutes, I have to say that I'm okay with this interface.

Back then, I wrote a very simple server, pyscgi_wsgi, to bridge the gap from the HTTP server (via the PySCGI module, also written by the Cherokee guys) to any WSGI app (Pylons in this case).

So now, while learning to use Catalyst, I again wanted to avoid using FastCGI while at the same time using some shiny new software. I saw that the Catalyst SCGI engine had fallen into disuse and wasn't being actively maintained. That weekend, I gave it some love and now Catalyst-SCGI-Engine ready for action once more.

But enough talk, let's get down to setting up Catalyst with SCGI.

First step, download and install Catalyst-Engine-SCGI:

$ sudo cpan Catalyst::Engine::SCGI

Now, create the SCGI launcher and make it executable:

$ script/myapp_create.pl SCGI
created "/var/www/myapp/script/myapp_scgi.pl"
$ chmod +x script/myapp_scgi.pl

Now, in Cherokee, under "Information Sources", create a new source and give it any nick, for example "myapp_scgi". In the field for the command to run, enter:

/var/www/myapp/script/myapp_scgi.pl -p 9000

This will allow Cherokee to restart the your application's SCGI server if necessary.

Now create or edit your virtual hosts. Create a "Directory"-type rule under the "Behaviour" tab. For example, to host the blog application I wrote, I have a virtual host for blog.2wycked.net with a directory handler for /. That handler is associated with the data source I defined above. Catalyst will automatically detect that your application is "mounted" under / and will do the right thing when you use things like $c->uri_for.

Next time you visit the application url, Cherokee will automatically start the SCGI server for us. Hurray!

Some possible problems you may encounter are permission errors from session files etc that your dev server may have left around. You may find it useful to have a couple of configuration scripts that set this up properly.

:wq

Posted by orlando at 10:50:45 12-Jun-2009
Tags: web development, catalyst, scgi, cherokee, fastcgi, mod_perl, http