RoboRally Project Status

Bad idea: drinking an iced coffee with at least two espresso shots in it (I didn’t count, I just poured) after dinner, at roughly 10:00pm.

On a related note, I also thoroughly enjoyed the Yale House’s home brewed beer, courtesy of Sean. On a further related note, I successfully made my grandmother’s Imitation Chow Mein hotdish! More on cooking and assorted foodage later…

Good result of aforementioned bad idea: more work done on RoboRally project!

For those of you who don’t know, RoboRally is an awesome game that was put out by WotC several years ago, in a very limited printing. I bid a copy up for auction on eBay up to $30, and it just sold for $81. No way I’m paying that much for a used board game, even a totally awesome one. I’ve played it 4 times now, and have become instantly obsessed with it. Perhaps more loyal fans may be offended by my fervor, but have you ever met a born-again Christian? I think it’s kind of like that. At any rate, I’m trying to write a computer version of the game.


I’ve completed the board file XML parser, created all of the board element data structures I’ll be using (plus their assorted substructures), and created a sample board file. AND IT ALL WORKS!!!

In case you’re curious, the very simple board I’m testing with is the first board here. Right now I’m only implementing the board elements from the basic set, and this example doesn’t even have all of those, but testing can come later. Plus, I’m fairly confident of my XML schema.

Working on this, I’ve noticed an interesting feedback loop when I’m developing code. In this case, I started with the XML schema to describe all of the data, and then started on the parser. As each part of the parser was written, I defined the relevant data structure type. When I ran into the problems with the parser, I adjust data types, or the methods I was using to reference data structures.

Once that was all ready, I created an example board file. I had to fix some parse errors in the schema file, and then I discovered that my example board file wouldn’t validate, because I had made the schema too strict. I was requiring all board element information for all board element types, some of which isn’t relevant, and would require someone writing a board file to have empty or meaningless XML elements. I modified the schema to match up with the board element structure union type definition I’m using in the program, such that any of the full sets of data necessary for each board element are valid, but so that no mixes and matches of board element data are allowed that don’t match up with a specific board element type. In other words, I replicated the union typedef in the XML schema.

