Skip to content

feat(profiles): detect an alternate mod manager mod and hand it to Relay at launch - #231

Merged
ModifAmorphic merged 8 commits into
release/1.1.0from
feature/228-alt-mod-manager
Aug 20, 2026
Merged

feat(profiles): detect an alternate mod manager mod and hand it to Relay at launch#231
ModifAmorphic merged 8 commits into
release/1.1.0from
feature/228-alt-mod-manager

Conversation

@ModifAmorphic

@ModifAmorphic ModifAmorphic commented Aug 20, 2026

Copy link
Copy Markdown
Owner

Resolves #228.

What changed

Relay v1.1.0 can replace its built-in mod manager via --mod-manager <file>. Curator now supports that end to end:

  • Generic detection (IProfileService.GetActiveModManager): an enabled profile mod whose resolved staging target is a base folder containing mod_manager.lua is the active alternate mod manager (the Darktide Mod Loader family convention; e.g. AML, Nexus mod 246). Detection is content-based, manager-agnostic, and shares the staging resolver, so the answer always matches what PrepareModRoot stages. At most one manager per profile (the existing base-name collision block). Yields null when the manager file is missing from the resolved target: Relay hard-refuses a configured-but-missing file, so Curator never hands it one.
  • Staging and mods.lst are unchanged: the manager mod stages and lists like any ordinary mod. AML installs as base/ with mod_manager.lua + an empty base.mod; the empty descriptor passes the existing import validation (a Vortex install marker), and AML-shaped archives import with base name base.
  • Launch flag: when a manager is active, --mod-manager <path> is emitted immediately after the --mod-path pair (verbatim on Windows, Z:\-translated on Linux). The value is projected onto the same effective mod root --mod-path was formulated from: the game dir under default hosting, the staged root under the external-hosting preference. RELAY_MOD_MANAGER is now a reserved profile env-var name so a profile cannot point Relay at a different manager than the staged one.
  • Mods-page banner: a full-width, non-dismissible caution banner between the import card and the row list is shown exactly while the active profile has an enabled manager, reading "{name} is managing ordering of mods. Changes to mod order in Curator will not be reflected in game." Reorder and lock controls stay fully functional (Curator keeps writing mods.lst as the working fallback the moment the manager is disabled). Banner state is re-derived on every Reload and on the enable-toggle path, from the same derivation the launch path consumes.
  • Docs: AGENTS.md, architecture doc, reference docs (profiles, relay-client, ui), and the README cover the detection rule, the flag projection, and the banner.

Tests

New coverage across Profiles (detection matrix: untracked/Nexus/linked, disabled, unresolvable, missing file, capitalized Base, unknown profile, ordinary staging), Mods (AML archive shape validates + imports), RelayClient (flag presence/position/value on both platforms, projection in both hosting modes, Z:\ translation, no-flag cases), and UI (banner on/off/name formatting, toggle-driven refresh in both directions).

…lay at launch

Relay v1.1.0 added a --mod-manager slot that replaces its built-in mod
manager. Curator derives the manager generically from profile state: the
enabled mod (first in order) whose resolved staging target is a base folder
containing mod_manager.lua, via one focused IProfileService read
(GetActiveModManager) that shares the staging resolver so the answer matches
what PrepareModRoot stages. The derivation nulls when the manager file is
missing from the resolved target, because the launcher hard-refuses (exit 2)
a configured-but-missing manager; a stale flag would be a launch failure.

The launch path emits --mod-manager <absolute staged path> immediately after
the --mod-path pair, in both hosting modes (the staged tree is authoritative
and the game-dir link resolves to the same file), verbatim on Windows and
Z:\-translated on Linux. RELAY_MOD_MANAGER joins the reserved profile env
names so a profile value cannot point Relay at a different manager than the
staged one. Staging and mods.lst are unchanged: the manager mod stages and
lists like any ordinary mod, and import keeps requiring base/base.mod (the
existing generic mod-shape rule; an empty descriptor passes, so AML's real
artifact imports under the base name).
…ls ordering

While the active profile has an enabled manager mod, the manager (not
Curator's order) drives in-game load order. The Mods page shows a
full-width, non-dismissible caution banner between the import card and the
row list, carrying the manager mod's display name. The banner state reads
the same GetActiveModManager result at every Reload that the launch path
consumes, so the banner and the --mod-manager flag can never disagree, and
it gates nothing: reorder and lock controls stay fully functional. The name
resolves through the loaded row, then the repository container, then the
literal base as a defense.
Update the architecture, reference, and orientation docs for the manager
slot: the Relay contract flag, the Profiles derivation and its single-read
guarantee, the relay-client emission rules (absolute staged path in both
hosting modes, verbatim vs Z:\ per platform, no version preflight), the
mod-list banner, the reserved RELAY_MOD_MANAGER env name, and the new test
coverage. The README gains a short user-facing note.
…d root

The staged manager path was handed to the launcher verbatim in both hosting modes. Under default game-dir hosting --mod-path is the game dir, so Relay received a profile-tree path for a file it is told to find under the game dir's mods link. Compose the flag value from the same effective mod root --mod-path was formulated from (modPath plus the in-tree relative portion of the staged manager path), right after the hosting block finalizes modPath. The derivation still locates + verifies the manager in the staged tree; ActiveModManager.ManagerPath stays the staged path.
@ModifAmorphic
ModifAmorphic merged commit cb2fb9b into release/1.1.0 Aug 20, 2026
4 checks passed
@ModifAmorphic
ModifAmorphic deleted the feature/228-alt-mod-manager branch August 20, 2026 00:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AML support: profile mod + conditional --mod-manager launch flag

1 participant