Skip to content

Milestone 9: Stationeers IC10 backend - #10

Merged
dustinsurwill merged 5 commits into
mainfrom
milestone-9-ic10-backend
Aug 18, 2026
Merged

dustinsurwill merged 5 commits into
mainfrom
milestone-9-ic10-backend

Conversation

@dustinsurwill

@dustinsurwill dustinsurwill commented Aug 18, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Second Game entry (src/games/ic10/): grew from an initial 9-node catalog to 35 nodes covering all 154 real IC10 instructions (119 directly, 3 reachable-but-not-literally-emitted, 8 reachable-but-unoptimized, 24 deliberately excluded — see docs/ic10-api-notes.md for the full reconciliation), after cross-checking against the VS Code extension/ic10.dev/ic10emu.dev ecosystem (all share the @stationeers-ic/ic10 npm package — AGPLv3-licensed, used only as a fact-reference, never copied in, same posture as reading a wiki page).
  • Codegen (src/games/ic10/codegen/generate.ts) is flat and label-based, not recursive-method-call like Space Engineers — IC10 has no functions/call stack, just natively-supported labels and j/branch jumps. Number Math/Compare each fold an entire instruction family into one Operator combo (50 and 33 instructions respectively); Compare also auto-optimizes to the shorter zero-compare/call-and-link mnemonics. New categories: Batch Devices (network-wide lb/sb/... addressed by prefab hash), Slots, device-by-ID, device-presence checks, reagents, subroutine call/return, and the IC's own stack.
  • Imported and extended a device/LogicType reference (src/games/ic10/deviceLogicTypes.json, 145 devices/1546 rows, now including prefab hashes) compiled from the Stationeers Community Wiki, powering a DeviceType property + LogicType suggestion picker — UI-only except for the batch nodes, where DeviceType is a real codegen input.
  • Generalized ScriptPreview's size-limit display via new optional Game.charLimit/Game.lineLimit fields so IC10 gets a correct line-count readout instead of a meaningless character count.
  • Fixed a real bug found while manually testing: the batch nodes' optional DeviceName field defaulted to '' and tripped the generic "property is empty" validation error (that rule doesn't know some fields are legitimately optional) — switched to a '(none)' sentinel default.

Test plan

  • npm run test — 232/232 passing (56 IC10-specific tests: register aliasing, Compare's zero/call-and-link opcode selection, Number Math's arity dispatch across ~50 operators, batch-device prefab-hash resolution + HASH() emission, device-presence checks, stack ops, >16-register/>128-line warnings)
  • npx tsc -b, npm run build, npm run lint — all clean
  • Manual browser pass via chrome-devtools MCP: landing page → IC10 editor shows its full 35-node catalog grouped into 7 categories → Batch Read Device Property's DeviceType combo correctly filtered to hash-known devices → confirmed the DeviceName empty-property false-positive is fixed → Read Device Property's DeviceType/LogicType picker still narrows correctly (verified in the prior commit)

🤖 Generated with Claude Code

dustinsurwill and others added 5 commits August 17, 2026 22:47
Second Game entry (src/games/ic10/): a 9-node catalog (Start/Sleep/Yield/
Loop To Start, Read/Write Device Property, Set Number/Number Math/Compare)
and a flat, label-based codegen distinct from Space Engineers' recursive-
method-call model - IC10 has no functions/call stack, just labels and
jumps, and a hard 128-line/90-char cap instead of a soft character budget.

Reuses src/lib/graph.ts's findStartNodes/getReachableNodeIds as-is (already
game-agnostic, confirming the Milestone 8 architecture's claim that
graph-walk logic doesn't need per-game duplication). Register allocation
aliases each declared variable to r0-r15 by first appearance, warning past
16. Generalized ScriptPreview's size-limit display (previously hardcoded
to Space Engineers' char budget) into optional Game.charLimit/Game.
lineLimit fields so IC10's line-count cap gets its own correct readout.

