Skip to content

Gsd/phase 0 logic port pr - #2

Open
kindasneaki wants to merge 110 commits into
masterfrom
gsd/phase-0-logic-port-pr
Open

Gsd/phase 0 logic port pr#2
kindasneaki wants to merge 110 commits into
masterfrom
gsd/phase-0-logic-port-pr

Conversation

@kindasneaki

Copy link
Copy Markdown
Owner

No description provided.

kindasneaki and others added 30 commits June 22, 2026 20:24
…gy gate

- engine.cjs: graph reach engine reproduces Randovania reachability
  (all items => 149/149 pickups + Ship victory; monotonic in items)
- match-artaria.cjs: affine-fit reconciliation, 35/35 bijection, 12px worst match
- energy.cjs: damage-as-max-energy gate, Dread-accurate suit reductions
- Deltas: Itorash has 0 pickups; +3 = boss pickups (Z-57, Kraid, Drogyga)
- FINDINGS.md + STATE.md updated; Phase 0 complete

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…1, DAT-02)

- Add scripts/refresh-logic-db.mjs: ESM node script copying 10 JSON files
  from RDV_DREAD_DB (default local checkout) into public/logic/ with VERSION.txt
- Vendor public/logic/{header,Artaria,Cataris,Dairon,Burenia,Ferenia,Ghavoran,
  Elun,Hanubia,Itorash}.json from Randovania schema_version=33 checkout
- public/logic/VERSION.txt records randovania_rev + schema_version=33 + copy date
- Zero new npm dependencies; only node:fs + node:child_process built-ins used
- Export EXPECTED_SCHEMA_VERSION=33 (pinned from verified header.json)
- Export assertSchema(loaded): throws descriptive Error on schema drift
- Export createGameModel(db): calls assertSchema, returns Object.freeze sentinel
- Export recompute(model, resourceState, settings): returns {inLogicPickups, energyRisk} stubs
- Zero Node built-in / Vue / Vuex imports — shared browser+node seam
- Plan 02 will replace stub bodies with real engine implementation
… (VAL-01)

