Skip to content

Milestones

List view

  • Replace the v1 zip/tarball distribution with native installers on each OS so a fresh user goes from "click download" → "agent is running" without ever editing a JSON file or clicking through a SmartScreen / Gatekeeper warning manually. The v1 PoC ([ADR-0024 §7](../blob/main/docs/adr/0024-agent-v1-shape.md)) deliberately shipped self-contained zips because that was the smallest thing that closed the save-upload loop. It works but the onboarding is jagged: download → unzip → find the right path → edit `agent.json` → run `--install` from elevated terminal. Real users won't do that. This milestone polishes the install experience so it's a pleasant first-run, per platform: - **Windows**: double-click an `.msi`, click Next a few times, done. Service auto-starts. - **Linux**: `apt install` / `rpm install` a package, post-install hook registers + starts the systemd unit. - **macOS**: double-click a `.pkg`, drag the agent app into place, launchd auto-loads. **Un-defers** the macOS support that ADR-0024 §7 punted. - **All platforms**: a first-run wizard prompts for API URL + token, validates the server is reachable, writes `agent.json` — instead of the user editing JSON by hand. ## Out of scope (separate follow-up under the same milestone) - **Code signing** (Authenticode on Windows, Apple Developer notarization on macOS). Requires paid certs (~$300/yr combined) — file as a deferred issue so we track it without gating the milestone. v2 still ships unsigned; users see a one-time scary dialog. - **Auto-update.** Important once there are real users, but a separate concern from the install flow. - **Distribution via package managers** (winget, Homebrew Cask, apt repo, AUR). The installers themselves are the prerequisite; distribution can layer on later. ## Backwards compatibility The v1 zip flow keeps working through this milestone — installers are an additive change. Users on zips get migrated when they next download. No forced cutover.

    No due date
    0/12 issues closed
  • **v1 PoC scope** (deliberately small — required for first stable release [#154](https://github.com/ChrisonSimtian/ErpForFactoryGames/pull/154)): A headless background agent for **Satisfactory only**. Watches the user's save folder; when a `.sav` is created or updated, parses + uploads it to the hosted API. No auth (planned ahead, not implemented). Minimal localhost UI to show what the agent sees and the last upload status. Future iterations expand to CoI, catalogue uploads, auth, multi-machine setups — but they don't gate 1.0. ## In scope (v1 PoC) - **Headless agent** — `Microsoft.Extensions.Hosting` generic host + `BackgroundService`. On Windows runs as a Windows service (via `Microsoft.Extensions.Hosting.WindowsServices`); on Linux as a systemd unit (via `Microsoft.Extensions.Hosting.Systemd`). macOS deferred — figure it out when it matters. - **Logging via ILogger** — built-in console + simple file sink. No opinionated framework (Serilog/NLog) until there's a reason. Logs land in a well-known per-user folder. - **Save-folder watching** — `FileSystemWatcher` over `%LocalAppData%/FactoryGame/Saved/SaveGames/` (auto-detect with config override). On create / change, debounce briefly, then upload. - **Satisfactory save upload** — POSTs the raw `.sav` to a new ApiService endpoint. Parse-side (`SatisfactorySaveNet`) stays server-side; agent just shuttles the bytes. - **Localhost status UI** — agent self-hosts a tiny Kestrel endpoint at e.g. `http://localhost:52525/`. Shows: game-data folder, save folder, detected game version, last upload (file + timestamp + result). Read-only; cross-platform; no system-tray app needed. - **Auth seam, planned but not implemented** — config carries a placeholder `AgentToken`, API endpoint accepts it without validating. Documented as a seam so the auth ADR can drop in without restructure. - **Distribution** — `dotnet publish` self-contained per RID (`win-x64`, `linux-x64`). GitHub Release with a zip per platform + a one-page install README. ## Out of scope (separate milestones later) - CoI catalogue uploads, CoI saves, anything CoI-specific. Satisfactory only for v1. - Real auth (OAuth, magic-link, per-install tokens). Just the seam. - macOS support. - Two-way sync (planner edits → save edits). - In-game overlay / mod hooks. - Anything beyond a single watched save folder. - Auto-update of the agent itself. ## Open questions (settle via [ADR-0024](https://github.com/ChrisonSimtian/ErpForFactoryGames/issues/197)) - Exact wire shape of the upload endpoint — multipart vs. raw body? Server-detected version vs. agent-provided? - Localhost UI tech — a single Razor page hosted in the same agent process is the obvious pick; confirm vs. plain static HTML. - Where do logs land per-OS? (Windows: probably `%LocalAppData%/ErpForFactoryGames/agent-logs/`; Linux: systemd journal + a file under `~/.local/share/...`.) - Service-install UX — `--install` / `--uninstall` flags handled by the agent itself, or a separate installer script? ## Forward fit (not v1 work, captured for context) - Add catalogue upload alongside save upload — same pattern, different endpoint. - Add CoI savegame parsing once R&D answers the format. - Drop in real auth. - macOS support. - Move the localhost UI to a fuller settings page once there are settings worth managing.

    No due date
    13/18 issues closed
  • Add Captain of Industry as the second supported factory game, exercising the multi-game seams introduced by the rebrand ([ADR-0020](../blob/main/docs/adr/0020-rebrand-to-erp-for-factory-games.md)). Satisfactory remains the reference module; this milestone is about proving that a second game slots in cleanly as a sibling under `src/`. Captain of Industry is a good second pick because the core loop is recognisably the same — recipes, buildings, throughputs — so it stresses the game-agnostic planner without dragging in radically new domain concepts. ## In scope - New `src/CaptainOfIndustry/` module alongside `src/Satisfactory/`, following the same Onion + CQRS layout (see [repo layout](../blob/main/.claude/README.md)). - Catalogue: products (solid + liquid + gas), buildings, recipes (including alternates / unlocks). Mirrors the Satisfactory catalogue ingestion pattern but reads CoIs data format. Source TBD — community wikis, exported game data, or a hand-curated seed for v1. - Planner integration: CoI recipes flow through the same planning core (and LP solver once milestone #6 lands). Validate the `IRecipeCatalog`-style contract is genuinely game-agnostic — widen or split it if it isnt. - Subdomain wiring: `captain-of-industry.erp-for-factory.games` per the rebrand convention. - ADR documenting the CoI data source + any contract changes forced by a second game. ## Out of scope (separate milestones if/when needed) - **Save-file ingestion** for CoI (Satisfactory equivalent is milestone #12 — large effort, defer until basic planning works). - **Map / world visualisation** for CoI. - **CoI-specific mechanics** that dont map onto recipes-and-buildings: pollution, worker population, vehicle logistics, terrain/mining depth. These are interesting but out of the planners critical path; capture as follow-ups once the core is proven. - **Namespace refactor** to `ERP.Core` + `ERP.Games.*` (already deferred in [roadmap](../blob/main/docs/roadmap.md)). - **UI rebrand** — Blazor UI still skews Satisfactory-themed; a game switcher / per-game theming is a later concern. ## Open questions (resolve via ADR before code) - Where does CoI catalogue data come from? Game files, community export, or hand-curated JSON committed to the repo? Each has IP / freshness / maintenance trade-offs. - How does the user select which game theyre planning for — config, subdomain routing, or in-app switcher? - Does the current `IRecipeCatalog` need widening (e.g. multiple outputs per recipe, unlock prerequisites) or is it already sufficient?

    No due date
    14/17 issues closed
  • Rename the project from "ERP.Satisfactory" to "ERP for Factory Games" to reflect that we plan to support multiple factory games (Satisfactory first, then others). Domain `erp-for-factory.games` registered via Cloudflare; subdomain convention `<game>.erp-for-factory.games`. **In scope:** repo rename, solution/workspace rename, CI + build pipeline updates, README/CLAUDE.md/ADR refresh, new ADR documenting the rebrand, domain wiring, auto-memory updates. **Out of scope (deferred to future milestones):** - UI/branding inside the Blazor app — stays Satisfactory-themed for now. - Namespace refactor to `ERP.Core` + `ERP.Games.*` (already noted in `docs/roadmap.md:152`). - Multi-game catalogue work (tracked under ADR-0010). - The `Satisfactory.*` project tree and `tools/SatisfactoryPakExtractor` — these are the Satisfactory game module and stay named as-is.

    No due date
    9/11 issues closed
  • v2 of the factory map (ADR-0013): place modules, simulate belts, drag-to-plan. Editing capabilities layered on top of the read-only map shipped in milestone #12.

    No due date
    0/1 issues closed
  • Replace the hand-curated `.satisfactory/stocktake.md` with live factory state parsed directly from the user's Satisfactory `.sav` file. Add a map view that shows what the parser found. ## Decisions made - **Parser:** Node sidecar wrapping `@etothepii/satisfactory-file-parser` (TypeScript). PoC confirmed it handles current v1.2 saves (SaveVersion 60, BuildVersion 489969); the C# alternative `SatisfactorySaveNet` 3.2.3 fails on those. See [ADR 0012](../blob/main/docs/adr/0012-live-factory-state-via-node-sidecar.md). - **Orchestration:** Aspire `NodeApp` resource. Production runs containerized; dev runs `pnpm`. - **Application port:** new `IFactoryStateProvider` returning domain entities (`Miner`, `Smelter`, `ConveyorBelt`, `ResourceNode`, `NodePurity`). Adapter pattern keeps a future pure-C# implementation possible if `SatisfactorySaveNet` catches up. - **Save path config:** mirrors [ADR 0011](../blob/main/docs/adr/0011-catalogue-source-path-configuration.md) — env var, then config, then auto-detect under `%LocalAppData%\FactoryGame\Saved\SaveGames\`. - **Ingestion is user-triggered**, not on startup. Large saves (50–200 MB) parse in a few seconds. - **Map visualiser:** Leaflet via Blazor JSInterop, fed by server-rendered GeoJSON. Procedural tile layer (Coffee Stain map art is IP). See [ADR 0013](../blob/main/docs/adr/0013-map-visualiser-approach.md). - **Drift detection:** Blazor page that diffs `.satisfactory/stocktake.md` against the parsed save. The save is the source of truth; the stocktake becomes optional human-curated context. ## Out of scope - Editing the factory from the map (placing new buildings, simulating reroutes). Read-only at v1. - Hot-reload / file-watch on the `.sav`. Manual re-ingest only. - Mod-added actors. Surfaced as warnings, not domain entities. - A C# replacement for the sidecar. Tracked separately as a future option if upstream `SatisfactorySaveNet` catches up. - Tile generator quality. Procedural / abstract is fine at v1 — geographic accuracy lands later.

    No due date
    21/21 issues closed
  • Model raw extraction: miners (Mk.1/2/3), oil extractors, water extractors, resource wells, geothermal generators. Node purity (impure / normal / pure) drives extraction rate. Per-node-type max counts let plans cap raws to what a real save actually has. Brings in: - Resource node types per resource (iron / copper / coal / caterium / quartz / sulfur / bauxite / uranium / SAM / oil / nitrogen). - Extractor + node combinations (e.g. Miner Mk.2 on a Pure node = 240/min iron ore). - Power cost per extractor (feeds the LP solver's power output). Depends on the catalogue ingestion epic for extractor + node data, and on the Fluids epic for oil/water/nitrogen extraction. ## Out of scope - World-map visualization of node locations (separate epic if ever). - Train/conveyor logistics.

    No due date
    1/1 issues closed
  • Model fluids as first-class in the planner: water, crude oil, heavy oil residue, fuel, turbofuel, sulfuric acid, nitrogen, etc. Pipe throughput, junction balancing, head-lift, valve/pump behavior. Recipes that mix solid + fluid inputs/outputs (refineries, blenders, packagers). Depends on the catalogue ingestion epic landing first (Docs.json contains fluids alongside items, but they need separate handling). ## Out of scope - Pipe layout / pathfinding (a logistics planner concern, not an ERP one). - Visual pipe routing on a map.

    No due date
    1/1 issues closed
  • Replace the hand-coded 12-item seed with a runtime ingestion of the user's installed Docs.json. Items, buildings, recipes (including alternates). English text only — translation deferred. ## Decisions made - **Source:** parse the user's Docs.json at startup. Aligns with whatever patch level they have installed. No vendored game data in the repo. - **Loading:** JSON load on startup, dynamic. No codegen, no checked-in .cs catalogue. - **Multi-game:** ingestion lives behind an Application-layer contract so a future Factorio/etc. adapter can plug in. Satisfactory.Catalog is the first adapter. - **Scope:** items + buildings + recipes (incl. alternates) only. Fluids and extractors/nodes get their own epics — they each have distinct logic. - **Icons:** out of scope. Text-only for v1 with category fallbacks. Real icon extraction from the user's game install is a later epic. - **Default Docs.json:** not now; we may ship a default later as a fallback. ## Open architectural questions (need ADRs before code) - Where does the user point us at Docs.json? (config setting, env var, auto-detect Steam common paths?) - What does the Application-layer catalogue contract look like to stay game-agnostic? (current `IRecipeCatalog` likely needs widening or splitting.) - Where does the parsed catalogue live at runtime? (singleton in DI, hot-reloadable, file-watched?) ## Out of scope - Fluids (separate epic). - Extractors / resource nodes / generators (separate epic). - Schematics / milestones (separate epic if we ever need them — gating recipes by tier is a UX choice, not a planner one). - Icons. - Localization.

    No due date
    6/6 issues closed
  • Render the production plan as an interactive graph alongside the table view. Nodes show recipe, building count, in/out rates; edges show item flows with quantities. Layout via ELK or library auto-layout. Hover/tooltips, viewport fit; drag-to-edit not required for v1. Architecturally significant — requires an ADR on rendering approach: JS interop with vis-network/Cytoscape vs. Blazor-rendered SVG. Reference: greeny/SatisfactoryTools uses vis-network with ELK layout (cytoscape is bundled but unused).

    No due date
    1/1 issues closed
  • Replace the naive backwards-expansion planner with a real linear-programming solver. New inputs: per-resource max + weighting, alternate-recipe allow-list, blocked recipes/machines/resources, sinkable resources. Output: machine groups, power per group, leftover/sink amounts. Handles byproducts and multi-recipe optimization. Architecturally significant — requires an ADR on solver choice (likely Google OR-Tools .NET binding) before implementation. Reference: greeny/SatisfactoryTools does this server-side via a closed-source LP at api.satisfactorytools.com/v2/solver.

    No due date
    5/5 issues closed
  • Blazor pages for entering production targets, listing available resources, and visualising the computed plan.

    No due date
    5/5 issues closed
  • Solution scaffold, CI, baseline conventions. Everything we need before product features land.

    No due date
    16/21 issues closed