github linkedin email rss

Robots Vs Stuffed Animals

The title screen. You can always tell when it's programmer's art.

I have whisked away thousands of hours playing real time strategy games. So much so, my first website ever was a Starcraft fan site[1]. When I took video game design in my senior year of college, with a whole semester to make whatever game my group wanted, I knew two things:

  1. We would make a real time strategy, complete with network play hosted on our own version of Battle.net.

  2. We would use C++. From what I could gather, an intimate familiarity with the language was required to work in the game industry[2], and I had minimal practical experience at this point.

For reasons forgotten by me, we named ourselves Usurpology and set off to make our lighthearted take on the real time strategy genre titled “Civil Disobedience: Robots vs Stuffed Animals”.

The player's robots fail to take over a resource pool controlled by the neutral peace-seeking AI. Controlling a resource pool yielded a mix of shards used to accumulate more units.

Our initial designs were, per usual, overly ambitious. Despite having never created a networked game prior, we sought to construct a massively online multiplayer world with a real time strategy component. Fortunately, the reality of a semester timeline and each of us taking a full course load quickly narrowed the scope.

We took the idea of having powerful heros as the cornerstone of the player’s army from Warcraft 3. We took the idea of the gameplay focusing on control points rather than base building from Company of Heroes. The latter really helped keep the game on the more simple side.

Players would start on a map with a captain and a handful of basic units. To win the map, the player needed to conquer and simultaneously control a handful of control points on the map dubbed Power Sources. Players expanded on their army by spending shards acquired when defeating peace seeking neutral armies or controlling shard generating resource pools. Victory meant finding a way to balance collecting shards versus the burden of conquering and controlling Power Sources.

The first networked game I ever created. We went all out going so far to provide a lobby inspired by Battle.net.

Even without the networking component, this stood as quite the game to execute in only a few months. We accomplished most of our goals by capitalizing on our experience from previous games and the good fortune of working with the same group of people multiple times over the last couple of years. Come demo day, we showed off a full player versus player battle over the network. Of course, there were two memorable hiccups.

The first hiccup, surprising to nobody familiar with games with moving units, was the hands on confirmation of path-finding being a tough problem. Moving a single unit? Sure, take your time, run an A* algorithm, and watch your unit take a perfect path to the target. But let’s throw in a just a few curveballs:

  • Any reasonable game lets you highlight a group of units and move them with a single click on a destination. Of course, not all the units can fit on the one destination point, so you have to try and derive an intelligent destination and path for every unit simultaneously. Watch out for obstructions, such as other units, around the destination. Even better, all the units might not fit near the destination.
  • Different unit types might have different speeds, so make sure to consider faster units knocking into a slower unit else creating messy traffic jams.
  • Path destinations aren’t necessarily stationary (i.e. targeting a moving enemy unit), so you can not just create a path and check out.
  • We also want units to end up in formations which look nice aesthetically and conducive to gameplay elements like attack ranges.
  • Oh, and all of these calculations need to occur really quickly as players expect their units to start moving within milliseconds of issuing a move command.

We tried numerous iterations of path handling, but every deep dive on one problem unearthed several other more complicated problems. In the end, we were happy units moved at all.

The basic Stuffed Animal units available for purchase.

The second hiccup came during the tail end of our demo and still makes me smile to this day. Robots vs Stuffed Animals used an event based networking model. Every input event, like a mouse click, first goes to the server to be queued. After collecting the events from all connected clients for the current frame, the server would send back the queue to each client. Since each client now had the same queue of events to iterate through, the resulting effect on the respective client’s games should be the same. Pretty straightforward and surprisingly easy to implement.

Pleased with how our multi-player came together during development, we had quite the shock when our games started to radically desynchronize during our demo day. This had never happened in any of our testing! Well, turns out we made one very hilarious oversight: we completely forgot to account for any kind of packet latency.

The Stuffed Animals take over the last enemy controlled Power Source and achieve total victory!

The College of Computing network was extremely fast, and packets between computers in the lab often arrived in sub millisecond time. Except during demo day, traffic on the network was a little more contentious, and packet travel time sometimes spiked to a whopping 5 ms. Our game had ignorantly assumed a packet would go from the player’s client, to the server, and back to each players’ client in the same game frame. Now with even the most modest of latency spikes, clients started receiving events during different game frames. Since a different game frame meant a different game state, one client might take the same input and make a slight, but rapidly compounding, deviation from the other client. For example, a unit receiving a move order one frame later on one client might also have the unit arrive at the destination one frame later. This deviation in arrival time might be just the difference to have the unit collide with an enemy on one client while narrowly missing on the other. Uh oh.

As fate would have it, I would go on to work as an online engineer at EA a year later and learn the many intricacies, of which latency was just one of many, to keeping event based multi-player games synchronized.

Footnotes

[1] The website looked like the worst cliches of a mid nineties Geocities design combined with the eager ramblings of a 15 year old over estimating his importance on the Internet. Just like many of my stupidly embarrassing creations, I did not understand the permanence of the Internet at the time (though I question if that would have changed anything). For many years, long having lost the ability to update or take down the site, a feeling of dread would pass over me when searching for my name on Google and seeing this ancient abomination of a website and personality appear too high on the results for my comfort. God help me if some serious Internet sleuther made it all the way to page 5. Thankfully, the host of the site finally went out of business around 2018, and I feel somewhat confident one of my more horrifying Internet stumbles is lost in time.[/f]

[2] I spent a good chunk of time in the months before interviewing for a game industry job by reading Bjarne Stroustrup’s “The C++ Programming Language” like the novel it wasn’t. However, the true turning point in my relationship with C++ came when my future boss suggested I scope out “Effective C++” by Scott Myers prior to the on-site interview. I devoured and loved the book, and I still consider it the most helpful technical book I have ever read (not least because I got the job).[/f]


Back to fun things