Elm is getting a lot of traction these days. It is a fully functional language with a strong type system that compiles to JavaScript, so naturally we’ve been wanting to learn it! During our recent Hack Week, we found the perfect opportunity after realizing that Zalando was in dire need of an awesome game on our 404 page. Using Elm, we created 404 Elm Street: a browser game in which you play Joe, a courier who deliver packages to Zalando customers and shuttles returns back to the company. Players have to plan Joe’s route carefully to prioritize deliveries and pick-ups at top speed. It’s a challenge!

Among the four of us who developed 404 Elm St., one of us had used Elm to develop a Flatris clone, one was new to functional programming, and two were experienced functional programmers eager to try Elm. Here’s how we got the job done while learning a new language on the fly.

Day One: Basic Framework and Sprite Rendering

At Zalando, we always try to put ourselves in our customer's shoes. With 404 Elm St., we wanted to put our customers in our shoes for a change. After brainstorming a minimum set of features, our team got to work.

Kolja (senior front-end engineer, ClojureScript enthusiast, illustrator) created the first animated sprites

Andrey (senior front-end engineer, author of the aforementioned Flatris clone) put the raw framework together and the code to animate the sprites

Vignesh (senior front-end engineer) got up to speed with Elm

Arpad (front-end engineer) worked on an A* algorithm to generate a pathfinder for Joe

At the end of the day, we had created a map featuring houses and an animated fountain.

Day Two: A* Pathfinding FTW

Arpad finished his work on the algorithm; Andrey coded a mock page for pathfinding that used SVG to draw a calculated path; Andrey and Vignesh pair-programmed and came up with a code model and game logic; and Kolja sketched.

The results: A working pathfinding algorithm and a map with actual game objects (houses, warehouses, trees, fountains and Joe).

Day Three: Game Logic Focus

We rendered different items and made sure that Joe was mobile. Andrey continued working on the game logic and event handling, and Kolja continued drawing. By day’s end, Joe could move around in eight different directions and follow paths.

Day Four: Putting Things Together

We went open source on GitHub! We also added click-handling and other components, and Kolja finished drawing the customers.

Day Five: Final Presentation

We set up a booth at the Hack Week project fair and demonstrated the game for our colleagues. Thanks to Vignesh’s implementation of continuous deployment, we were able to add features and fix bugs during the fair. When our booth visitors refreshed the screen, they saw our improvements.

Elm Discoveries

Elm can be quite challenging, and not everyone on our team was able to understand it completely. Adhering to a purely functional paradigm was something new for us, even if we’d previously written functional code in JavaScript. In most cases, we could agree on a function’s signature and make it return a hardcoded value; then one of us would take care of implementation. We also organized our data structures to reduce the scope of the functions. Instead of keeping multiple lists of articles for each location (be it a delivery person, a warehouse or a house), we placed all articles in one list and used location as a tag. This allowed us to quickly iterate over and filter out the articles that we needed, instead of collecting them from different locations.

Coming from JavaScript backgrounds, our team had to adjust to Elm’s immutability. Some of us even wrote functions that compare records by checking the equality of each field, when a simple “==” operator was enough. This actually helped us a lot by linking game objects together; a game object effectively became its own foreign key inside another object. One thing we learned to keep in mind, however, was that changing an original object necessitated updating all of its copies.

Finally, we learned that our algorithm really needed to be streamlined, or else the code would turn out ugly and complicated. Elm makes it obvious what needs to be refactored or rewritten in the future.

Once we’d established all the necessary primitives around the Elm architecture, our productivity increased quickly. Using JavaScript would have required setting up the boilerplate code of Webpack, Babel etc., and would have stolen much more time.

The Elm compiler helped us greatly — allowing us to toss code around quickly, rename functions, and change types, while remaining confident about the results. The compiler also helped us resolve a cyclic dependency issue by showing nice ASCII art of the dependency loop.

Conclusion

We had a great time making the game, and are still improving it; go here to contribute, share issues, and send pull requests. Some of our plans:

create “Start” and “Game Over” screens

add sound (if you’re a sound engineer, drop us a line at andrey.kuzmin at zalando dot de!)

put this thing on an actual 404 page!

We’re also continuing our work with the Elm language, and have created a guild that will allow us to pursue things further.