Chrome extension based campaign

Last year, our friends at TBWA\ asked us to create a Chrome extension for their client Adressändring. Adressändring’s services are normally used to forward mail when moving to a new place, and now they wanted to reach a younger demographic. This Chrome extension forwards a user’s social life by taking over banner space, much like Adblock. Instead of removing the banners, as Adblock does, it swaps them for feeds from Facebook, Twitter and Instagram.

Technically this meant alot of black magic and unconventional methods. Serverside we didn’t want to make lookups in a database, or fetch data from an API, for every banner rendered. If a user enters Aftonbladet.se, we have to render at least 15 content areas from our servers, so these servers need to serve only static content to keep up with even a small load.

We decided to store all data in static json files on the server, serving them via Nginx. When the user installs the extension, we make a request to the server to create a new user (= a new json-file). As a response to the request, the server returns the identifier and stores it in localStorage. Access tokens from the various social media sites are then stored in this file.

When a user browses the web, the extensions makes a timed request to update the users feeds (= json files). This way the user will always get semi fresh social feeds from the server, and can request static files from Nginx. We had to set up both http and https so the security zones wouldn’t get mixed.

Two things we wish we would have had time to do:
– offload all json files to S3.
– instead of having the extension tell the server when to update a users feeds, we first planned on tailing the Nginx access log with a go or python script. Then we would have grep’d the user identifier, and depending on server load the script would decide if a user’s feeds should be updated or not.

The Chrome extension itself may get a separate blog post eventually. This got way too long anyway.
Oh, feel free to try out the extension!

http://post-forward.com

Asynchronous game in real time

We made a game, a mobile racing game for Red Bull. Sort of in the trails of Chrome Racer, but even more fun we think. We used some cool stuff that we’ve written about here before – html5 audio, multiplayer gaming with websockets and node.js, but also stuff that was new to us, the vector scripting library paper.js, canvas animation and angular.js.

The first mindboggle was the question of where the race actually is taking place. The game is multiplayer and also a competition, so we needed to make sure the race synced well across multiple devices, but also that the game was correct in deciding who’s winning and what time you get. We started out with presuming that the game had to take place in real time on the server, and the server could push your car or hold it back when you got out of sync with the server, or crash it when you took a curve too fast, but in bad conditions with network latency the racing got twitchy. So the gaming experience hurt – no good.

racing-twitchy
Blue car is weirding out.

It was best to leave your car be. If your opponents get jittery on bad reception it’s ok, as long as your own car moves smoothly. So if the client is controlling the race, how do we know it’s not spoofing a killer race time? The conclusion was that the race must take place both in your browser and on the server, and the server rules when it comes to the actual result.

If the server doesn’t interfere with your driving it doesn’t have to work in real time either. There’s no clock running on the server so to speak. The server sets a start time, you tell the server when you’re throttling and when you’re not (or actually when you did throttle, due to latency we work with past tense data – the player throttled 0.2 seconds ago), and the server calculates the race, and where it thinks you should have crashed. Does nothing with this data, just quietly executes the race in an asynchronous manner. Since it just waits for events to come in it doesn’t really know or care where you are at this exact moment, not even at the finish line. Your race time is calculated when the server simulates your final run towards goal and sees that this gal was over the finish line at 16.34.

The server basically take your actions and recreates your race on the server piece by piece, while simultaneously sending out the same data to your opponents, and finally sets your race time with no consideration of the time you said you finished at. Latency matters at race start, if you’re on a bad connection you get a late start, but at the end and during the race it doesn’t matter at all. Your opponents will just look like drunk chinchillas on the race track.

Play the game on your phone: www.redbullracechallenge.se