ADR-0029 + consume upstream CUE4Parse from nuget.org - #314
Merged
Conversation
Test results228 tests 223 ✅ 2m 1s ⏱️ Results for commit e06ed3a. ♻️ This comment has been updated with latest results. |
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
force-pushed
the
docs/adr-0029-standalone-game-libraries
branch
from
August 9, 2026 09:34
e06ed3a to
d4af55a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
ProjectReferenceinto vendored source.The two dependencies looked like the same problem and turned out to be opposites:
SatisfactorySaveNetCUE4ParseDecisions recorded:
erp-for-factory-games/<Game>repos publishingErpForFactoryGames.<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_TOKENretirement 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.PackageReferenceonCUE4Parse 1.2.2.202608net8.0→net10.0— the pin existed only to match the vendored project's TFM; rolling builds target net10.0vendor/CUE4Parsesubmodule +.gitmodulesentry removedsrc/Satisfactory/Save/…) corrected and every relative link verified to resolveVerified against a real install, not just compiled
Satisfactory build 444486. The extractor mounts
FactoryGame-Windows.utoc— the exact container header plain1.2.2choked on withParserException: Invalid bool value— and regeneratesknown-resource-nodes.jsonbyte-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 = noneand 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 two —
nuget.configreduces to a single nuget.org source once the Satisfactory library is published, so ADR-0021'sGITHUB_TOKENretirement completes in full rather than partially.Backlog
Microsoft.Bcl.Memoryadvisory the now-working build revealed🤖 Generated with Claude Code