Installation de Doom Roguelike
STATUS:PAGE LOADED — 2026-07-15

Compilation et installation de DRL (Linux x86-64)

Ce document récapitule toutes les étapes suivies pour configurer, compiler et faire tourner DRL (« That Trademark », the Roguelike) sur cette machine Linux x86-64, y compris le mode graphique (TILES). Environnement de référence : Ubuntu 22.04, FPC 3.2.2, Lua 5.1.5.

Code source : https://github.com/HackTechDev/DoomRoguelike_2608

1. Prérequis déjà présents sur la machine

  • FreePascal fpc 3.2.2 (/usr/bin/fpc)
  • Lua 5.1 lua5.1 5.1.5 (/usr/bin/lua5.1)
  • Outils X11 dev (libx11-dev, libxext-dev, libxrandr-dev, libxcursor-dev, libxi-dev, libxfixes-dev, libxss-dev), libgl1-mesa-dev, cmake, ninja-build, pkg-config (utilisés plus tard pour compiler SDL3)

Aucune installation apt n'a été nécessaire (tout était déjà présent sur la machine, y compris les paquets -dev X11/GL utilisés pour la partie 5).

2. Dépendance obligatoire : fpcvalkyrie

DRL a besoin du moteur bas niveau fpcvalkyrie, un dépôt frère qui n'était pas présent au départ. Cloné à côté du dépôt drl :

cd /home/util01/JEUX/DOOM/DOOMRL
git clone --branch master https://github.com/ChaosForge/fpcvalkyrie.git

Résultat : /home/util01/JEUX/DOOM/DOOMRL/fpcvalkyrie/.

3. Configuration du build (config.lua)

makefile.lua (à la racine de drl/) charge un fichier config.lua gitignoré, à créer à partir du template Linux fourni :

cd /home/util01/JEUX/DOOM/DOOMRL/drl
cp config-linux.lua config.lua

Le chemin par défaut du template pointait vers une machine tierce (/home/epyon/...), corrigé pour pointer vers le checkout réel de fpcvalkyrie :

-- config.lua
VALKYRIE_ROOT = "/home/util01/JEUX/DOOM/DOOMRL/fpcvalkyrie/"
OS = "LINUX"

4. Compilation du jeu

Le build est piloté par lua5.1 makefile.lua <cible>, qui wrap le compilateur FPC (via fpcvalkyrie/scripts/lua_make.lua) et compile aussi l'outil makewad qui empaquette les règles Lua + assets dans des fichiers .wad.

cd /home/util01/JEUX/DOOM/DOOMRL/drl
mkdir -p tmp pkg
lua5.1 makefile.lua lq

Cette commande :

  1. régénère src/version.inc (version + révision git) via le hook pre_build,
  2. compile bin/drl (exécutable du jeu) et bin/makewad,
  3. exécute makewad pour générer bin/drl.wad et bin/core.wad à partir de bin/data/**/*.lua,
  4. tente d'empaqueter une release complète (drl-linux-01010-lq.tar.gz) — cette dernière étape a émis deux cp en échec (bin/data/drllq/sound/*.wav, bin/data/drllq/music/*.mid), car les assets audio sont volontairement absents du dépôt (gitignorés, normalement téléchargés depuis drl.chaosforge.org en CI, cf. .github/workflows/ci.yml). Sans incidence sur la compilation : l'exécutable et les .wad sont bien produits, et le tarball est quand même généré.

Résultat : bin/drl (exécutable x86-64), bin/makewad, bin/drl.wad, bin/core.wad, drl-linux-01010-lq.tar.gz.

5. Vérification en mode console

Test initial en mode texte (curses), plus simple car il ne dépend pas de SDL3 :

cd bin
LD_LIBRARY_PATH=. ./drl -console -nosound -god

Le runtime.log a confirmé un démarrage complet et sans erreur : chargement des modules (core.wad, drl.wad), interprétation de tous les fichiers Lua de règles (beings.lua, items.lua, ai.lua, etc.), initialisation du driver curses. Le jeu attend ensuite une entrée clavier interactive (normal, aucun crash).

-nosound a été utilisé ici car, à ce stade, ni libSDL3.so (mauvaise architecture, voir partie 6) ni SDL3_mixer (absent du dépôt, voir partie 7) n'étaient encore fonctionnels — sans ce flag, l'initialisation audio provoquait un crash. Ce n'est plus nécessaire une fois les parties 6 à 8 appliquées (voir partie 9).

6. Mode graphique (TILES) : diagnostic du crash

