Skip to content

ADR-0029 + consume upstream CUE4Parse from nuget.org - #314

Merged
ChrisonSimtian merged 3 commits into
mainfrom
docs/adr-0029-standalone-game-libraries
Aug 9, 2026
Merged

ADR-0029 + consume upstream CUE4Parse from nuget.org#314
ChrisonSimtian merged 3 commits into
mainfrom
docs/adr-0029-standalone-game-libraries

Conversation

@ChrisonSimtian

@ChrisonSimtian ChrisonSimtian commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Two commits: the ADR establishing the per-game library pattern, and the CUE4Parse migration it made possible.

Closes #310.


1. ADR-0029 — per-game libraries as standalone packages

Each game gets a standalone repo in the org, publishing NuGet packages that ERP simply consumes — no submodules, no ProjectReference into vendored source.

The two dependencies looked like the same problem and turned out to be opposites:

Divergence from upstream Upstream health Conclusion
SatisfactorySaveNet 21 ahead, 0 behind last substantive commit 2025-12-18, 18 ⭐ We are the maintained line — take ownership
CUE4Parse 0 ahead, 0 behind actively developed, 601 ⭐ Not a fork at all — we just needed a fresher build

Decisions recorded: erp-for-factory-games/<Game> repos publishing ErpForFactoryGames.<Game>.<Concern> under one reservable nuget.org prefix; Satisfactory rebranded as a hard-fork successor per the NUKE → Fallout playbook in ADR-0021, continuing the 4.x line.

Resolves the permanent-fork question ADR-0014 left open (upstream PR #33 closed unmerged, 4-week cutoff long passed) and completes the GITHUB_TOKEN retirement ADR-0021 anticipated.

2. CUE4Parse — consume upstream, delete the submodule

The ADR originally proposed mirroring CUE4Parse into the org and republishing our own rebuild. That was wrong, and checking nuget.org showed why: upstream now publishes dated rolling builds of master (1.2.2.202607, 1.2.2.202608) — newer than the commit our submodule pinned (2026-05-13). The published package is the master build we were hand-rolling.

So: no fork, no mirror, no republishing pipeline. Just a PackageReference. We fork if and when we need to.

  • PackageReference on CUE4Parse 1.2.2.202608
  • TFM net8.0net10.0 — the pin existed only to match the vendored project's TFM; rolling builds target net10.0
  • vendor/CUE4Parse submodule + .gitmodules entry removed
  • README rewritten; stale ADR-0026 paths (src/Satisfactory/Save/…) corrected and every relative link verified to resolve

Verified against a real install, not just compiled

Satisfactory build 444486. The extractor mounts FactoryGame-Windows.utoc — the exact container header plain 1.2.2 choked on with ParserException: Invalid bool value — and regenerates known-resource-nodes.json byte-identical to the committed dataset: 647 nodes (472 / 34 / 18 / 123 by class), plus the 2,662 intentionally-dropped deposits. Matches the README coverage table exactly.

Incidental finding: the extractor did not build at all on a normal checkout before this, because the submodule is update = none and never populated. This PR fixes that as a side effect.

ADR amended, not superseded

ADR-0029 was still unmerged, so §3/§4 were corrected in place rather than leaving an accepted-then-immediately-wrong decision on record. Net effect: one feed, not twonuget.config reduces to a single nuget.org source once the Satisfactory library is published, so ADR-0021's GITHUB_TOKEN retirement completes in full rather than partially.

Backlog

🤖 Generated with Claude Code

@ChrisonSimtian ChrisonSimtian changed the title docs(adr): ADR-0029 per-game libraries as standalone NuGet packages ADR-0029 + consume upstream CUE4Parse from nuget.org Aug 9, 2026
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

Test results

228 tests   223 ✅  2m 1s ⏱️
 12 suites    5 💤
 12 files      0 ❌

Results for commit e06ed3a.

♻️ This comment has been updated with latest results.

ChrisonSimtian and others added 3 commits August 9, 2026 21:34
Each game's parsing/extraction code becomes a standalone repo in the
erp-for-factory-games org, publishing ErpForFactoryGames.* packages to
nuget.org. ERP consumes released packages only -- no submodules, no
ProjectReference into vendored source.

Resolves the "permanent fork" question ADR-0014 left open: the
SatisfactorySaveNet fork is 21 commits ahead / 0 behind an upstream whose
last substantive commit was 2025-12-18, so we are the maintained line, not
a fork of a maintained project.

Treats CUE4Parse differently on the evidence: our mirror is 0 ahead /
0 behind upstream, so it is not a fork in any meaningful sense. We publish
unmodified rebuilds of pinned upstream commits to the org GitHub Packages
feed and drop the vendor/CUE4Parse submodule.

Completes the GITHUB_TOKEN retirement ADR-0021 anticipated: tools/ sits
outside the solution, so the main build restores tokenless once the
Satisfactory packages reach nuget.org.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…module

Upstream now publishes dated rolling builds of master (1.2.2.202607,
1.2.2.202608) -- newer than the commit vendor/CUE4Parse pinned (2026-05-13).
The published package now IS the master build the submodule was hand-rolling,
so the reason for vendoring is gone.

- SatisfactoryPakExtractor takes a PackageReference on CUE4Parse 1.2.2.202608
- TFM moves net8.0 -> net10.0; the pin existed only to match the vendored
  project's TFM, and the rolling builds target net10.0 anyway
- vendor/CUE4Parse submodule and its .gitmodules entry removed
- README rewritten; stale ADR-0026 paths (src/Satisfactory/Save/...) corrected
  to src/Infrastructure/Satisfactory.Infrastructure/, all links verified

Verified end to end against Satisfactory build 444486: the extractor mounts
FactoryGame-Windows.utoc cleanly and regenerates known-resource-nodes.json
byte-identical to the committed dataset (647 nodes, 472/34/18/123 by class).
Note the extractor did not build at all before this change on a normal
checkout, since the submodule is update=none and never populated.

ADR-0029 amended: no fork, no mirror, one feed. We fork only when we need to.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ADR-0029 said each game gets a repo; it did not say what goes inside one. The
first attempt moved Captain of Industry out as a console app with its logic in
Program.cs -- which put every piece of game-specific knowledge inside a binary
the planner cannot consume, and left the "package or dotnet tool?" question
unanswerable because the thing was both and neither.

Each game repo is now onion-layered exactly as ADR-0004 describes for this
repo, holds every game-specific concern for that game (catalogue, saves, and
whatever comes next), and ships its CLIs as presentation-layer .NET global
tools alongside the libraries.

The layering is load-bearing rather than decorative: reading a CoI catalogue
means executing the game's own registration code, and reading an Outworld
Station save means parsing a UE 5.4 binary format. Each is one adapter, and
everything around it -- model, use case, persisted output -- has no such
requirement, so both use cases are unit-tested with no game installed.

Also records the decisions that were implicit in the implementations: a package
per layer rather than per repo, game-prefixed domain types because the planner
consumes several game packages at once, serialisation contracts kept in
infrastructure DTOs, and publishing on a version tag via trusted publishing
rather than on every merge.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ChrisonSimtian
ChrisonSimtian force-pushed the docs/adr-0029-standalone-game-libraries branch from e06ed3a to d4af55a Compare August 9, 2026 09:34
@ChrisonSimtian
ChrisonSimtian merged commit 30646a2 into main Aug 9, 2026
9 checks passed
@ChrisonSimtian
ChrisonSimtian deleted the docs/adr-0029-standalone-game-libraries branch August 9, 2026 09:34
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.

Consume upstream CUE4Parse from nuget.org and drop the vendor submodule

1 participant