WOWHack 2012 Debrief
(or how we built a multiplayer WebGL game as a Spotify App)
A quick debrief about Battlefy, our 2.5D space shooter for fun music discovery, implemented as a Spotify App, created during the Way Out West Hackathon 2012.
The game idea is based around a simple space shooter. The goal is to fly around in space and avoid obstacles in forms of moving asteroids and other players. Your ship is equipped with a weapon that uses your top tracks as ammunition. Health is lost when you’re hit and health is gained if you get hit by one of your starred/favourite tracks. The connection between the hack theme ‘Music Discovery’ is that the player will hear and (hopefully) discover new music while playing the game with different people all over the world!
Pre hack
We knew before the hack started that we wanted to do something fun, not just a straightforward interpretation of the theme (“Music Discovery”). Since everyone on our small team loves game development, we had a direction we all wanted to explore that was both fun and challenging. What could be more fun than creating a game experience with focus on music discovery?
Our initial idea (which ended up quite close to the final result), depended on utilizing libspotify server side since we had already decided to implement the game using WebGL (there exsits no JavaScript bindings for libspotify, so client side was a no go). This solution would only be able to work on user submitted collaborative playlist, since these are the only types of playlists a non-owner can alter with libspotify. Right before the hack we explored some of the other API:s provided in the hack, and found out about the possibilities of Spotify Apps. Spotify Apps are HTML5 and JavaScript bundles that run inside a Chrome Frame in the standard Spotify client. This meant that we would be able to run the game inside Spotify and have access to a sleek Spotify API through JavaScript on the client side. Almost too good to be true (see Obstacles part)!
Tech used
JavaScript
Both the client and server was written in JavaScript. This made it possible for everyone on the team to quickly jump between parts of the code base without much of a hassle.
WebGL
Since Spotify Apps uses a Chrome Frame, we were able to utilize WebGL for graphics rendering. Sadly this awesome technology seemed to be disabled on the latest Windows versions of Spotify (according to @mager it is should work, but we couldn’t get it running on our Windows machines).
Node.js + Socket.IO
The server is run inside Node.js, and uses Socket.IO to communicate with the clients.
Something worth noting regarding Spotify Apps and Socket.IO: Since no data should be dynamically downloaded inside a Spotify App, we needed to serve the Socket.IO JavaScript file locally, more information here: https://github.com/LearnBoost/Socket.IO/wiki/How-do-I-serve-the-client
Pxf.js
Our own tiny collection of JavaScript and WebGL utilities we usually use for hacks and game jams.
Spotify Apps API
We use the Spotify Apps API to get the players top tracks (which are used as ammunition in the game), and to add/play tracks from other players when the player dies.
Echonest API
We used the Echonest API to calculate ammunition properties based on song traits..
Game Client
The actual game is based on a previous hack for the Ludumdare compo called “Spaceblastah”, and is for the most time available on http://proc.se:8080. The game features full 3D space flight where the objective simply is to find and shoot your enemies with your laser.
The game world is rendered in 3D using WebGL, and although the preceding game allows for player movement in three dimensions, all movement in Battlefy is restricted to a 2D plane. This allows for easier controls and lets a new user accustom to the game more quickly. However, diving into and modifying the code produced for another very time limited hack proved to be a challange, as code flow not always follows an instinctively logical path.
The look-and-feel of the game is visualized with strictly lo-fi, pixelated graphics reminiscent of old school video games. While the style of Battlefy is in tune with current retro-gaming aesthetics, the simple graphics are in reality a product of time constraints and very little to no skill in the visual arts department of game development :)
Before the game begins, the player is shown a list of her/his top tracks, which in turn will be their “ammo” list. Different songs will have different properties, and this is reflected in damage and speed modifiers for songs used as ammunition. This is calculated with a (super secret) “special algorithm” using popularity and various song traits extracted using the Echonest API.
Since it wasn’t possible to freely access the user’s playlists directly (see Obstacles below), the user will have to drag a playlist to the game screen before the game can be started. This playlist will then be used while playing, to buffer all the songs the player is killed by.
Backend
The game and lobby server is written in JavaScript, running Node.js serving WebSocket connections through Socket.IO. We reused the actual server backend in large from our last Ludumdare entry, mainly because of the simplicity of its original design. Essentially, except from the lobby part, the server just propagates state changes between connected clients. The main drawback in our implementation is the fact that it lacks any kind of security, and would not be suitable in any production environment what so ever. :) Thankfully, such things as security and stability is not the highest priority in a hackathon like this (and for once, can be even liberating to not have to worry about these subjects). However, the main thing to take away from developing the backend, is how sweet it is to have a unified language on both the client and server side.
The state of the game world should ideally be maintained by server, where the actions of each client can be verified in order to find misbehaving clients and cheaters. Updates to the game state is then propagated to each client, which can use client-side prediction to interpolate smooth movement.
The server communicates with the clients using WebSockets, which are TCP-only. This is unfortunate, since UDP is the preferred protocol for real-time games. With UDP, a network model similar to the one used in Quake 3 can be used. This might be possible to implement in the future with WebRTC.
Obstacles
We encountered some obstacles that we had to work around, this section describes how we worked around them.
Spotify - No WebGL support under windows, poor support under Linux
The game is intended to run as a application inside Spotify; unfortunately some of us were using Windows machines at the hack where WebGL wasn’t available in the embedded chrome frame. As a workaround we wrote a dummy wrapper for the Spotify API so that the game would sort-of run in any WebGL enabled browser without code stripping.
Spotify Apps API - No access to username
This is of course a very minor annoyance, but having access to username would be nice for kill log and high-score. In the current API version there is an anonymous identifier available, but it isn’t fun to display. We ended up using Facebook Connect for this.
Spotify Apps API - Restricted access to playlists
We wanted to add an optional “hardcore” mode, where the game would add tracks to a (selected subset) of the users existing playlists. Force-fed music discovery. Unfortunately you don’t have access to this with the API so the user has to drag a playlist to use before starting the game. Having the game maintain a single playlist automatically might be possible? We didn’t have much time to play with that.
Echonest API - Song batching
Requesting songs one-by-one worked fairly simple, but it would have been nice to minimize the requests by batching and querying several song ids together in one request. It might have been possible to do this using a temporary “Collection” though.
It would have been nice with a client-side JavaScript wrapper for working with Echonest, but I guess there isn’t much real world use for it as it exposes the API key. In hindsight, we should have put metadata lookups in the server and used the Echonest library for Node. We would then be able to cache requests for faster loading times.
Legal stuff
As far as we know, Battlefy could cause certain legal problems when using Spotify to play the tracks during a game session. It seems that the permissions when playing music in the context of a game differ contractually from streaming songs in services such as Spotify, even though the game itself is run completely inside the Spotify client. We don’t really know the specifics regarding this matter, but copyright violations isn’t something you normally take lightly in the music industry. :)
However, if it is only a matter of not being able to play the songs from within the game, the gameplay should not suffer much from removing playback altogether (right now, a Justin Bieber song is played when crashing into an asteroid, guess it could become annoying after a while..). On the other hand, if no artist interaction with Spotify can be used (such as getting URIs from artist names etc.), the point of integrating this specific game in spotify would be severely diminished.
What’s good?
Even though Battlefy is simple and hacked together in only a few days, it effectively shows some of the capabilities of the technology supported by both the Spotify platform and the current web generation. Hardware-accelerated graphics, real-time client-server communication and instantaneous input are powerful tools that enable developers to implement wide range of ideas and concepts. It is even possible to build apps that communicate with users not running inside native spotify, such as standard web-browsers or even standalone clients.
Without these traits, we would probably not have been able to build Battlefy during wowhack, some of us were running Spotify under Windows, which seems to lack WebGL-support with the current release. Instead, a stripped-down browser-version was used concurrently with the Spotify app, which worked seemingly well. Most of the game used the same code for both versions, only with slight modifications for the API-specific calls. This means that a user does not necessarily need Spotify to run the game in order to discover new songs or generate automatic playlists from the game sessions.
Aftermath
We had a fun time at the hack, despite the lack of coffee. It was a well arranged event with great people. Thanks for the free food and beers, and of course the Way Out West tickets!
To our surprise, our little hack got us two fine prizes! Everyone in the team got a full year Spotify Premium subscription courtesy of Spotify, and wireless headset courtesy of Sony.
The only downside was that the lack of a public prize ceremony at the end of the event.
If you would like to play the game yourself, head on over to the BitBucket repo where there is some more info how to get it running https://bitbucket.org/andsve/multiplayerspotify/.
Posts by fellow wowhackers
Check out these blog posts by other participants in the #wowhack event!