The end result of all of this XML skullduggery is that the validation step (#6) takes care of making sure that all of the necessary data is there, so the only error checking I need to do in the program is with step #9, in making sure that the values that aren’t strictly constrained by the XML schema are good when I load them into the board element data structures.

Here’s just a quick rundown of all of the steps that need to be completed successfully for this simple program to work:

  1. The program has to compile
  2. The program has to run
  3. The XML document has to be well-formed
  4. The XML schema has to be well-formed
  5. The XML schema has to be valid, based on the RelaxNG schema specification
  6. The XML document has to be valid, based on the XML schema
  7. The data structures have to get allocated
  8. The data structures have to be loaded with data from the parsed XML document
  9. The data from the parsed XML document has to have good values

So yeah, I’m happy that I’ve gotten this far. Current code stats: 486 lines of C (just the XML parser and a testing main function), 197 line XML RelaxNG schema, 541 line example XML board file, and 76 line makefile (the complexity will be useful later in the project, when I have multiple build targets), for a total of 1300 lines written on and off over the last 4 days. The makefile I’m using is a basic design started by , but one that I’ve tweaked as well (since it was originally for our robot project in the engineering department), and that I’ve further customized for the RoboRally project.


The next phase of the project is to produce some sort of visual output for the board, since that’s sort of the point. There are several steps to this, now that I’m planning things out a bit more:

  1. Create board tile images, such as individual board elements, plus phase activity indicators and directional arrows
  2. Create a board square visualizer, that will layer all of the above images appropriately, and will announce errors in the board file if there are conflicting or redundant elements
  3. Create an I/O program that will do all of the steps from reading the board file to dumping the resulting board image to a file
  4. Create a simple SDL program to display the rendered result, as a transition into the board editor phase

After that phase is complete, I have a number of other phases. The first is the board editor phase. XML is all well and good, but these boards get complex very quickly, especially as their size increases. In other words, no human would want to describe these boards in XML by hand. It took me almost 20 minutes to write up the simple example board I linked to above, and a lot of the rows in the board are almost identical, allowing for a lot of my good friend copy-and-paste. Once the board editor is complete, I can create a number of test boards, or even recreate some of the boards from the original set (there happens to be a nearly-complete set in the lounge of the summer dorm – thank you, Sven ’03!). I’ll have to check on the copyright status of those board designs, first, though.

Then comes the hard part: turning a board editing utility into a playable game. I’ll focus on single player first, and implement the movement and event part of each turn phase, in which all of the robots and the board elements do their thing, respectively. I should be able to get programming working as well. Option cards will probably have to wait… I’ll figure out more of these details once I get to this point.

I’m going to use CMU IPC to handle the multiplayer networking for the game. It’s slow, but not a lot of data needs to change hands, assuming everyone has the same board definition. The huge, huge, HUGE advantage of using IPC is that I don’t have to write a server; I can just define messages and pass them around. This is far enough in the future that I don’t know if it will get done before the summer is out.

I’m writing everything in C, with libxml2 and SDL. This means that it should be fairly portable, but I’ll let someone else try it out on Windoze :oP.

This is going to be FUN!! Planning this all out makes me happy.


Comments

5 responses to “RoboRally Project Status”

  1. foodage!
    i’m looking for recipies to make while i’m here, especially baking. got any good ones?
    -sasha

  2. I’m going to use CMU IPC to handle the multiplayer networking for the game. It’s slow, but not a lot of data needs to change hands, assuming everyone has the same board definition

    Hrm, you’ll almost certainly have to create some sort of consistency checking — this doesn’t need to be an airtight distributed system, so it could be as simple as “use one counter for all the players’ messages, and have everyone whine and roll back if the counter value is ever unexpected”, but messages do get lost, so you’ll have to do something.

  3. Congratulations that things are going so well for you on it. Using libxml2 is a very good choice for an XML parser, and the idea of defining boards in XML is also intriguing. It’s intriguing to me because it opens up the possibility of using something like XLinks to easily buy yourself the ability to “include” patches of tiles at a level beneath that of your parser. You could use this to help with your map editor because it would let you define multi-tile blocks (i.e. map components) that people could then add whereever they wanted them without the bloat and maintainability problems of always copy-pasting code.

    (Keep in mind that I’ve never played RoboRally, though it sounds quite interesting if you’re willing to put this much work into it.)

    Mmm, graphics. SDL is a good choice. Nice and portable. Should you ever find yourself wanting to do 3-d stuff (and if you’re comfortable with C++), check out OGRE some time. In addition to a cute name, it’s also a beautiful engine. I suggest it in part because I know that they’ve made huge progress on their GUI tools recently (which would be handy if you want an ingame gui) and because they’re a) cross-platform, b) good documentation & tutorials are available, and c) they’re very responsive to help requests. I spent last summer doing tech support on IRC for them.

    Hmm. Networking. I take it that you used this IPC library on the robot? I’m curious because it seems kind of like the outlier among the other very standard libraries that you’re using here (SDL, libxml2). I mention it only to make you aware of other options that I’ve found useful. CORBA, for example, is a very well-developed standard for this kind of thing. In particular, the ACE networking library comes to mind as being a very heavy duty C++ networking library.

    If a library that includes as a subproject, a CORBA ORB (object request broker), is too heavy for your needs… have you looked at either the Torque Networking Library (a commercial game networking library-made-open-source) or at enet, which is a *very* lightweight networking library for the kind of message passing that you mentioned you were thinking about?

    Obviously, if you’re already comfortable with the CMU IPC library and it’ll do what you need, then go for it. I mention these alternatives to you not because I want to intrude on your project, but simply because when I did projects like this, I did them because I wanted to find out how to do all of the required things in something close to the “best” (and what that is varies considerably) way possible. If you’re also doing this for a similar reason, or even if you just enjoy looking at really amazing C++ libraries, then these libraries (along with Boost and Loki) will give you quite a bit of enjoyment.

  4. One other quick thought occurred to me just now. Have you thought about keeping the file i/o and parsing code separate from your actual turn-to-turn processing code? If you did so, then you could use libraries (statically or dynamically linked) to reduce code duplication between the projects. I mention it (even though it’s really simple on Linux and not *too* hard on windows) because the idea of using filesystem i/o and *executing a process* every time you take a turn just doesn’t sound fun. Why not just leave those things as procedure calls and tack you monitoring code (i.e. the stuff you’re using to make sure that what you’re writing is always working, the test harness as it were) outside of that?

    Also, if I didn’t mention it before, good luck!

  5. It’s all going to be the same source code, compiled into multiple targets. In other words, I’ll just have different main functions that use some subset of all of the source code, and the overlap shouldn’t bloat the executables too much.

Leave a Reply to ashsongCancel reply