Lancer ./drl -god -nosound (mode graphique, sans le flag -console) plantait immédiatement avec EAccessViolation. Le message d'erreur (error.log) pointait vers un crash secondaire dans la routine de nettoyage de fpcvalkyrie (vio.pas / vgenerics.pas), qui masquait la vraie cause.

Root cause trouvée avec gdb

En posant un breakpoint sur le symbole FPC_RAISEEXCEPTION (le point d'entrée du mécanisme d'exceptions Object Pascal), la première exception réellement levée s'est révélée être :

LOAD (vlibrary.pas:68) : Can't load library "libSDL3.so.0.4.0"

C'est un échec de dlopen(). Vérification du fichier fourni dans le dépôt :

file ext/linux/libSDL3.so.0.4.0
# ELF 64-bit LSB shared object, ARM aarch64, ...
file ext/linux/libSDL3_image.so.0.4.0
# ELF 64-bit LSB shared object, ARM aarch64, ...

Cause du bug : les bibliothèques libSDL3.so.0.4.0 et libSDL3_image.so.0.4.0 vendues dans ext/linux/ du dépôt sont compilées pour ARM64, alors que la machine est en x86-64. dlopen() échoue silencieusement (mauvaise architecture ELF), ce qui déclenche une exception Pascal ; le nettoyage automatique de l'objet partiellement construit crashe ensuite à son tour (bug distinct dans fpcvalkyrie), ce qui masquait le vrai message d'erreur. (libfmod.so et libsteam_api.so dans le même dossier sont, eux, bien en x86-64.)

7. Compilation de SDL3, SDL3_image et SDL3_mixer depuis les sources (x86-64)

Pas de paquet SDL3 disponible via apt sur Ubuntu 22.04 (trop récent), et pas de build x86-64 vendored dans le dépôt. Compilation depuis les sources officielles libsdl-org.

Version requise : SDL3_mixer exige SDL3 >= 3.4.0 (find_package échoue sinon). C'est d'ailleurs exactement la branche que fpcvalkyrie attend : le nom de fichier littéral codé en dur (libSDL3.so.0.4.0, voir plus bas) correspond au soname réel d'un build SDL 3.4.x (libSDL3.so.0.4.14 pour la version utilisée ici), pas 3.2.x.

mkdir -p /tmp/.../scratchpad/sdl-build && cd /tmp/.../scratchpad/sdl-build

git clone --depth 1 --branch release-3.4.14 https://github.com/libsdl-org/SDL.git
git clone --depth 1 --branch release-3.2.4  https://github.com/libsdl-org/SDL_image.git
git clone --depth 1 --branch release-3.2.4  https://github.com/libsdl-org/SDL_mixer.git

# SDL3
cmake -S SDL -B build-sdl -G Ninja -DCMAKE_BUILD_TYPE=Release \
      -DSDL_SHARED=ON -DSDL_STATIC=OFF -DSDL_TEST_LIBRARY=OFF
ninja -C build-sdl -j$(nproc)
# -> build-sdl/libSDL3.so.0.4.14

# SDL3_image (lié contre le SDL3 fraîchement construit)
cmake -S SDL_image -B build-sdlimage -G Ninja -DCMAKE_BUILD_TYPE=Release \
      -DBUILD_SHARED_LIBS=ON -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_TESTS=OFF \
      -DCMAKE_PREFIX_PATH="$PWD/build-sdl" -DSDL3_DIR="$PWD/build-sdl"
ninja -C build-sdlimage -j$(nproc)
# -> build-sdlimage/libSDL3_image.so.0.2.4

# SDL3_mixer : nos assets sont uniquement .wav/.mid, donc seuls wave+midi(timidity)
# +aiff/voc/au sont activés. Ça évite aussi d'avoir besoin des sous-modules git
# vendored de SDL_mixer (ogg/vorbis/opus/flac/mpg123/gme/xmp/wavpack), qu'un
# `git clone --depth 1` ne récupère pas.
cmake -S SDL_mixer -B build-sdlmixer -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON \
      -DSDLMIXER_VENDORED=ON -DSDLMIXER_DEPS_SHARED=OFF \
      -DSDLMIXER_FLAC=OFF -DSDLMIXER_GME=OFF -DSDLMIXER_MOD=OFF -DSDLMIXER_MP3=OFF \
      -DSDLMIXER_OPUS=OFF -DSDLMIXER_VORBIS_STB=OFF -DSDLMIXER_VORBIS_VORBISFILE=OFF \
      -DSDLMIXER_WAVPACK=OFF -DSDLMIXER_MIDI=ON -DSDLMIXER_WAVE=ON \
      -DSDLMIXER_TESTS=OFF -DSDLMIXER_EXAMPLES=OFF -DSDLMIXER_INSTALL=OFF \
      -DCMAKE_PREFIX_PATH="$PWD/build-sdl" -DSDL3_DIR="$PWD/build-sdl"
