Traffic simulation game in Elm

A couple of weeks ago I read about Elm, a new functional language, which compiles to JavaScript and HTML. Elm is designed with the browser in mind, most notably by implementing Functional Reactive Programming (FRP).

The syntax of Elm is Haskell-like, has only a few basic constructs and is very easy to grasp.

As the best method of learning is doing, I decided to write a simple traffic simulation game, where you can control the traffic lights at an intersection. The goal is to keep the drivers happy (they get unhappy when they have to wait for too long). You can see the results here: http://www.warski.org/traffic/, and the source code is of course on GitHub.

2014-01-05_1207

Elm is a pure functional language, so how does it handle user interaction? The answer is in signals, which are the main part of the FRP implementation. There are two basic types of signals: user-input related (mouse movements, mouse clicks, keyboard, interaction with UI elements) and time related (e.g. frames-per-second). Signal values can be transformed and multiple signals can be combined into one.

Thanks to FRP, we don’t have to worry about callbacks and events. All of that is handled behind-the-scenes; we only need to provide code that should be run in reaction to the specific event – when the signal emits a value.

Elm also has quite a rich graphics & UI library. Drawing, manipulating (resizing, rotating), adding images to the canvas, laying out elements is a breeze – and all done in a functional, no-sides-effect way of course.

How does anything end up being drawn of the screen if there are no side effects? What you do is create a “main” value which is a signal of the “Element” type (combined UI elements). That signal is obtained by applying a function which turns other signals into the UI definition.

Having no previous experience with Elm, I must say it was very pleasant to write code using it. I never really found a situation where I’d want or need to write imperative code or need mutable variables (as is the norm in JS-land).

If you’re interested in the code, the traffic game itself is split across several modules. The basis is a “World” record, which holds information about the current game state (cars, traffic lights state). The rest of the modules can be split into three main parts.
1. the UI definition, which lays out the main graphics area, but buttons, and handles the drawing of the cars (Draw and partially UI). This takes a UIWorld record and draws what’s needed.
2. combining the signals from the different buttons, and the frames-per-second signal (Main and UI)
3. updating the game state for a specific period of time. This is basically a Time -> World -> World function. It updates the speed of the cars, their position etc. as needed (all other modules, with Physics.update being the main one)

If you’d like to give Elm a try, there’s a good deal of tutorials and examples on the Elm page. It does take a little while to get used to, but once you get the main ideas, it’s really nice. Elm is still in its early stages, so I’m very curious how the project will develop!