- Import createGameModel/recompute/assertSchema/EXPECTED_SCHEMA_VERSION from src/logic/index.js
- Load vendored db via fs.readFileSync of public/logic/*.json (node-side; proves shared seam)
- ENGINE_READY detection: active if model._stub is absent + pickupCount > 0 (auto-activates in Plan 02)
- PASS (active now): vendorPresent, schemaGuard, immutable
- SKIP with "engine pending Plan 02": allItems, noItems, monotonic, templates, trickLevel,
  miscNegate, energy, energyRisk, missileGate, starterBaseline
- Exits 0; prints PASS n / SKIP m / FAIL k summary line
- Zero third-party imports; uses only node:assert, node:fs, node:path, node:url
- templates.js: makeExpander(rdb) — memoized, cycle-guarded, 45 templates expand clean
- Requirement.js: evaluate(req, state, ctx) — and/or/resource/negate; damage via energy gate
- energy.js: maxEnergy, reductionMultiplier, damagePasses — Dread-accurate suit reductions
- ZERO Node/Vue imports in all three modules (shared-code seam enforced)
…hability

- GameModel.js: createGameModel(db) — 1860-node frozen graph, all templates pre-expanded
- dockRequirement honors override_default_open_requirement (8 non-null overrides in Dread)
- Reachability.js: reach() fixpoint BFS, reachablePickups(), collectEnergyRisk()
- All-items run: 149/149 pickups + Ship victory (7 fixpoint passes)
- No-items run: 0 pickups, no Ship
- Energy-risk set non-empty (8 risky pickups) for low-tank/no-suit state
- ZERO Node/Vue imports enforced in both modules (DAT-04 immutability asserted)
…attery green

- Settings.js: defaultSettings(header) with D-04 starter preset (trickLevel 0, NerfPB:1, strictness 1.5)
- itemMap.js: ABILITY_TO_RDV — 24 major ability ids mapped to Randovania short-names
- ResourceState.js: buildResourceState(obtained, counters, settings, rdb) — missile/PB/energy fan-out
- index.js: createGameModel delegates to GameModel; recompute wires reach+pickups+energyRisk
- Lint auto-fix applied to energy/GameModel/Reachability/index/ResourceState
- validate-logic.mjs missileGate fix: add Slide:1 to both states (Dread starting ability;
  without Slide the tutorial area is unreachable, making missile comparison degenerate)
- All 13 validation cases ACTIVE and PASS; SKIP 0 / FAIL 0
- Async load action fetches public/logic/*.json in parallel via
  process.env.BASE_URL (Pitfall 4 / gh-pages publicPath fix)
- assertSchema + createGameModel on success; SET_ERROR on any failure
  (fail loudly, T-01-07)
- recompute reads rootGetters['items/inLogic'] + root counters, builds
  ResourceState via buildResourceState, runs the engine, stores result
- Early-return load gate (state.ready) — no-op until GameModel is cached
- D-05 non-breaking: zero Tracker.vue / items.updateArea references
…app init

- src/store/index.js: import logic module, add to modules map alongside
  existing artaria…hanubia + items modules
- src/App.vue: import useStore + onMounted; dispatch logic/load once on
  mount to warm the engine at boot (D-02); existing UI untouched (D-05)
- npm run build exits 0; logic JSON stays in public/ (not bundled)
- Import buildResourceState + defaultSettings into validate-logic.mjs
- New recomputeIntegration case (case 14) exercises the items→
  ResourceState→recompute wiring the Vuex logic/recompute action uses,
  without Vuex: buildResourceState(obtained, counters, settings, rdb)
  → recompute(model, resourceState, settings)
- Asserts both outputs are instanceof Set (ENG-07)
- Asserts no-items via ResourceState matches raw noItems path (consistency)
- Asserts Morph+Slide obtained >= no-items (monotonic via ResourceState)
- Skip case added to ENGINE_READY else-branch for forward compat
- Battery: PASS 14 / SKIP 0 / FAIL 0; lint clean
…ection

- LOCATION_PICKUP_MAP.artaria: the Phase 0 verified 35-entry tracker→pickup_index array
- pickupIndexFor(region, i): lookup helper; throws descriptively on unknown region or OOB
- assertArtariaBijection(rdvArtariaJson): MAP-04 bijection guard (35 entries, unique, valid)
- assertArtariaTypeConsistency(rdvArtariaJson, locations): MAP-05 keyword-match guard
- Zero Node built-in imports; zero Vue/Vuex imports (runs in browser + node)
- mapImmutable: asserts LOCATION_PICKUP_MAP.artaria has 35 entries + only 1 region key
- bijection: assertArtariaBijection confirms 35-entry true bijection (0 uncovered)
- typeConsistency: assertArtariaTypeConsistency verifies all 35 node-name keywords match
- pilotParity: 4-kit battery (noItems/+Slide+Missiles/+Varia+Grapple/allItems)
  → 13 disagreements total, within DISAGREEMENT_BUDGET=13; each printed in terse rdv-parity format
- Reimplements legacy checkLogic as legacyInLogicForLoc pure fn (no Vuex)
- validate-logic.mjs regression intact (PASS 14/14)
- lint clean; node:assert only, zero new npm packages
…-after-load to logic module

- state.useRandovaniaLogic defaulting false (MIG-01, D-01)
- SET_FLAG mutation coerces to boolean
- setFlag action commits flag and recomputes immediately if already ready
- useRandovaniaLogic getter
- load action dispatches recompute after SET_MODEL (D-03 initial paint)
…eAbility + items updateArea

- root updateAbility (src/store/index.js): adds dispatch + rootGetters; fires logic/recompute
  after the counter commit when logic/useRandovaniaLogic is ON — the load-bearing chokepoint
  for map-collection of missiles/energy/power-bomb (MIG-02)
- items/updateArea (src/store/modules/items.js): adds rootGetters; fires logic/recompute
  when flag ON for ability-grid toggles — legacy checkLogic dispatch kept unconditional
… flagOnSwitch + recomputeTrigger

- main.js: reads URLSearchParams ?rdv=1 (strict === "1"), dispatches logic/setFlag(true)
  before mount when present; window-guarded for non-browser safety (T-02-03)
- parity-artaria.mjs: adds flagOnSwitch case (MIG-01) — verifies 3-way classification
  contract (inLogic/softlock/noLogic) via pickupIndexFor for +Varia+Grapple kit
- parity-artaria.mjs: adds recomputeTrigger case (MIG-02) — asserts BOTH ability delta
  (setA→setB size growth) AND counter delta (tracker-index 15 pickup_index 31 flips
  missiles=0→OUT to missiles=10→IN via buildResourceState), guards Blocker-1 bug class
- all 6 cases PASS; pilotParity disagreement budget (13) unchanged
…ing to Artaria.vue

- Add pickupIndexFor import from @/logic/pickupMatch.js
- Add mapGetters for logic/useRandovaniaLogic, logic/inLogicPickups, logic/energyRisk
- Add locationStates computed: OFF path returns {shown: location.inLogic, softlock: location.softlock}; ON path derives from energyRisk/inLogicPickups via pickupIndexFor
- Add parityWarnings computed + inLogicPickups watcher: console.warn per-location disagreements only when flag ON (format: rdv parity: location {i} ({area}): old=.., new=..)
- Rewrite template v-for to (location, index) in locations; drive shown/softlock from locationStates[index]
- No location objects mutated; legacy artaria/checkLogic remains and still runs
- No new CSS/classes added; existing .toggle_switch/.toggle_switch_softlock/.toggle_switch_noLogic reused
- Add offPathState(location) pure function mirroring the view's OFF branch (returns {shown: location.inLogic, softlock: location.softlock || false})
- Add flagOffParity case: for all 35 locations x 4 battery kits, assert offPathState is the identity over (legacyInLogicForLoc result, location.softlock)
- Proves the OFF branch introduces zero divergence from legacy fields and reads no engine state
- Battery now PASS 7 / FAIL 0 (mapImmutable, bijection, typeConsistency, pilotParity, flagOnSwitch, recomputeTrigger, flagOffParity)
- validate-logic.mjs still PASS 14 / FAIL 0
kindasneaki and others added 30 commits June 27, 2026 08:14
… directly (matches Randovania's binary model)
…ons to items store

- add metroidDna array of 3 {type,name,checked} entries (DNA 1/2/3) to items state
- add TOGGLE_DNA mutation to flip checked state of a single DNA entry
- add HYDRATE_DNA mutation for absolute-set restore from checkedItems persistence map
- extend RESET_ITEMS to also clear all 3 DNA entries on resetProgress
- add toggleDna action (no logic/recompute - DNA is display-only goal item)
- add metroidDna getter for Tracker.vue consumption
- inLogic getter unchanged (returns state.items only; engine ignores DNA)
… + wire persistence

- add metroidDna to mapState in Tracker.vue
- render 3 DNA checkbox grid cells with hover tooltip and active/notActive styling
- add dnaChecked() method dispatching items/toggleDna (no logic recompute)
- add .metroidDna CSS class for text-label display (no icon asset)
- fold DNA into persist() snapshot items array so DNA checked states land in checkedItems map
- call items/HYDRATE_DNA in restoreState to rehydrate DNA toggles on page load
- resetProgress already commits items/RESET_ITEMS which now clears DNA (Task 1)
…egion views

- add :title="locationLabel(location)" to toggle_box wrapper div in each region view
- add locationLabel(location) method deriving tooltip from area/type/amount + region name
  (e.g. "Artaria — Location 3 (missiles ×2)") — no new per-location data field added
- mirrored identically across Artaria, Burenia, Cataris, Dairon, Elun, Ferenia,
  Ghavoran, Hanubia with each file's correct region name
- uses native HTML title attribute for zero-JS tooltip plumbing
…nNames.js map

- scripts/gen-location-names.cjs reads LOCATION_PICKUP_MAP + public/logic/*.json,
  resolves each tracker array index to the Randovania area (room) name, self-asserts
  per-region counts (35/25/23/20/17/20/5/4), and emits src/logic/locationNames.js
- src/logic/locationNames.js exports LOCATION_NAME_MAP and locationNameFor(region, index)
- burenia[19] === "Drogyga Arena" confirmed; fallback returns capitalized region name
…ip map

- All 8 views (Artaria, Burenia, Cataris, Dairon, Elun, Ferenia, Ghavoran, Hanubia)
  now import locationNameFor from @/logic/locationNames.js
- locationLabel renamed parameter to index, returns "Region -- RoomName" using the
  authoritative Randovania room name; removes all item/amount/Location-N text
- Template binding updated from locationLabel(location) to locationLabel(index)
- locationNames.js reformatted by Prettier (one element per line) and re-staged
- npm run lint passes with no errors
…o match app style

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Drogyga Arena: move from far-left (top:510,left:101) to top:140,left:302
- swap Burenia Hub to Dairon (7) and Gravity Suit Tower (3m) coordinates
  (they were reversed)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Derived marker positions from Randovania game coordinates via an affine
game->map-pixel transform (calibrated on cross-region transports, refit on
the 9 already-correct markers, residuals <=9px). Fixes the Gravity Suit
Tower / Main Hub Tower Middle swap and 9 other mispositioned markers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The 3 markers for Separate Tunnels Room (L/R) + Pitfall Puzzle Room were
shuffled; repositioned from Randovania game coordinates (transform fit on
the region's correctly-placed markers, residuals <=4px). Verified on icons.

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

Audit of all 8 regions via affine game-coordinate->map-pixel transforms.
Normal pickups were correct everywhere except Burenia & Ferenia (fixed
separately). This corrects the remaining major-item markers (boss / Central
Unit / EMMI rewards), which sit at their Randovania node coordinates (the
arena location), matching the convention of already-correct boss markers
like Kraid and Storm Missile:
- Artaria: Spider Magnet, Phantom Cloak
- Cataris: Morph Ball, Z-57
- Dairon: Speed Booster
- Ghavoran: Ice Missile, Cross Bomb
- Ferenia: Wave Beam
And all 4 Hanubia markers (2 missile tanks, power bomb tank on the in-game
icons + EMMI power bomb at node), which were scrambled. Marker icon centers
located by color detection for precision.

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

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

The node-coordinate placement (238,293) was off; restoring the original
(245,329) per user feedback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restore the EMMI ability-reward markers to their pre-task positions per user
feedback (node-coordinate placement was off):
- Cataris greenEMMI (Morph Ball) -> (139,322)
- Hanubia power (Orange EMMI Power Bomb) -> (282,829)

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

Per user feedback, restore the node-coordinate-placed boss/Central-Unit/EMMI
reward markers to their pre-task positions:
- Artaria whiteEMMI (Spider Magnet) -> (293,643), corpius (Phantom Cloak) -> (225,817)
- Ghavoran blueEMMI (Ice Missile) -> (100,200), cross (Cross Bomb) -> (78,644)
- Ferenia wave (Wave Beam) -> (121,1003)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bump dev toolchain: @vue/cli-* 4.5→5.0.9, eslint 6→8.57, prettier 2→3,
eslint-plugin-vue 7→9, @vue/eslint-config-prettier 6→9. Swap babel-eslint
for @babel/eslint-parser, relax Prettier endOfLine to "auto", and disable
vue/multi-word-component-names.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the Windows-only deploy.bat workflow: deploy.sh builds, writes a
.nojekyll file into dist/ (so GitHub Pages serves the webpack output verbatim
instead of running it through Jekyll, which was failing the Pages build), then
force-pushes dist/ to the gh-pages branch. Point `npm run deploy` at it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
public/logic/*.json are generated Randovania data (regen via
scripts/refresh-logic-db.mjs). Flag them linguist-generated + -diff so GitHub
collapses them and suppresses the ~143k-line textual diff in PR review. The
files are still committed — the static site fetches them at runtime.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The production build was committed to source so it could be deployed to
gh-pages. deploy.sh now builds and pushes dist/ via its own throwaway git repo
(off the on-disk files), so tracking dist/ in source is unnecessary and just
adds churn. Ignore /dist/ and remove the 23 stale tracked build files; the
files stay on disk for deploys.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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