Skip to content

feat(filesystem): Implement complete mod loading through -mod - #3091

Open
Jaredl-Dev wants to merge 5 commits into
TheSuperHackers:mainfrom
Jaredl-Dev:feat/complete-mod-loading
Open

feat(filesystem): Implement complete mod loading through -mod#3091
Jaredl-Dev wants to merge 5 commits into
TheSuperHackers:mainfrom
Jaredl-Dev:feat/complete-mod-loading

Conversation

@Jaredl-Dev

@Jaredl-Dev Jaredl-Dev commented Aug 10, 2026

Copy link
Copy Markdown

Implements complete native mod loading for Zero Hour through ordered, repeated -mod arguments. Each operand accepts a BIG archive or a directory. Directory layers expose loose files and recursively load *.big archives.

Precedence is deterministic:

  • Later -mod operands override earlier operands.
  • Loose files override BIG archives within the same directory layer.
  • Explicit mod layers override physical game-directory files and normal game archives.

The command line captures operands during startup. The file system validates and mounts the complete stack after the low-level file systems initialize and before GlobalData, GameData, and compatibility CRC inputs load. Missing or invalid operands produce a visible startup error without partially replacing the active stack.

Native-path consumers resolve winning loose mod files for Bink movies and animated Windows cursors without falling through to shadowed base assets. The FFmpeg backend reads winning movie resources through the file system, including BIG-backed resources.

Scope

This PR implements Zero Hour first. The corresponding Generals implementation is intentionally deferred until the Zero Hour code review is complete. The Generals target requires that replica before it builds with this series.

Known limitations

  • Mod-provided splash screens are not loaded by this implementation. Splash screens from mod layers require separate startup work that is better handled in a separate PR.

  • Mod archives whose resolved paths reach the legacy Windows 260-character limit may fail to open because the engine uses narrow-character CRT file APIs. A separate filesystem change to support Unicode extended-length paths would be required to resolve this issue.

Validation

  • Build Zero Hour with modern MSVC
  • Build Zero Hour Release with Visual C++ 6
  • Launch Contra 10.0.2 Beta 2 Patch 1
  • Launch C&C Shockwave 1.201 with the HD cursor add-on
  • Run git diff --check

TODO

  • Replicate to Generals

Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
@Jaredl-Dev
Jaredl-Dev force-pushed the feat/complete-mod-loading branch from deae37a to 024b98c Compare August 10, 2026 06:22
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
@Jaredl-Dev
Jaredl-Dev force-pushed the feat/complete-mod-loading branch from 024b98c to a3b6a31 Compare August 10, 2026 18:08
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
@Jaredl-Dev
Jaredl-Dev force-pushed the feat/complete-mod-loading branch from a3b6a31 to 6705fd2 Compare August 10, 2026 18:32
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 10, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GenLauncher_GO that referenced this pull request Aug 10, 2026
TheSuperHackers/GeneralsGameCode#3091 gives the Zero Hour client an ordered
mod overlay file system, so the launcher no longer has to make mods visible
by mutating the user's game folder.

Launch is now: verify integrity, resolve and validate mod layers, append one
quoted -mod operand per selected mod, patch, and add-on in selection order,
then start the process. Nothing is written to the game directory, so there is
nothing to journal, back up, clean up, or recover.

Removed:
- The deployment subsystem: FileSystemDeploymentService, DeploymentStateStore,
  DeploymentLaunchPreparationService, the file planner, path resolver, result
  types, and the hard-link creator, plus their ~1,500 lines of tests.
- The .gib storage rename. Installed archives keep the .big extension the
  client globs for; BigFileVariantPath and its call sites are gone.
- Base-game script hiding. Mod layers now override game-directory files, which
  is what that hack existed to work around.
- Startup deployment recovery, shutdown cleanup, game-switch cleanup/recovery,
  and the same-drive recommendation, which only mattered for hard links.
- The administrator requirement. Game-folder writes were its only driver, and
  an elevated launcher handed its integrity level to every game it started.

Added:
- IModLayerResolutionService and its FileSystem implementation, which validate
  each layer against the constraints the client enforces: the directory exists,
  every *.big below it really starts with BIGF, the path is representable in
  the active ANSI code page, no file exceeds MAX_PATH, and the path carries no
  double quote. A bad operand otherwise ends in a modal error and _exit(1).
- BigArchiveFile, which classifies archives by header the way the client does.
  Manual import now renames BIGF files to .big and quarantines files named as
  archives that the client cannot open.
- A CLAUDE.md that imports AGENTS.md and points at the per-project ones, so
  Claude Code loads the same rules every other agent already reads.

Symbolic-link rejection coverage is unchanged: it guards launcher-owned
storage, not the deleted hard-link path, and matters more now that the client
reads that storage in place. Only the two hard-link-specific tests were
dropped, and the new mod layer resolver gained the same linked-root test its
sibling services already have.

Accepted regressions, since the PR is Zero Hour only: Generals keeps the legacy
single-operand -mod, GeneralsOnline still launches without arguments, and World
Builder starts without mod content and warns before doing so.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 11, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 11, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 11, 2026
@Jaredl-Dev
Jaredl-Dev force-pushed the feat/complete-mod-loading branch from 6705fd2 to e01726f Compare August 11, 2026 00:16
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 13, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 13, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 13, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 13, 2026
Jaredl-Dev added a commit to Jaredl-Dev/GeneralsGameCode that referenced this pull request Aug 13, 2026
@Jaredl-Dev
Jaredl-Dev force-pushed the feat/complete-mod-loading branch from c98a5d1 to cd6d9ac Compare August 13, 2026 20:07
@Jaredl-Dev
Jaredl-Dev force-pushed the feat/complete-mod-loading branch from cd6557a to 78a5f58 Compare August 13, 2026 22:03
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.

Implement complete mod loading through -mod

1 participant