Ace Invaders

September 19, 2011 § 2 Comments

Ace Invaders is a little internal project we’re working on as a fun way to explore some new things. It’s a basic game which does the following:

  • Allows players to control a space invader character and move it around a grid.
  • Allows many players to move around the same grid.
  • Maintains the game state on the server and push it to all players as soon as it changes.

To get this done we’re using a combination of cool technologies.

Websockets

How Pusher works

If only there were a simple diagram representing this interaction. OH THX PUSHER.

Pusher is a super simple websockets service. Clients open up a websocket connection with Pusher and receive events which we trigger from the server though Pusher’s API. Our server triggers an event each time it is notified of a move and Pusher sends this event to each user.

Pusher is an awesome way to get a websocket connection working quickly, but it is limited to sending events to clients. Ideally we would write a websocket server component (Socket IO, anyone?) to allow two way communication. This would remove the need for a new AJAX request each time a player makes a move.

Backbone.js

is a client side application framework which allows us to organise data into – a backbone model maps directly to a game position database entry in our back end. We group these models into and define a to represent each.

Events make backbone tick – each time model data is changed an event fires. We bind to model change and destroy events when we instantiate a view, and then write the code to handle those events. In our game a destroy event causes the invader’s view to be removed from the game grid and a change event causes the view to be moved from one square to another.

Sinatra

The back end is a simple Sinatra app talking to a SQLite database which stores users and grid positions. It accepts PUT POST and DELETE via AJAX calls and triggers Pusher events.

Application Flow

When a user makes a move a series of things happen:

  1. We listen for ↑ ↓ ← → key-presses and fire the backbone function on the current user’s model. Save is a nice proxy for jQuery.ajax() and will make a RESTful POST or PUT request to the server with the new data.
  2. The server processes this data, creates or updates the user’s position and triggers a Pusher event with the new position data.
  3. Pusher sends an event to every client (except the originator) containing the new position.
  4. Each instance of our backbone invader model is bound to listen for events which are fired when Pusher delivers a new message. When this event fires the model is updated with a backbone and the views update accordingly.

TLDR; when a user makes a move they send it to the server and every other user gets a Pusher notification of the move. This ensures that every player has an up to date representation of the game in their backbone models and can make moves in real time.

The game board

A breakthrough in real time massively multiplayer moving around (RT3MA)

Now this is all pretty basic and as proud of it as I am I don’t think it’s going to be winning any awards for gameplay. We have the working bones of something cool – the next job is to spec out a game which people may actually want to play and make it happen!

§ 2 Responses to Ace Invaders

  • Phil Nash says:

    If you implement your own websocket server, will backbone.js have to be altered in any way? It seems to me that it is entirely based on AJAX rather than websockets.

  • Andrew Appleton says:

    Yes. You can override backbone.sync to do whatever you like – in the example they use localStorage.

    We’d do something similar but tell Backbone.sync to talk to a websocket connection rather than localStorage (or the default $.ajax()).

Leave a Reply to Andrew Appleton Cancel reply

What’s this?

You are currently reading Ace Invaders at Logical Friday.

meta

Follow

%d bloggers like this: