Skip to content
Monorepo for a multi-player game engine, and game examples
Branch: master
Clone or download
Latest commit 84883de Mar 5, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
docker Fix regression in deployment image for highscores Jun 26, 2018
imj-audio Update submodule Mar 5, 2019
imj-base Add missing BangPatterns Oct 26, 2018
imj-game-hamazed Minor changes, documentation. Feb 5, 2019
imj-game-synths Fix MIDI polling Nov 3, 2018
imj-game-tutorial-increment Bump versions Oct 26, 2018
imj-game Bump versions Oct 26, 2018
imj-measure-stdout Bump versions Oct 26, 2018
imj-music Bump versions Oct 26, 2018
imj-particlesystem Bump versions Oct 26, 2018
imj-prelude Bump versions Oct 26, 2018
imj-profile Bump versions Oct 26, 2018
imj-serve-highscores Bump versions Oct 26, 2018
imj-server Bump versions Oct 26, 2018
imj-space Minor changes, documentation. Feb 5, 2019
imj-time Bump versions Oct 26, 2018
.gitignore Misc. work on UI, Envelopes, Music Jun 3, 2018
.gitmodules Removed submodule Jun 19, 2018
.travis.yml Add response tail subsampling feature Oct 31, 2018
.weeder.yaml Minor changes, documentation. Feb 5, 2019
Brewfile Fix CI Apr 22, 2018 Update doc May 16, 2018 Add 0-latency convolution reverbs, OSX Mojave support, bump stack lts… Oct 18, 2018
appveyor.yml Doc, bump nightly resolver Jun 26, 2018 Fix and update deploy script Jun 3, 2018
stack.yaml Bump stack lts version Oct 28, 2018

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.
  • 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 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.

You can’t perform that action at this time.