ninja -C build-sdlmixer -j$(nproc)
# -> build-sdlmixer/libSDL3_mixer.so.0.2.4

Les trois builds ont réussi sans dépendance manquante (X11/GLX/mesa déjà présents ; libtiff/libwebp système détectés automatiquement pour SDL3_image, les autres formats en mode vendored/stb).

Installation dans bin/

Le nom de fichier exact est important : le code Pascal (vsdl3library.pas / vsdl3imagelibrary.pas / vsdl3mixerlibrary.pas) fait dlopen() sur des noms littéraux (libSDL3.so.0.4.0, libSDL3_image.so.0.4.0, libSDL3_mixer-3.0.so.0), peu importe le vrai soname produit par le build :

cp build-sdl/libSDL3.so.0.4.14              bin/libSDL3.so.0.4.0
cp build-sdlimage/libSDL3_image.so.0.2.4    bin/libSDL3_image.so.0.4.0
cp build-sdlmixer/libSDL3_mixer.so.0.2.4    bin/libSDL3_mixer-3.0.so.0

file confirme des binaires ELF x86-64 valides, et ldd ne montre plus aucune dépendance manquante.

Deux bugs trouvés dans fpcvalkyrie (branches master et development)

Même avec la bonne lib installée, SDL3_mixer refusait toujours de charger. Diagnostic via gdb (breakpoint sur FPC_RAISEEXCEPTION, qui intercepte la première exception Pascal réellement levée, avant que le bug de nettoyage-après-échec-de-constructeur ne la masque) :

  1. Symboles inexistants dans les bindingslibs/vsdl3mixerlibrary.pas référence MIX_TrackLooping et MIX_SetMasterGain/MIX_GetMasterGain, qui n'ont jamais existé sous ces noms dans aucune version de SDL3_mixer (vérifié via git log -S sur tout l'historique du dépôt SDL_mixer). Les vrais noms sont MIX_GetTrackLoops et MIX_SetMixerGain/ MIX_GetMixerGain. Comme GetSymbol() lève une exception fatale au moindre symbole manquant (et qu'aucun de ces trois bindings n'est utilisé ailleurs dans fpcvalkyrie), ce simple mismatch de nom empêchait SDL3_mixer de se charger, quelle que soit la version installée. → un audit de tous les symboles attendus (extraits par regex depuis le fichier) contre le header réel de SDL_mixer a confirmé que ces deux paires étaient les seules incohérences.

  2. SDL3 (la lib de base) jamais chargée en mode audio seulsrc/vsdlaudio.pas (TSDLAudio.Create) appelle LoadSDL3Mixer mais jamais LoadSDL3. En mode graphique ça fonctionnait "par accident" car le driver vidéo (TSDLIODriver) avait déjà appelé LoadSDL3 avant que l'audio ne s'initialise. En mode -console (pas de driver vidéo), SDL_Init restait un pointeur de fonction nul → EAccessViolation à l'adresse 0x0.

Correctifs appliqués (dans le checkout ../fpcvalkyrie, pas dans le dépôt drl) :

# libs/vsdl3mixerlibrary.pas
- MIX_TrackLooping             : function(track: PMIX_Track): Boolean; cdecl;
+ MIX_GetTrackLoops             : function(track: PMIX_Track): Integer; cdecl;
- Pointer(MIX_TrackLooping)             := GetSymbol('MIX_TrackLooping');
+ Pointer(MIX_GetTrackLoops)            := GetSymbol('MIX_GetTrackLoops');
- MIX_SetMasterGain            : function(mixer: PMIX_Mixer; gain: Single): Boolean; cdecl;
- MIX_GetMasterGain            : function(mixer: PMIX_Mixer): Single; cdecl;
+ MIX_SetMixerGain              : function(mixer: PMIX_Mixer; gain: Single): Boolean; cdecl;
+ MIX_GetMixerGain              : function(mixer: PMIX_Mixer): Single; cdecl;
- Pointer(MIX_SetMasterGain)            := GetSymbol('MIX_SetMasterGain');
- Pointer(MIX_GetMasterGain)            := GetSymbol('MIX_GetMasterGain');
+ Pointer(MIX_SetMixerGain)             := GetSymbol('MIX_SetMixerGain');
+ Pointer(MIX_GetMixerGain)             := GetSymbol('MIX_GetMixerGain');

