About /


My Favorite


Old Projects
What version of Shadow Armada do you have downloaded?

Hey, another curious e-mail finally motivated me to try to get the old Shadow Armada lobby up and running for kicks and maybe to provide a little further motivation for myself.  Anyway, if any of you have a version of Shadow Armada downloaded, I’d love to know what version number you have (it’s shown in the upper-left of the main menu screen).  I have a compiled version of 0.8, but I think there were some 0.9’s floating around.



Google Chrome, substrings, and memory leaks

Google chrome (at least, I haven’t checked other browsers) has some interesting memory management decisions that come into play when you’re parsing a specially formatted response.  In my case, I was parsing a graphite-style string like:


In other words, each line is a small descriptive string followed by a bunch of numbers.  My code was splitting on commas and pipes, and then using the first element of that array for display and matching purposes.  Surprisingly to me, Chrome was keeping the large data string around because I was still referencing a substring within it!  Using a little hack to duplicate the string:

label = label.replace(/./, “$&”)

fixed the issue.  Now the page only uses 129 MB, whereas before it was using 154 MB.  So a 16% memory reduction just by manually copying a string.  Something to be aware of…

lamegame_statview - Better graphite stats

Since graphite’s got a really terrible, hard to use interface that draws really unintuitive graphs unless you know what you’re doing, here’s an alternative

Google's Closure, Advanced Optimizations, and AJAX data

I recently came across Google’s closure compiler, which I really like for its advanced optimizations feature.  It bothered me, since I’m writing a webapp, that most compilers take too much care in respecting that all of the attributes of my methods be available in the global scope, at the expense of a lot of kilobytes.

After fixing up jQuery using the appropriate closure externs file (see, I was still having issues getting my code to run with ajax data.  Specifically, parts of my code accessed the data from a callback:

function onSuccess(data, status, request) {
  if (data.success) {

Whenever closure would compile this bit of code, it would replace data.success with something like  Of course, since the server didn’t know that success was renamed, the success token was actually in d.success.  The workaround, it turns out, is to write a thin translation library, and to process all of your data both before looking at received data and before sending data back to the server.  This way, the client code can translate variables from the longhand that the server might use to the shorthand in the minified JS.  The code looks like this:

//This is a dict containing all of the attributes that we might see in remote
//responses that we use by name in code. Due to the way closure works, this
//is how it has to be.
var closureToRemote = {
  ts: 'ts', snippet: 'snippet', username: 'username'
  , hasMore: 'hasMore', success: 'success', multi: 'multi'
  , id: 'id', multiWithSelf: 'multiWithSelf', since: 'since'
var closureToLocal = {};
for (var i in closureToRemote) {
  closureToLocal[closureToRemote[i]] = i;
function _closureTranslate(mapping, data) {
  //Creates a new version of data, which is recursively mapped to work with
  //mapping is one of closureToRemote or closureToLocal
  var ndata;
  if (data === null || data === undefined) {
    //Special handling for null since it is technically an object, and we
    //throw in undefined since they're related
    ndata = data;
  else if ($.isArray(data)) {
    ndata = []
    for (var i = 0, m = data.length; i < m; i++) {
      ndata.push(_closureTranslate(mapping, data[i]));
  else if (typeof data === 'object') {
    ndata = {};
    for (var i in data) {
      ndata[mapping[i] || i] = _closureTranslate(mapping, data[i]);
  else {
    ndata = data;
  return ndata;

function closureizeData(data) {
  return _closureTranslate(closureToLocal, data);
function declosureizeData(data) {
  return _closureTranslate(closureToRemote, data);

Usage is pretty straightforward - the first line of the onSuccess() method becomes

data = closureizeData(data);

And the first line of my gateway method for sending data to the server becomes

dataToSend = declosureizeData(dataToSend);

After that, my application worked completely with closure’s advanced optimizations, for a size reduction from 206kb with YUI compressor’s minification down to 134kb with Google Closure’s advanced compilation minification.

lamegame_tasking - Open source tasking library

I uploaded my distributed task processing framework which I’m going to be using in a number of upcoming projects; MIT license, do whatever you want pretty much.

Shadow Armada 2

I officially began work on Shadow Armada 2 today!  I also start work and school this week, so progress may be slow, but I got a fair amount done.  I’ll post some alpha screenshots or something in a few months depending on progress.

Shadow Armada 2?

So… you guys might just get a Shadow Armada 2.  I’ll keep you posted.

Published App! Bamboo Wallpaper - LameGame

Hi!  As a (kind of) test of the Android Market, I have designed, implemented, and published a live wallpaper for Android devices that is bamboo themed.  It uses some libraries that I’ll hopefully get up on Github pretty soon (a few weeks or months).  This is a pretty exciting step for LameGame Productions since it opens up the possibility of paid apps and was pretty fun and simple to create - I’m really curious to see how it goes.  Please check it out!  Market URL :  There’s also a free version at

Let me know what you think!

An Introduction

LameGame Productions has been around for many years (I have records from 2003…), and has mainly existed as an experimental game production company.  It has also served as the testbed for a few algorithms and other learning platforms, but most of its public activity has been a variety of games (search for “Shadow Armada” for the most popular game, or look at for the other old games). 

The company is entering a new era though, as we have several promising projects coming up.

A public site will be coming soon, but in the meantime feel free to take a look at for any open source libraries that were produced through LameGame.