Verified: 200/200 tests passing (10 new IC10 codegen tests), typecheck/
build/lint clean, and a manual browser pass (landing page lists both
games, IC10 editor shows only its own 9-node catalog, palette/property-
panel/validation/script-preview all render correctly for it).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Compiled 145 devices/1546 logic-parameter rows from the Stationeers
Community Wiki's per-device pages (site is Cloudflare-Turnstile-gated,
blocking automated fetch, so this was gathered via a real browser session
and handed in as a markdown export) into src/games/ic10/deviceLogicTypes.
json, with a small typed wrapper (logicTypeNamesFor filters by device +
read/write access).

Added a `DeviceType` combo property to Read/Write Device Property nodes -
UI-only, since a graph's `Device` property is just a physical IC pin
(d0-d5/db), not a guarantee of what's actually wired to it in-game; it
only scopes a new LogicType suggestion picker. Generalized ItemPicker
(previously hardcoded to Space Engineers' "Pick Item ID" label) to accept
a label/title, and reused it as-is for LogicType rather than building a
new component. Game.logicTypeCatalog is the new optional Game field
carrying this - a device-scoped alternative to the flat itemList pattern.

None of this touches codegen: generate.ts still only ever reads a node's
Device/LogicType properties verbatim.

Verified: 205/205 tests passing (5 new deviceLogicTypes tests), typecheck/
build/lint clean, manual browser pass (DeviceType combo lists all 145
devices, LogicType picker correctly narrows to Active Vent's 26 readable
LogicTypes when scoped, button/help text no longer says "Item ID").

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Grew from the initial 9-node catalog to 35 nodes, reconciled against
every one of IC10's 154 documented instructions (119 directly covered,
3 reachable-but-not-literally-emitted, 8 reachable-but-unoptimized, 24
deliberately excluded - see docs/ic10-api-notes.md for the full
breakdown). Cross-checked against the VS Code extension/ic10.dev/
ic10emu.dev ecosystem (all share the @stationeers-ic/ic10 npm package,
AGPLv3-licensed - used only as a fact-reference to verify instruction
names/syntax exist, same as reading a wiki page, never copied in).

Number Math and Compare each fold an entire instruction family into one
Operator combo (50 and 33 instructions respectively) rather than one
node per mnemonic - Compare also auto-optimizes to the shorter
zero-compare ("z") and call-and-link ("al") mnemonics based on property
values, since IC10's own naming happens to just concatenate those
suffixes onto the base opcode. New node categories: Batch Devices
(network-wide lb/sb/lbn/sbn/lbs/lbns/sbs, addressed by prefab hash - the
one place DeviceType is a real codegen input, not just a UI hint), Slots
(ls/ss), plus device-by-ID, device-presence-check, reagent, subroutine
call/return (jal/ra), and stack nodes.

Re-derived deviceLogicTypes.json to include each device's prefab hash
(needed for the batch nodes) alongside the existing LogicType data.
Fixed a real bug found while testing: the batch nodes' optional
DeviceName field was defaulting to '' and tripping the generic
"property is empty" validation error, since that rule doesn't know some
fields are legitimately optional - switched to a '(none)' sentinel
default instead.

Verified: 232/232 tests passing (56 new IC10 tests across generate.ts
and deviceLogicTypes.ts), typecheck/build/lint clean, manual browser
pass (35-node catalog renders correctly by category, Batch Read Device
Property's DeviceType combo correctly filtered to hash-known devices,
DeviceName empty-property false-positive confirmed fixed).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Solar Tracker uses Batch Write (network-wide by device type) instead of
per-panel pins, so it works unchanged for any number of panels — no
wizard/parameters needed. Pressure Alarm demonstrates a Compare node's
True/False branches converging back onto one shared Sleep before looping.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Every node used to get its own label and an explicit trailing jump
regardless of whether anything needed either. Now each node's output is
built as a block, then a peephole pass drops a trailing jump when its
target is already the physically-next block (true fallthrough) and drops
any label nothing still jumps to. Order-preserving, no graph reordering —
pure size reduction for the common case of graphs authored roughly in
execution order, which matters given IC10's hard 128-line cap.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@dustinsurwill
dustinsurwill merged commit 211c611 into main Aug 18, 2026
1 check passed
@dustinsurwill
dustinsurwill deleted the milestone-9-ic10-backend branch August 18, 2026 23:33
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.

1 participant