One of the issues with this request was the timeframe — three weeks to build the game to coincide with an album release, and with a tiny budget. On top of that, the game had to work on desktop, Android, and iOS.
So, Hunter rationalized and decided to accept the project.
“Optimism is an occupational hazard of programming”
After accepting the project for what he thought would be a small, indie release, Hunter realized that the artist (Rustie) was huge in the UK and overseas, and this release would be a huge deal.
”That’s when I realized that it wasn’t me helping out this no-name artist… *I* was the no-name artist, and he was giving me an opportunity.”
Hunter built a custom rendering engine for the game that renders about four million rays per second in canvas.
Check out the demo. You wander around a large, procedurally-generated world, and you find golden stones which allow you access to certain songs. There are lots of hidden challenges. In the maze, if you get lost, it plays a song called “Lost.”
“I’m really bad at my own game. I’m not going to solve the maze… because I can’t.”
One month later, Apple introduced WebGL for iPhone and iPad. In addition to learning a lot about trigonometry, Hunter had his game featured in Kotaku.
Application Interfaces Are Becoming More Like Games
“Building a simple game is harder than building most complex web applications.”
1. Minimize and isolate state
Game developers don’t have that luxury.
Originally we had a huge state object that would keep track of speed, direction, and current animation frame. Instead, we used pure functions, which are super powerful.
The idea behind a pure function is that it has no side effects; it changes nothing. It takes some input and returns some type of output. Instead of creating a huge state object, we created a few pure functions:
var velocity = this.getVelocity(state.x, state.y, state.interval);
var direction = this.getDirection(velocity);
var pose = this.getPose(state.distance);
var frame = this.getFrame(direction, pose);
There are no variables set in these pure functions. We can learn from game developers to use pure functions to remove as much state as you can.
2. Enforce deterministic rendering
If you have state, you should be able to send it to your renderer, and it should be able to render everything based off that data. This is important because it makes sure that you’re encapsulating all your state in your state objects. If you have stage distributed through your application, it makes it difficult to undo and redo, and also save the current state of the application.
In gaming, this is especially important for multi-player games. If your state can’t be transformed into JSON, it will make multiplayer game development more difficult.
3. Separate rendering and simulation
Let’s understand that simulation is what leads to good animation. Modern interfaces require simulation: scrolling with momentum and bounce, or draggable icons with weight, mass and friction
Hunter ends the presentation by discussing his favorite bug ever.