Tutorial: Building
From empty folders to a running game and a passing ctest on Linux, then the web build.
This walkthrough uses Debian or Ubuntu package names and the directory names the project itself uses. It takes a while the first time, mostly because CNA builds SDL from source on its first configure. Background and every alternative are in the Build Guide.
1. Install the tools
You need CMake 3.23 or newer, a C++23 compiler (GCC or Clang), Ninja and git, plus the development packages SDL builds against. The full package list is on Getting Started; it starts with:
sudo apt-get install -y --no-install-recommends \
build-essential ninja-build pkg-config cmake git \
libasound2-dev libpulse-dev libx11-dev libxext-dev ... # see Getting Started
Add xvfb if you want the demo-replay test and headless runs. If your distribution's
CMake is older than 3.23, install a newer one first: easy-gl and meta-gl require it.
2. Clone the game and its siblings
Everything goes into one parent folder. The siblings are ordinary clones, not submodules.
mkdir eggbert && cd eggbert
git clone https://github.com/openeggbert/galaxy-eggbert.git
git clone https://github.com/libcna/cna.git
git clone https://github.com/libcna/cna-engine.git
git clone https://github.com/libcna/easy-gl.git
git clone https://github.com/libcna/meta-gl.git
git clone https://github.com/libcna/sharp-runtime.git
# test data for two tests: only the worlds/ folder of mobile-eggbert
git clone --filter=blob:none --sparse https://github.com/openeggbert/mobile-eggbert.git
git -C mobile-eggbert sparse-checkout set worlds
3. Match the revisions CI builds
The newest CNA may be ahead of what the game was last checked against. The safe set is the one
in galaxy-eggbert/.github/workflows/cna-ci.yml (its ref: lines). As of
2026-11-10:
git -C cna checkout 594eb28dc5129b20c822d51032fd0c02e20a55d8
git -C cna-engine checkout 6737a1cf0895df3e4de73776ad1052e06e49541f
git -C easy-gl checkout b582bd85f646678d1de38473160defed4729f323
git -C sharp-runtime checkout c793ef3e886043b565749b071c6514cedc805b75
git -C meta-gl checkout 795bcdcfe9e2c418ced189717d3699cbb0847cc0
git -C cna submodule update --init # SDL3, SDL3_mixer, ... (not recursive)
Initialise CNA's submodules after the checkout, so they match the CNA revision.
4. Configure
cd galaxy-eggbert
cmake -S . -B build-cna-opengl3 -G Ninja \
-DCMAKE_BUILD_TYPE=Release -DCNA_GRAPHICS_RENDERER=OPENGL33
Expect several minutes the first time: CNA builds SDL3 and SDL3_mixer, and CMake downloads
GoogleTest. The log names the CNA and cna-engine folders it found and includes
GalaxyEggbertCNA target enabled (maintained playable game). If ccache is installed,
add -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache to make
later rebuilds faster.
5. Build and run the game
cmake --build build-cna-opengl3 --target GalaxyEggbertCNA --parallel 4
cd build-cna-opengl3
./GalaxyEggbert
Pick a lower --parallel number if the machine runs short of memory. The build copies
the game's assets into the build directory; always start the game from there. Press F1 in the game
for the controls. To jump straight into a mission without the menus, try
./GalaxyEggbert --mission 12 (Running the Game lists every
flag).
6. Build everything and run the tests
cd .. # back to galaxy-eggbert/
cmake --build build-cna-opengl3 --parallel 4
ctest --test-dir build-cna-opengl3 --output-on-failure
The tests are separate executables, so the whole tree must be built first. Once built they take
seconds. A good run ends with 100% tests passed, 0 tests failed out of N (N was 120 on
2026-11-10; it is a little lower without xvfb-run, which the demo-replay test needs).
What each test covers: Testing.
7. Build for the web
Install and activate the Emscripten SDK once:
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk && ./emsdk install latest && ./emsdk activate latest && cd ..
Then, in a separate build directory (never reuse the desktop one):
source emsdk/emsdk_env.sh
cd galaxy-eggbert
emcmake cmake -S . -B build-cna-webgl2 \
-DCNA_GRAPHICS_RENDERER=WEBGL2 -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF
cmake --build build-cna-webgl2 --target GalaxyEggbertCNA --parallel 4
emrun build-cna-webgl2/GalaxyEggbert.html
The result is GalaxyEggbert.html, .js, .wasm and
.data plus a Content/music/ folder. Serve them over HTTP; a
file: URL does not work. Click into the page if the sound does not start.
If something goes wrong
| Symptom | Fix |
|---|---|
CNA not found at '...' or cna-engine not found at '...' | Clone it beside galaxy-eggbert, or pass -DCNA_HOME=<path> / -DCNA_ENGINE_HOME=<path>. |
CNA: Missing sharp-runtime checkout at ... | Clone sharp-runtime next to cna (or set CNA_SHARP_RUNTIME_ROOT). |
Errors that mention missing SDL sources under cna/third_party/ | Run git -C cna submodule update --init. |
renderer SDL_GPU ... was renamed to SDLGPU | Use the new spelling, -DCNA_GRAPHICS_RENDERER=SDLGPU. |
OPENGLES3 is a desktop/mobile GL renderer and cannot target Emscripten | A desktop renderer reached a web configure: use a fresh directory for emcmake, with WEBGL2. |
| The game starts but finds no worlds or models | Start it from its build directory, not through a symlink or from the source folder. |
VerifyMoveObjectTypesCna and VerifyBigDecorParsingCna fail | They need ../mobile-eggbert/worlds/ (step 2). |
Next
- Build Guide - the Linux bundle, Android, Windows, CI.
- Configuration - options, environment variables, settings.
- Tutorial: Modifying Levels - make a world of your own.