The coopdx-rs launcher splits its data-layer concerns into five focused manager modules that live underDocumentation 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.
src/managers/. Each module owns one domain — mod scanning, DynOS packs, player profiles, network settings, and the online download database — and exposes a clean set of public functions that the main event loop calls. All config writes use an atomic write-then-rename pattern (*.tmp → final) so that a crash or power loss never leaves a half-written file on disk.
Mod Manager
Source files:src/managers/mod_manager.rs, src/managers/mod.rs
The mod manager discovers Lua mods on disk and serialises the enabled set into sm64config.txt. It is the only module authorised to write enable-mod: lines.
Scanning
mods_dir and returns one UiItem per discovered mod, sorted alphabetically by name. Two shapes are recognised:
- Single-file mods — any
.luafile becomes a mod whosenameis the file stem (e.g.star_road.lua→name = "star_road",rel_path = "star_road.lua"). - Folder mods — any subdirectory that contains a
main.luafile (e.g.super_mod/main.lua→name = "super_mod",rel_path = "super_mod").
main.lua) is silently skipped. If mods_dir does not yet exist it is created and an empty list is returned.
Reading and writing the enabled set
sm64config.txt and returns the set of names that appear on enable-mod: lines. Returns an empty set if the file does not exist. Both enable-mod: name (with space) and legacy enable-mod:name (without space) are accepted. Empty values are ignored.
enable-mod: section atomically. All non-enable-mod: lines (network settings, DynOS packs, etc.) are preserved in their original order. The new enable-mod: lines are appended after the preserved block.
The write is atomic: the function writes to a sibling
.tmp file and then calls fs::rename to swap it into place. On POSIX systems this is a single atomic syscall, so the config is never partially written.Helper: applying the enabled set to a scanned item list
Vec<UiItem> and sets each item’s enabled flag based on whether item.name or item.rel_path appears in enabled. Call this immediately after scan_mods + parse_enabled_mods to get a fully-populated item list for the UI.
DynOS Manager
Source file:src/managers/dynos_manager.rs
DynOS packs are character and texture replacement packs loaded by the game’s DynOS system. The DynOS manager mirrors the mod manager’s API but targets dynos-pack: config lines and treats every directory inside dynos/packs/ as a valid pack (no main.lua requirement).
Scanning
packs_dir and returns one UiItem per immediate subdirectory, sorted alphabetically. Plain files in the directory are ignored. Missing directories are created on first call.
Reading and writing the enabled set
dynos-pack: lines from sm64config.txt. Semantics are identical to parse_enabled_mods: missing files return an empty set, and both dynos-pack: name and dynos-pack:name are accepted.
dynos-pack: lines atomically, preserving all other config content exactly as with write_enabled_mods.
Profile Manager
Source file:src/managers/profile_manager.rs
Profiles let players keep separate configurations (player name, window mode, Discord settings) for different play styles. Each profile is a subdirectory of ~/.local/share/sm64coopdx/profiles/ that contains a profile.json, an sm64config.txt, and a saves/ subdirectory.
ProfileConfig struct
false via #[serde(default)] so that older profile.json files without those keys deserialise correctly.
Initialisation and scanning
Default profile directory (including saves/) and writes the initial profile.json if neither exists. Also creates active.txt pointing to Default if that file is absent. Safe to call on every launch.
UiItem per profile directory, alphabetically sorted with Default always first. The enabled field is set to true for the active profile. A synthetic "+ New Profile" item (with rel_path = "__new__", item_type = ItemType::Action) is appended as the final entry.
Active profile tracking
active.txt. Returns None if the file is missing or empty.
active.txt (via .active.tmp → rename).
Profile CRUD
.{name}.tmp, then renames). Copies the caller-supplied parent_cfg (sm64config.txt) if it exists and is non-empty. Rejects empty names, unsafe filesystem characters, and case-insensitive duplicates.
active.txt if the renamed profile was active.
Err if name is "Default" (the default profile is undeleteable) or if name is the currently active profile (switch to another profile first).
ProfileConfig. save_profile_config writes atomically via .tmp → rename.
Building UI items and CLI args
ProfileConfig into a CLI argument slice ready to be passed to the game binary. Always emits --savepath <data_dir>. Emits --configfile <profile_dir>/sm64config.txt only when that file is non-empty — an empty config file would override the game’s own settings and break ROM path resolution.
Updating the player name
playername to new_name, saves it atomically, and returns the updated ProfileConfig. Called by the event loop when the virtual keyboard confirms a player-name edit in the Profile Detail sub-screen.
Network Manager
Source file:src/managers/network_manager.rs
The network manager handles reading and writing the network-related keys in sm64config.txt and provides the NetworkMode enum that drives the network form UI.
NetworkMode enum
Local → Client → Server → CoopNet → Local. Navigation methods:
| Method | Description |
|---|---|
next(self) -> NetworkMode | Advance to next mode |
prev(self) -> NetworkMode | Go to previous mode |
label(self) -> &'static str | Human-readable label ("Local", "Client", etc.) |
to_i32(self) -> i32 | Serialises to coop_network_system value |
from_i32(v: i32) -> NetworkMode | Deserialises from config file value |
NetworkConfig struct
mode = Local, join_port = 7777, host_port = 7777, max_players = 16.
Reading and writing
coop_player_name, coop_join_ip, coop_join_port, coop_host_port, amount_of_players, coop_network_system, coopnet_password) from sm64config.txt. Returns Ok(NetworkConfig::default()) if the file is missing.
Download Manager
Source file:src/managers/download_manager.rs
The download manager provides the mod database data model, the search index, and the actual HTTP download and ZIP extraction pipeline used by the Download Mods sub-screen.
DbMod and DbFile structs
#[serde(default)] so that mods with partial data deserialise without errors.
DbMod methods
true if any URL in download_urls contains gamebanana.com (case-insensitive). The search index builder calls this to exclude such entries before indexing.
DownloadProgress struct
Arc<Mutex<DownloadProgress>>. The worker thread updates bytes every ~128 KB to reduce mutex contention. pct() -> u8 returns 0–100 for progress bar rendering.
Download and extraction
.{filename}.part temporary file and atomically renames it on completion. Sets a 30-second connect timeout with no total timeout (large mods can take a while). Checks the cancel flag between each 64 KB chunk and deletes the .part file if cancelled.
dest_root (the mods folder). The algorithm:
- Scan all ZIP entries for files named
main.lua. Eachmain.lua’s parent directory is a mod root. - Extract all entries under each mod root into
dest_root/{mod_root_name}/. - If no
main.luais found, fall back to extracting the ZIP flat intodest_root/. - Any entry whose resolved path escapes
dest_root(zip-slip attack) is silently skipped.
Installed mod tracking
InstalledMap is a persistent JSON dictionary (launcher_downloads.json) mapping installed folder names to their database mod_id. load_installed_map returns an empty map if the file is missing or corrupt. save_installed_map writes atomically via .tmp → rename.
Search utilities
s and strips all non-alphanumeric characters. Used for fuzzy matching between installed folder names and database mod IDs/titles. Never use the output for display — it is for comparison only.