technical gaming projects April 1, 2014

The continuing adventures of Encounter

I'm working on a game. It's a remake of the C64 classic Encounter, but available to play in any modern browser (including your phone, eventually). This is made possible by some cleverness called WebGL.

Every so often I post some techie details about how it's going. Previously I used tumblr, but why not have everything here? Much tidier. You can read the devlog entries so far by browsing the projects tag on this very site.

The easily distracted can play the current build here and browse the source if you're suitably perverse.

So what's been happening in 2014?

1. Thoughts on multiplayer

In December I had a pretty good shot at getting a two-player version running.

Even with a humble EC2 server acting as intermediary between the players, latency was low enough that this approach is definitely workable.

It turns out though that getting player movement to register on both screens was the easy part.

The hard part is getting two clients to agree on where Shots are, and what constitutes a hit. It's not a new problem by any means, but without some pretty robust server adjudication and lag compensation, this was a GIANT NEON RABBIT-HOLE that I would never emerge from with sanity intact.

So that branch is left as a curio for now and onward we go to get the core game done.

2. State machines

As soon as your game reaches any complexity you realise you need to model state all over the shop.

There are macro states - are we in attract mode, or combat, or warp? - as well as littler state machines for the objects that do interesting things over time.

Our Enemies need to decide if they're moving, waiting or attacking. A Portal needs to decide if it's opening, waiting or closing. Stuff like that.

How do you code that? With an FSM.

Apologies. A Finite State Machine.

It's better to reuse than to invent, so off to github we went to find javascript-state-machine. Things looked rosy for about an hour of state fiddling, before I hit a brick wall. Javascript was throwing an obscure error in the depths of the library that I couldn't make sense of.

After a few days of intense swearing I gave up and surfing on a tsunami of optimism, coded my own simple approach. The good news: it works nicely.

The FSM story finally got some closure thanks to the independent eyeballs of JHawk. It turns out that the OO parts - my pet hate in the land of Javascript - are absolutely fine and not the issue. Rather, I'd forgotten to have a one-time start state for the FSM to hold while init was taking place. So our poor FSM tried to jump into a functional attract mode state before everything was ready to go. By poor fortune the relevant error message was 'a bit cryptic' (i.e. abysmal).

So this FSM library is absolutely usable, but I'm some distance into my own implementation now. I could retrofit my various FSMs back into it, but the charming simplicity of the hand-coded approach is attractive.

3. Have you ever seen... a Portal?

With the FSM approach in my head, I bashed out the Portal.js to about 100 lines before trying it. A bold move. It worked pretty quickly with only a couple of tweaks to make it commit-ready.

When your Enemy counter - that's the E1 in the top left - reaches zero, a Portal will open somewhere on the playfield. It animates over time using tween.js , a library which can't easily be discussed without popping a few hundred boners. Check these graphs if you don't believe me.

Get to the chopper Portal quickly though - you have twelve seconds before it closes and you're thrown back into the fray.

4. Warp

It's taken me a few iterations of brain-bending to figure out exactly how Paul Woakes implemented the intimidating warp phase. It seems clear that we can simulate the whooshing inbound-death effect by moving the player, but not the spheres of destruction. Since there's no other visual reference point, the viewer can't tell the difference. This also simplifies the update loop because the bad guys all stand still; we just force the player's foot on the gas and let them deal with the consequences.

I think it'll take a few tries to get it feeling right - I'll update when it's in a workable state.

n.b. Are they asteroids? In the source I'm calling them asteroids. The manual says: "You will be propelled at high speed through a hail of spheres."

Well that makes perfect sense.