The Making of Crucial Pain

Recently outofscope has open sourced Crucial Pain, an HTML5 game in which you control a puck through 32 levels with increasing difficulty. You can find it on GitHub, play it online or download it from the AppStore for free.

The rules are fairly simple. When you tap a point on the screen, you accelerate towards it. The greater the distance between you and that point, the faster you go. After tapping, you lose control over the game. When you hit a wall, you lose one of your three lives and in return win back control. Apart from this basic principle there are items, enemies and special walls to spice things up a little. The games title was inspired by the following saying: you can’t do anything until you get hurt, so every move counts and every pain is crucial to win.

The whole development process started when Johannes (one of our founders) created a single prototype level with Impact.js. The basic idea of the game became visible. It was only a rough draft though. It felt sluggish and pretty much none of the final features were present. But it was enough to get me exited and highly motivated to turn this into a full fledged game. Up to this point all the graphics of the release version were more or less done. Johannes got those made from Martin Wackerbauer, a talented designer with a very distinctive style. That was what motivated me most, just by browsing the assets I could perfectly visualize our final product. Grabbing a few sheets of paper, I started scribbling level ideas and sketched out movement patterns deep into the night. The concept was pretty much done by the next morning but one key component was still missing. The game needed a soundtrack that could match its distinctive graphics. Gladly Johannes is a jack of many trades and so he happily set out to compose a few songs to harmonize with the overall visual style.

After a closer look at the prototype and specifically Impact.js, I decided to use a different framework. The landscape of HTML5 game engines and frameworks was vast but nonetheless there was only one valid choice for me and that was phaser.js. I had used it before for my own private projects, where it proved to be fast, accessible and last but not least well documented. It also gave the developer a whole lot of freedom, as there was no specific programming style required or even implied by the API. Phaser came with another major advantage, it could natively read JSON exports from the Tiled map editor, which was probably the most advanced 2d level editor freely available. To package all of the code and to be able to serve it as a mobile app, I opted for phonegap. It came with an included web server, so phaser had no path problems when locating any necessary assets. Apart from that I used coffeescript and grunt to be able to write classes and have a local build system, so that there was only one minified javascript file to be loaded.

The use of coffeescript classes made it so much easier to create a clean and structured code. I created base classes like “Item” or “Walker” and child classes with proper inheritance. This is something that I wouldn’t have imagined in the earlier days of javascript. All of a sudden, it felt as if language had come of age and we were able to build large modular applications with it. Thanks to grunt I was able to separate each class into its own file and sort them into ui, state or system, thus labeling their category. The grunt file contained the correct order of all classes, so it was able to concatenate and minify them, once the build command was given. The assets were located in a separate folder, categorized into fonts, levels, sounds and sprites. I created a preloader file where every asset was registered with an id and the relative path. From there on I could refer to any file just by using its id anywhere in the code.

I was surprised when I realized that implementing physics, map rendering and gameplay was pretty quick and straightforward. The first thing that really made me tax my brain was the camera. I could easily fix it to the player, but the result looked very stiff and boring. It just didn’t reflect the fast and dynamic feeling I was trying to achieve. So I decided to write a “Camera Manager” class that would handle smooth camera motion manually. When the puck moved, it should be followed by a little delay, going faster the further it was away. To achieve that, I created an invisible point that reflected the cameras position. The point was updated once for every frame by the phasers physics module, which would move it towards the last position of the puck. The change of speed didn’t require any additional programming because the physics module accepted parameters for speed and maximum duration when moving an object. Finally, I fixed the camera to the invisible point and achieved the look and feel I was aiming for.

The second task that turned out to be rather challenging was the scaling and sizing of the game to fit any resolution and aspect ratio. I wanted to use all of the available screen space without stretching the canvas, so I had to write a custom class that would manage the size of the camera, the world and all sprites. I created predefined scale multipliers for most iOS devices that were detected by screen size, because our primary plan was to publish Crucial Pain on the AppStore. If the scale manager couldn’t detect the device, it would assume the size of an iPad mini. After the desired dimensions were selected, the game would define them as a safe zone that was then resized proportionally, until it filled either the height or the width of the browser window. At that point the scale was saved and applied to every sprite. If there were empty parts of the browser, they were simply added to the game world. That way all elements kept their aspect ratio but the game still used all of the available space.

The remaining features could be implemented without any bigger problems. Soon I had the final version up and running in my browser. But before being able to publish, it had to be converted into an app and thanks to phonegap, that was as easy as it gets. I created a template project with the command line utility and put the game files into the www directory, then I could open the project in Xcode. After adding icons and splash screens, I submitted it to the AppStore. Ten terribly long days later, Apple approved Crucial Pain. We had published our first game!

A few months passed, we received great feedback from our customers and earned a little money. But then we decided to go open source. There were multiple reasons to take that step. Initially we wanted to enable as many people as possible to play the game, to present what we had created, to prove that it was possible to deliver a fast and smooth gaming experience using nothing but web technologies. But we also strongly believed in the idea of open source. The tools and programs we used to create the game wouldn’t have existed without the countless passionate developers who released their software for free, without expecting anything in return. That is why we felt the urge to give something back to them. That is the reason why Crucial Pain went open source.

Looking back at the project, I’m amazed at how much I could learn from creating a game from the beginning to end. I had a lot of fun writing the code and building the levels, but even more fun playing it and competing with friends. The transformation of the web from simple hypertext documents to something that can deliver a smooth 60fps gaming experience, is still unbelievable to me.

Finally, I want to thank Johannes and Michael for creating a workplace where people can explore new technologies and work on projects they love and care about. Without the two of them, Crucial Pain would have never been possible.

– Jan Geselle

Originally published on outofscope.io.