ElixirQuake

Quake, written in Elixir, played in a terminal. The renderer, the BSP world, collision hulls and sliding moves are Cauldron's (cauldron_3d); this package reads Quake's files and runs the game: the QuakeC program from progs.dat on a QuakeC virtual machine, Quake's server physics and monster movement, the builtins the program calls, and the client's screen — models, particles, the status bar, sounds.

mix deps.get
mix quake --dir path/to/quake
mix quake --dir path/to/quake --map e1m1 --skill 2

--dir is the game directory holding pak0.pak (or the directory above its id1). Set QUAKE_DIR to skip it. The game starts on start, the hub where the episode and skill are chosen by walking, unless --map says otherwise.

On a terminal that keeps images (kitty, Ghostty, WezTerm, iTerm2) the picture is drawn at Quake's own 320×200 and the terminal scales it to the window, so a small font gives more room without a blurrier picture; native:2 is sharper and costs about twice the time a frame. --picture (or CAULDRON_PICTURE, or config :cauldron_2d_drafter, picture: "..." in a config/runtime.exs) chooses otherwise, with any of these comma separated: native draws at Quake's own size times the largest whole number that fits the window, native:N at N times, size:WxH sets the size itself, png sends each frame as a PNG (about a third smaller, for play over ssh, at more CPU), swap replaces each frame without a blank between, and none draws at the window's cells instead. The default is native:1,swap.

No game data is included. Two sources work:

The view keeps Quake's vertical field of view, that of 90 degrees across a 4:3 screen, so a wide terminal sees further to the sides rather than losing the bottom of the view and the weapon in hand.

Keys

Key Action
W S or ↑ ↓ forward, back
A D strafe
← → turn
T G or PgUp PgDn look up, down
C or End look straight ahead
F fire
Space jump, swim up
R (held) run
Q E previous, next weapon
1–8 a weapon
Esc the menu

Esc opens Quake's own menu, drawn from the game's pictures and paused while open: single player (a new game), options, help and quit. Options holds customize controls (Enter then a key or mouse button to bind it, Backspace to clear), reset to defaults, screen size, brightness, mouse speed, sound volume, always run, invert mouse and use mouse; they are saved per player. The mouse is off until "use mouse" is on: then moving it turns and looks, the left button fires, the right button runs, and the wheel changes weapon. Multiplayer, loading and saving say they are not part of this game.

A controller works too: the left stick walks and strafes and the right stick turns and looks, each as far as it is pushed; the right trigger fires, the left trigger (or pressing the left stick) runs, A jumps, X looks ahead, the bumpers change weapon and Start opens the menu, where the d-pad moves, A chooses and B goes back.

What is here

What is not

How it is built

Three packages shared with other games carry the engine:

This package is the game around them:

Speed

On one Apple M-series machine, a server frame of the shareware's first level takes about 0.4 ms, and of LibreQuake's largest about 1 ms; a 240 by 150 picture with its surfaces made takes 20 to 40 ms. Everything is Elixir; drawing is spread over the schedulers.

Tests

mix test
QUAKE_DIR=path/to/quake mix test

Without QUAKE_DIR the test that plays a level is skipped.

Licence

GPL-2.0-or-later. Quake's source was released by id Software under the GPL; the server physics, monster movement, builtins, client effects and the model normals here follow it closely, so this package is a derivative of that source. Cauldron, which it runs on, is MIT and contains no Quake code or data.

Quake's own data — the shareware and registered paks — is id Software's (now ZeniMax's) and is not covered by that release; this package only reads it from files the player supplies. LibreQuake's data is under its own licences.