Rocqman is a Pacman-like game written in Rocq and extracted to C++ with Crane. The game uses SDL2 for rendering, SDL2_image for loading the Rocq logo sprite, and small external audio players for sound playback. This establishes, at least informally, that Rocq is Pacman-complete.
- game logic written in Rocq
- extraction to C++ with Crane
- SDL2 rendering
- smooth sprite interpolation
- sound effects for dots, power pellets, ghost kills, losing a life, game over, and victory
You need:
- Rocq with
dune - a C++23 compiler
pkg-config- SDL2
- SDL2_image
Runtime audio also needs a platform player in PATH:
- macOS:
afplay - Linux: one of
mpg123,ffplay, orplay
Clone the repo with everything it needs:
git clone --recurse-submodules https://github.com/joom/rocqman.git
cd rocqmanIf you already cloned it without submodules, run:
git submodule update --init --recursiveInstall the SDL packages with Homebrew:
brew install sdl2 sdl2_imageIf you want to use Homebrew LLVM instead of the system toolchain:
brew install llvmThe exact package names vary by distribution, but you generally need:
sudo apt install clang pkg-config libsdl2-dev libsdl2-image-devFor sound playback, also install at least one of:
sudo apt install mpg123or
sudo apt install ffmpegor
sudo apt install soxBuild the game:
makeThis does three things:
- uses the local Crane checkout in
./crane - extracts
theories/Rocqman.vandtheories/SDL.vto C++ - copies the generated C++ into
src/generated/ - compiles the final executable
./rocqman
Build with a different optimization level:
make OPT=-O2Run the game:
make runor:
./rocqmanControls:
- arrow keys or
WASD: move Space: pause or unpauseQorEsc: quit
Remove build outputs:
make cleanThis removes:
./rocqman./src/generated/./rocqman.dSYM- Dune build outputs
.
├── assets/
│ ├── *.mp3 sound effects
│ └── rocq.svg player sprite
├── crane/ Crane submodule used for extraction
├── src/
│ └── sdl_helpers.h C++ SDL and audio helper functions
├── theories/
│ ├── Rocqman.v game logic, rendering, extracted main
│ ├── RocqmanProofs.v proofs about gameplay transitions and control flow
│ ├── SDL.v Rocq-side SDL bindings and extraction directives
│ └── dune Rocq theory stanza
├── Makefile extraction and native build entrypoint
├── dune-project Dune project file
└── README.md
Generated files are written to:
src/generated/
These are build artifacts and should not be edited manually.
The file theories/RocqmanProofs.v contains machine-checked proofs about the current game logic. At the moment, those proofs show that the pure gameplay transitions used by the frame loop preserve key monotonicity properties: score never decreases, lives never increase, and the number of collectibles left never increases. It also proves that terminal logical states are fixed points of tick, that paused gameplay stays paused until space is pressed, that pressing space while paused returns to Playing, and that WinScreen and GameOverScreen eventually request quit once enough time has elapsed.
- The authoritative game logic lives in Rocq, not in the generated C++.
- The build expects Crane at
crane/. src/sdl_helpers.his the main handwritten C++ integration layer.- The extracted program defines its own
main, so there is no separate handwrittenmain.cpp. - If extraction succeeds but sound does not play on Linux, check that one of
mpg123,ffplay, orplayis installed.
