Overactive Vocabulary

When In Doubt, Ameliorate

RSS

Warcraft, DOSBox, IPX, and Tomato Shibby, Oh My!

I’m a nerd. A total, unadulterated, no-holds-barred, nerd. Let this post serve as proof for posterity…

This little vignette starts with Warcraft. See, I have kids. Quite a few kids. And they’re getting old enough it’s fun to play games with them. Now, if I was a normal father, I’d buy them modern computers and we could play modern multiplayer video games like normal people. I am not a normal father; rather, if you’ll recall, I’m a nerd, which makes me a nerd father. Which means, when I think, “it’d be fun to play a multi-player video game with the kids,” my mind harkens back to some of the most fun I had playing multiplayer as a kid: Warcraft.

More specifically: Warcraft II: Tides of Darkness.

OK, first step is, can we even play it on a computer made in the last decade? Turns out we can - and quite easily - using DOSBox. DOSBox is a nerdy dad’s best friend when it comes time to introduce his kids to the classic experience of a LAN party. Since around here even our “old computers” run OS X, I’m a big fan of Boxer for making DOSBox a cinch to setup and manage.

So far things aren’t too nerdy, but we’re nowhere near done yet. The next step is networking, and this is where it gets interesting. Old games mostly use IPX, and IPX is pretty much a dead protocol on modern networks. DOSBox has a cool trick up its sleeve, though: it translates IPX to UDP, and it works without a hitch.

While hitchless, this IPX-over-UDP setup is kind of a pain; one player has to set up their DOSBox to be the server, and the other players have to know and enter the IP address of that player to connect. Kind of a pain in the tuckus to do every single time we want to play, so surely we can do better, right? Wouldn’t it be awesome if the network at the Talbott house had an always-on IPX server on tap? Why yes it would!

Since we’re not the first ones on the internet to wish for such a thing (is it possible to be the first at anything on the internet these days?), some searching around turns up ipxrelay, which is such a beautiful, dependency-less, single-purpose tool it makes me want to weep for joy. A quick:

1
2
3
4
git clone git://git.zytor.com/games/dosbox/ipxrelay.git
cd ipxrelay
make
./ipxrelay

And we have a working standalone IPX server. Now, I wouldn’t be comfortable running this on the big bad internet without a deeper understanding of its operation and security, but for internal LAN parties? Sign me up!

But that brings us to our next challenge: where do we run it? I don’t maintain an always-on server on our home network, nor do I really want to. But actually that’s not true, since I have three routers running Tomato Shibby, and they’re nothing but mini-servers that have lots of idle capacity that could be put to good use. So I decided to get ipxrelay running on my biggest/fastest Tomato router. No sweat, right?

No sweat, except that running a program written in C on a device like an Asus router means cross-compiling that program. My highest-powered router is a MIPS device, and Tomato itself has a very distinct and limited set of libraries available, all of which must be taken into account. But people do this all the time, so should be easy, right?

I’ll save you the multiple weekends and evenings of futzing, hair-pulling, puzzling deadends, and searching in circles. For some reason, nowhere on the internet could I find: “To cross-compile a program for a Tomato Shibby target do A, B, and C.” Until now, since that’s exactly what I’m going to do in as clear a terms as I can for the sake of future searchers.

Tomato Shibby Cross-Compiling for Dummies

It’s pretty simple really:

  1. Be on a Linux box
  2. Checkout a copy of the Tomato Shibby code
  3. Use the included, pre-built compiler to build your application

Well, it’s simple now that I know what to do. Follow these steps to avoid great pain!

1. Be on a Linux box

So first I need a Linux box to do the building on since I’m on OS X and I don’t need or want the pain of getting cross-compiling working in an environment different than what’s already used by the Tomato Shibby developers. In real life I built a VM from scratch, but with time for reflection and a blog post to write I’ve remembered I have Vagrant set up and ready to go here already. Here’s a little ‘cast of me setting up a Debian Vagrant box:

2. Checkout Tomato Shibby

Now that I have a Linux environment to build in, I need to clone the Tomato repo and checkout the tag my router is at:

Using --branch and --depth reduces the size of the checkout somewhat.

3. Use the Cross-Compiler

One rule of step-wise recipes is that one step will always be more complicated than the rest. This is that step. We need to take the program we want to compile, tweak its Makefile to use our cross-compiler, and build the program:

Wow, it looks easy now that I know exactly what to do. sigh

You can copy and paste from the screen cast above - slick, right? - but just in case, the patch referenced is available here: https://gist.github.com/ntalbott/75a8aa269b2d310bf02f, and the ipxrelay repository is here: http://git.zytor.com/games/dosbox/ipxrelay.git/.

Running ipxrelay on the Router

Now that we have a cross-compiled ipxrelay, we need to get it saved somewhere safe on the router, and ensure it’s running with the right options. I’m running mine from a USB flash drive I have plugged in, but I’ll leave the setup of that as an exercise to the reader. Once it’s somewhere safe - your options are /jffs (wiped each time you restart the router), some kind of added storage like a my USB drive, or a memory card mounted at /mmc if your router supports it - the next step is to get it fired up. Here’s the Firewall script I have in the Administration->Scripts area of Tomato to start it up:

1
/mnt/ROUTER/bin/ipxrelay --port 2130 --address 192.168.1.1 --pidfile /var/run/ipxrelay.pid

My IPX relay is going to run on port 2130, only bind to my internal IP, and put out a pidfile. The shutdown script then uses the pidfile to properly clean up:

1
if [[ -e /var/run/ipxrelay.pid ]]; then kill `cat /var/run/ipxrelay.pid`; rm /var/run/ipxrelay.pid; fi

And there you have it, an always persistent IPX relay on your internal network! You might think we’re done, but we can go even deeper!

DOSBox Automation

What’s better than having IPX networking consistently available? Using that fact to make our DOSBox games auto-networked, of course! The final thing I did was to create a couple of batch files to auto-configure the IPX setup so that when we launch the game, it Just Works™. We need to put three files in our DOSBox C: to make this work: first, FIND.COM from FreeDOS since DOSBox doesn’t come with a FIND built-in. Second, START.BAT, which tries to start IPX networking, and fails out if it can’t:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@echo off

del ipxnets >nul

ipxnet disconnect >nul
ipxnet connect 192.168.1.1 2130 >nul
ipxnet status >ipxnets
find "Client status: CONNECTED" ipxnets >nul
if errorlevel 1 goto neterror

call game
goto end

:neterror
echo Error starting networking...
echo Is ipxrelay started on the router?
goto end

:end
del ipxnets >nul

And finally, the super-simple GAME.BAT, which just makes START.BAT generic:

1
launch war2

DOSBox can be configured to launch START.BAT when it starts, and voila! You’re all set to crush your offspring - or siblings, or whoever you can convince to have a LAN party with you - at Warcraft 2!

The conclusion of this little piece is the same as the beginning: I am a total nerd. And as aggravating as it sometimes is, it’s a lot of fun, too!

Warcraft 2 Screenshot