Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/retired64/sm64coopdx_launcher/llms.txt

Use this file to discover all available pages before exploring further.

The SM64 Coop DX Launcher produces two separate streams of diagnostic output: a log file that captures everything the game process writes to stderr, and the launcher’s own structured log messages that are emitted to the terminal through the env_logger crate. Understanding both streams lets you pinpoint the exact point of failure — whether the problem is in the launcher’s startup logic, the binary path resolution, or deep inside the game process itself.

Game stderr log

The launcher redirects the game process’s standard error stream to a file on every launch. The file is created fresh each time the game is started, so previous output is always overwritten. Log file location:
~/.local/share/sm64coopdx/game_stderr.log
This path is constructed from the GAME_STDERR_LOG constant ("game_stderr.log") joined to the launcher’s data directory (~/.local/share/sm64coopdx/), as defined in config.rs. The launcher passes a Stdio::from(stderr_file) handle to the spawned Command, so all game-side errors — including OpenGL failures, audio device errors, Lua script panics, and ROM load failures — end up here. Reading the log after a crash:
cat ~/.local/share/sm64coopdx/game_stderr.log
Following it live while the game is running:
tail -f ~/.local/share/sm64coopdx/game_stderr.log
The game’s standard output (stdout) is discarded (Stdio::null()). Only stderr is captured. If a game-side feature prints diagnostics exclusively to stdout, those messages will not appear in the log file.
Open a second terminal and run tail -f before pressing Enter in the launcher. This gives you a real-time view of game stderr from the moment the process spawns, which is especially useful for catching early initialization failures that happen before a window appears.

Launcher logs (env_logger)

The launcher uses the Rust log crate with env_logger as the backend. By default, only error and warn messages are shown. Raising the log level reveals the full path-resolution chain and every decision the launcher makes before the game is spawned. Enable debug-level logging:
RUST_LOG=debug ./sm64coopdx-launcher
Available log levels (least to most verbose):
LevelWhen to use
errorDefault — only fatal issues
warnIncludes fallback warnings (e.g. a configured path not found)
infoShows key milestones: path resolution, ROM discovery, spawn command
debugFull trace of every decision; recommended for bug reports
Filter logs to the launcher only (suppress noisy dependencies):
RUST_LOG=sm64coopdx_launcher=debug ./sm64coopdx-launcher

Key log messages to look for

The following messages appear at info level and above. They mark the most important steps in the launch sequence:
Log messageWhat it means
Initializing SDL2 subsystemsLauncher startup — SDL2 is being set up
SDL2_mixer initializedSDL2 audio mixer opened successfully
Using game path from CLI: …Binary found via --game-path flag
Using game path from SM64COOPDX_PATH: …Binary found via environment variable
Using game path from profile override: …Binary found via active profile’s game_path
Using game path from launcher.toml: …Binary found via [game].path in launcher.toml
Using default game path: …Binary found by automatic directory search
ROM found in game directory: …ROM discovered next to the game binary
ROM found in launcher data dir: …ROM discovered in ~/.local/share/sm64coopdx/
ROM found via launcher.toml: …ROM found at [game].rom_path path
ROM already present and valid: …ROM copy skipped — destination already correct
ROM copied: … → …ROM was copied to the save directory
Spawning: … with N args, cwd=…The exact binary and argument list passed to Command::new()
Game process exited with status: …Game closed; exit code shown
Shutdown completeLauncher main loop exited cleanly
At warn level, messages like CLI --game-path points to non-existent file and launcher.toml [game].path points to non-existent file tell you which resolution tier was tried and fell through.
A warn about a path not found does not stop the launcher — it moves to the next tier. Only error messages indicate that the entire operation was aborted.

Checking the environment

The launcher calls Command::env_clear() before spawning the game, then selectively restores a known-safe whitelist of environment variables via build_game_env(). This prevents environment pollution from Flatpak/AppImage wrappers, LD_PRELOAD hooks, and stale PYTHONPATH entries, but it also means the game process only sees what the whitelist explicitly passes through.

Display server variables

If SDL2 cannot connect to a display server, the game will crash immediately with no window. Verify that the relevant variable is set in your current shell:
# X11
echo $DISPLAY
# Wayland
echo $WAYLAND_DISPLAY
A typical X11 session has DISPLAY=:0. If either variable is empty, SDL2 has no display to connect to. Full environment whitelist passed to the game process (from build_game_env() in game.rs):
VariablePurpose
DISPLAYX11 display server connection
WAYLAND_DISPLAYWayland compositor socket
XAUTHORITYX11 authentication cookie file
HOMEUser home directory
XDG_RUNTIME_DIRRuntime directory for sockets and pipes
XDG_DATA_HOMEXDG user data directory override
XDG_CONFIG_HOMEXDG user config directory override
XDG_CACHE_HOMEXDG user cache directory override
XDG_DATA_DIRSXDG system data directory search path
PULSE_SERVERPulseAudio server address
PULSE_COOKIEPulseAudio authentication cookie
ALSA_CARDALSA sound card override
DBUS_SESSION_BUS_ADDRESSD-Bus session bus address
LANGLocale language setting
LC_ALLFull locale override
LC_MESSAGESMessage locale setting
PATHExecutable search path
USERCurrent username
SHELLUser’s shell
TERMTerminal type
Any variable not on this list — including LD_LIBRARY_PATH, LD_PRELOAD, and PYTHONPATH — is stripped before the game starts.
If the game links against a library via RPATH=$ORIGIN (standard for self-contained release bundles), stripping LD_LIBRARY_PATH is safe. If your installation relies on LD_LIBRARY_PATH to find libdiscord_game_sdk.so or another bundled .so, the game may fail to load it. In that case, confirm the .so lives in the same directory as the binary so the runtime linker finds it via $ORIGIN.

Diagnosing a “no display” crash

If the game exits immediately with a non-zero status and game_stderr.log contains an SDL2 display error, run the launcher with RUST_LOG=debug and check which DISPLAY / WAYLAND_DISPLAY value was picked up:
RUST_LOG=debug ./sm64coopdx-launcher 2>&1 | grep -E "DISPLAY|Spawning"
The Spawning: … line shows the exact binary and argument list. Cross-reference the log table above to confirm the display variable was present when the launcher started.

Build docs developers (and LLMs) love