<!-- TOC depthFrom:1 depthTo:6 withLinks:1 updateOnSave:1 orderedList:0 -->

<!-- /TOC -->

What is it?

Monorepo for a Haskell multi-player game engine and games made with it. Build Status

The games can be played locally, in single-player mode, or in multi-player mode, after having run the [deployment script] to host the game server on Heroku.

You can even create your own multi-player game, starting from the tutorial-game.

Supported platforms

Officially supported client platforms are (recent versions of) macOS and Ubuntu, where a C++17-enabled compiler is available.


List of packages, inverse-topologically sorted wrt dependencies, with keywords / short description for each of them:

  • imj-audio
    • Bindings to a C++17 lock-free audio engine.
    • The C++ sources are located in submodules.
  • imj-music
    • Polyphonic music scores creation and playback.
  • imj-prelude
    • Prelude library used by packages hereunder, mainly to factorize imports.
  • imj-time
    • Timing library based on the system monotonic clock.
  • imj-base
    • Containers (Graph, Matrix, Cyclic matrix, Dynamic vector, etc...)
    • Geometry, text animations
    • 8-bit color manipulation in different color spaces
    • Easing, inverse-easing, interpolation, rectangular frame morphing.
    • Physics
    • UI components building blocks
    • Chat
    • Rendering backends, using delta-rendering:
      • In a GLFW-driven OpenGL window
      • In the terminal
    • Player input, window management.
  • imj-space
    • Randomized creation of 2D game levels, given some topological constraints.
  • imj-particlesystem (formerly imj-animation)
    • Physics-based and geometric particle systems.
  • imj-measure-stdout
    • An executable to measure the maximum capacity of stdout, and observe the effect of different buffering modes. This was used while developing delta-rendering.
  • imj-server
    • Using websockets to communicate between server and clients.
    • Broadcast messages to all clients
    • Handle connection failures generically (so that a client handler, when broadcasting a message, won't have to handle exceptions due to another client's connection being down.)
    • Detect client reconnection (keep track of clients identities using their MAC address)
    • Logging
  • imj-serve-highscores
    • Servant-based web service to persist and access highscores.
  • imj-game
    • Multi-player game engine
    • Listens to server events, and player events
    • Handles generic events, so that the game implementation contains only game-specific code.
    • Real-time music playback.
    • Debugging features : record and display events graphically, event logging.
  • imj-game-tutorial-increment
    • A tutorial on how to use imj-game to build a multi-player game.
  • imj-game-synths
    • "A jam session, in the cloud, with loops and synthesizers."
    • Players are playing music together, in real-time, using either real MIDI devices, or computer keyboards.
  • imj-game-hamazed
    • You're a ship pilot, shooting at flying numbers.
    • Each level has its own original music!
    • Levels generation is randomized, so that you will (very likely) never play the same game twice.
    • Demo (when the game was mono-player and had no music): asciicast
  • imj-profile
    • An executable precomputing optimal strategies used for random level generation.
    • And other profiling tests.

Development setup

After checking out the repo, run git submodule init && git submodule update to download the submodules.

Install dependencies (C libraries)

To install them:

  • On OSX:
brew install ftgl
brew install portaudio
brew install postgresql
  • On Linux:
sudo apt-get update
sudo apt-get install ftgl-dev
sudo apt-get install portaudio19-dev
sudo apt-get install postgresql
sudo apt-get install libpq-dev


stack is the preferred tool to build the project:

stack build --pedantic

A recent enough C compiler should be used by GHC, so as to be able to build C++17.

Run the games in single-player mode

Passing no command line argument will run the games in single player mode:

stack exec <game-executable>

Deploy a game server for Multi-player mode

Use the [deployment script] to host the games on a Heroku server.

Run the games in Multi-player mode

Connect to a running game server

stack exec -- <game-executable> -n <serverName> -p<serverPort>

Connect to a Heroku-hosted server

When the game server is hosted on Heroku, the port to connect to is 80:

stack exec -- <game-executable> -n <herokuAppDomain> -p80


The [CI script](/.travis.yml) verifies that compilation and tests succeed with GHC versions 8.2.2 and 8.4.3.

Game engine highlights



Melodies are written using the notes quasiquoter, where:

  • notes names follow the solfege notation
  • a note can be shifted by octaves using v and ^
  • - extends the preceding note
  • . indicates a pause


Every game made with imj-game can have the server send midi-like note on / note off events to game clients, allowing to perfectly synchronize the music with the game.

The music won't pause during garbage collection because we use an audio engine whose audio realtime thread is not managed by the GHC runtime.


The screen is conceptually divided in small blocks of equal size, where each block can contain a character with 8-bit background and foreground colors.

The fonts and font size for rendering can be modified at run time.