# src/vsdlaudio.pas (TSDLAudio.Create)
  inherited Create;
+ if not LoadSDL3 then
+   raise EAudioException.Create('Unable to load SDL3');
  if not LoadSDL3Mixer then
    raise EAudioException.Create('Unable to load SDL3_mixer');

Après ces deux correctifs et un rebuild (lua5.1 makefile.lua lq), TSDLAudio s'initialise proprement (<TSDLAudio//0> Initialized.) aussi bien en -console qu'en mode graphique, sans crash à la fermeture non plus.

8. Téléchargement des assets audio

Les fichiers .wav/.mid sont gitignorés (absents du dépôt) et normalement récupérés en CI depuis drl.chaosforge.org (voir .github/workflows/ci.yml). Même procédure ici :

mkdir -p bin/data/drllq/music bin/data/drllq/sound
curl -skfL https://drl.chaosforge.org/music_lq.zip -o music_lq.zip
curl -skfL https://drl.chaosforge.org/sound_lq.zip -o sound_lq.zip
unzip -oq music_lq.zip -d bin/data/drllq/music/
unzip -oq sound_lq.zip -d bin/data/drllq/sound/

Le -k (insecure) est nécessaire car le certificat TLS de drl.chaosforge.org ne valide pas (problème côté serveur, pas un souci de confiance local) — la CI officielle du projet contourne le même souci en pratique. Les zips (music_lq.zip, sound_lq.zip, et leurs équivalents _hq) ont été vérifiés avec unzip -tq avant extraction.

9. Lancement en mode graphique (avec son) et capture d'écran

cd bin
DISPLAY=:0 LD_LIBRARY_PATH=. ./drl -god

Le runtime.log progresse cette fois normalement jusqu'à <TSDLIODriver> SDL IO system ready., une fenêtre "DRL" s'ouvre (1920×1200), sans aucune entrée dans error.log. Capture réalisée via :

wmctrl -lG                              # récupérer l'ID de la fenêtre DRL
import -window <id_fenetre> screenshot.png

Résultat : le menu principal du jeu s'affiche correctement (logo DRL, artwork, menu New game / Challenge game / Settings / etc.), confirmant que le rendu graphique (SDL3 + OpenGL) et le son (<TSDLAudio//0> Initialized., aucune entrée dans error.log) fonctionnent pleinement une fois les bonnes bibliothèques en place et les correctifs fpcvalkyrie appliqués.

10. Script d'automatisation

Toutes les étapes ci-dessus (hors diagnostic) sont scriptées dans build_install.sh, à la racine du dépôt : clonage de fpcvalkyrie, application des deux correctifs SDL3_mixer, génération de config.lua, compilation du jeu, build de SDL3/SDL3_image/SDL3_mixer si les libs vendored ne correspondent pas à l'architecture hôte, et téléchargement des assets audio. Idempotent (relançable sans dupliquer le travail déjà fait).

./build_install.sh [lq|hq|all]   # cible de build, lq par défaut
./build_install.sh --skip-sdl    # ne pas (re)vérifier/compiler SDL3/SDL3_image/SDL3_mixer
./build_install.sh --skip-audio  # ne pas télécharger les assets audio

Résumé des fichiers modifiés / créés (hors dépôt git ou gitignorés)

Fichier Rôle
../fpcvalkyrie/ (dépôt cloné) Dépendance moteur obligatoire
../fpcvalkyrie/libs/vsdl3mixerlibrary.pas, ../fpcvalkyrie/src/vsdlaudio.pas Patchés (bugs de bindings SDL3_mixer, voir partie 7)
config.lua Config du build (chemin vers fpcvalkyrie, OS)
bin/config.lua SoundEngine laissé à "DEFAULT" (= SDL sur Linux, fonctionne maintenant)
src/version.inc Autogénéré par le build (version + révision git)
bin/drl, bin/makewad, bin/*.wad Sorties de compilation
bin/libSDL3.so.0.4.0, bin/libSDL3_image.so.0.4.0, bin/libSDL3_mixer-3.0.so.0 Builds x86-64 (les .so vendored ext/linux/ correspondants sont en ARM64 ou absents)
bin/data/drllq/{music,sound}/* Assets audio téléchargés (gitignorés, absents du dépôt)
drl-linux-01010-lq.tar.gz Package packagé par makefile.lua lq
build_install.sh Script qui automatise tout ce qui précède

11. Captures d'écran

drl01.png

drl02.png

drl03.png