Friday, January 9, 2009

Scripting missions in Java/Jython

The game I am working on has "missions" or "ops" or "capers" that involve the player choosing a bunch of his Crew for specific roles, such as say a Driver, a Lookout, a Thief, with specific skills. They then pull off the caper using their skills.

Since this is going to be a major portion of the content in the game, I wanted to have this be pretty accessible to the designers, so I thought up a simplified node-based system where a simple tree is walked and skill checks are made, etc..

Wow, what a waste of time that was.

It turns out that it's quite hard to simulate something like a mission script, even a simplified one, like that in this game. So I gave up and am now doing it the way I wanted to do it in the beginning - with scripts. Specifically, Jython/Python.

Now, this is slicker than it has any right to be. Basically you add the Jython.jar to your project, and if you want to use the JDK6 scripting support, you add the JSR-223 "engine" that is basically a glue layer between the Jython API and the JDK6 standardized scripting. Going to that engine page is a little disconcerting, as the engines there are from August and are all listed as "draft" - I'm sure there's more up to date stuff somewhere, but I haven't found it yet.

Anyway, if you use the JDK6 stuff instead of the Jython API directly, you get essentially transparent support for just about any scripting language you can think of. Jython is nice though, not only because it's Python and Python Est Good, but because it compiles the Python to JVM byte code, meaning it should be pretty fast.

That said, I got the scripts executing pretty quickly and ran into my next hurdle: How to debug mission scripts. Ugly.

Since right now op scripts are only running on a processor bean in the backend, and then generating results, etc, it's essentially very difficult to debug/create the scripts that way. I had to hack up a little Spring-based test app that loads the OpData I specify and then create a bunch of fake crew to meet the mission parameters, generate the Operation and then run the op script (first loading it from the "work" location rather than the database, where they will live when they are done.)

That works ok. Of course there are still rough spots, but I'm really just spoiled now - for instance, my basic OpExecution helper class in Python is derived from a Java base class, and since I don't have something set up right, the code completion can't complete for methods in the Java base class. Oh poor me. :)

Anyway, this is how I've wanted to do this kind of system in a game for a long time, and with how slick Java made it there's no way I'm going back!

0 comments:

Post a Comment