Thursday, September 20, 2012

Giving Back

Our first game, Just Tactics, is built on a lot of open source technology. From our graphics engine (jMonkeyEngine 3) to our networking library (kryonet) to our chat client (Spark), Just Tactics would not have been possible without untold hacker-years of labor.

So, we've been sure to give back when we could. Our fork of the jme3 game engine will be available soon (although I'd recommend you go get the real thing instead of ours anyway).

But, for now we have three useful modules available on GitHub. All are available under the BSD license, meaning that you may use them in both closed- and open-source projects.



Alamode is a super-lightweight continuous update framework for Java applications. It requires no server-side infrastructure beyond a standard web server. It quickly scans indexed local files at startup and downloads those that differ from the server's version.

We use alamode to push out updates to the Just Tactics match and chat clients.



Simmons is a thin Java wrapper around native exec()/CreateProcess() functionality. The Java version of exec (Runtime#exec) requires that the parent process manually drain the stdout of the child process. If the parent JVM exits, then the child process will eventually stall out when its output buffer fills up. Simmons offers an exec() that truly separates the parent from the child.

We use simmons to chain between the alamode updater and the Just Tactics chat client. (Bonus nerd points if you catch the joke in the name.)



Sploosh is a pure Java implementation of game-grade fluid dynamics. It uses a vorticity model to compellingly simulate vortices and swirls in the fluid medium. Since the problem is embarrassingly data-parallel, it makes use of all available processor cores to update fluid state in real time. Seriously, you should get hundreds of frames per second with thousands of vortons.

You can see sploosh-based effects throughout Just Tactics, especially in explosions.

Wednesday, September 12, 2012

Customizing a Tinycore Linux Image

In preparing the backend network for our new turn-based strategy game, Just Tactics, we architected it to be able to easily scale up as the game becomes more popular. Step one was designing an automated netboot operating system environment, to allow us to bring up new servers without having to sit through an install procedure, and remove our dependence on mechanical storage devices.

As such a minimal Linux environment, Tinycore provides a great starting point for a low-overhead server, but some applications will inevitably need to be added to the base install. They distribute packages as Tinycore Extensions in compressed .tcz files, and provide some great methods to dynamically load them on boot or as needed. This works great for a desktop or virtual machine appliance, but for a constantly-running server, this provides an unnecessary level of complication and overhead.

Initial Attempt

Initially, we started using the recommended Dynamic Root Filesystem Remastering method. This method decompresses the extensions into a second initial ramdisk, which is loaded by one of the Syslinux bootloaders alongside the tinycore ramdisk. This is how it worked in our environment:
  • TFTP load and boot the tinycore ramdisk
  • mount an nfs share inside the tinycore ramdisk
  • load the secondary ramdisk from the NFS share
We were having problems with consistently mounting the NFS share inside the tinycore ramdisk, so we decided to simplify, and integrate the extensions directly into the primary image.

Final Config

We ended up using the method outlined in this guide to decompress the tinycore image and all relevant extensions, and rebuild it with the additional packages integrated. This way, everything is integrated into the root filesystem, just like it would be with a standard local install.

Download necessary extensions:

All tinycore extensions for the current release are listed here. I manually downloaded extensions for all necessary packages, including the dependencies listed in .dep files.

Unpack extensions:

After installing squashfs-tools, you can unzip each .tcz extension using the following command:
unsquashfs -f filename.tcz
The extensions will be unzipped into a filesystem tree in squashfs-root in the current directory, for example /tmp/squashfs-root

Unpack tinycore:

You will want to unpack tinycore into it's own directory, for example /tmp/tinycore. Unpack the tinycore ramdisk using this command:
sudo zcat tinycore.gz | cpio -i -H newc -d

Merge everything:

To integrate all of the extensions into the base install, you simply copy the uncompressed files into the right place. This will give you one filesystem tree with tinycore files and extensions in the same places. Sudo is necessary to preserve permissions in some of the system files.
sudo cp -Rp /tmp/squashfs-root/* /tmp/tinycore

Recompressing the Tinycore Image:

I use the following commands to update the dynamic linker and build the image. The advdef command  is optional - it simply compresses the image a little more.
sudo ldconfig -r /tmp/tinycore
sudo find | sudo cpio -o -H newc | gzip -2 > /tmp/tinycore.gz
cd /tmp && advdef -z4 tinycore.gz

Additional References:
Integrating Extensions into an ISO