Skip to content

fix: stage pinned docker/saves into AppData before native game/load - #76

Merged
jkbennitt merged 1 commit into
masterfrom
cursor/native-live-save-pin-d919
Sep 8, 2026
Merged

fix: stage pinned docker/saves into AppData before native game/load#76
jkbennitt merged 1 commit into
masterfrom
cursor/native-live-save-pin-d919

Conversation

@jkbennitt

Copy link
Copy Markdown
Member

Why

Native runs (docker_mode: false) call POST /api/v1/game/load with file_name=rle_crashlanded_v1. RIMAPI loads that name from RimWorld AppData Saves, not from docker/saves/.

#75 updated docker/saves/rle_crashlanded_v1.rws (built SimpleResearchBench + queued Smithing) and re-pinned YAML save_sha256. The loader pin in src/rle/scenarios/loader.py only hashed the repo mirror. A stale April AppData file (no bench / no currentProj) still loaded on native machines. Docker is fine: docker/entrypoint.sh already symlinks /opt/saves into the container Saves folder. Native had no equivalent.

What landed

  • ensure_live_save() copies docker/saves/<name>.rws into the OS Saves folder (Windows AppData LocalLow / macOS Application Support / Linux ~/.config/unity3d/...) when the live SHA ≠ the scenario pin.
  • Matching live file is a no-op (no copy).
  • Fail closed: missing canonical, canonical hash ≠ pin, copy I/O error, or post-copy hash still wrong → LiveSavePinError before game/load. run_scenario exits 1; run_benchmark does not swallow the pin error.
  • Wired through load_save_and_settle(..., stage_live=) so Crashlanded and the other pinned scenarios get it. Native CLIs pass stage_live=True; --docker passes False.
  • Run metadata / console record live_save_sha256 and live_save_copied. Optional $RLE_RIMWORLD_SAVES override (also reused by create_scenario_saves.py).

Tests

  • mismatch → copy → match
  • already-matching AppData is a no-op
  • fail closed when canonical missing, pin/canonical disagree, or post-copy hash is wrong
  • load_save_and_settle stages before game/load, skips staging when stage_live=False, and does not call load_game on pin failure

No scoring changes, no matrix / billed model / cal runs.

Out of scope

  • Scoring 1.2 / SCORING_VERSION
  • Baseline recalibration
  • Rebuilding the five derived scenario saves
Open in Web Open in Cursor 

Native POST /game/load reads RimWorld AppData Saves, not docker/saves.
The YAML pin only hashed the repo mirror, so #75's Crashlanded seed
(SimpleResearchBench + Smithing) could be ignored in favor of a stale
April AppData file. Copy the canonical save when the live hash diverges
and fail closed if the pin cannot be satisfied.

Co-authored-by: Jason <jkbennitt@users.noreply.github.com>

@jkbennitt jkbennitt left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — closes the native/AppData gap after #75: ensure_live_save stages docker/saves → OS Saves when live SHA ≠ pin; fail-closed LiveSavePinError before game/load; docker skips (stage_live=False); metadata live_save_sha256/copied; RLE_RIMWORLD_SAVES override. Tests cover copy/no-op/fail-closed/load_save_and_settle wiring. No scoring/matrix. All five CI SUCCESS on df06459 (run 34259830319). Still draft — HOLD merge for CoS clear; plain squash (no --admin).

@jkbennitt
jkbennitt marked this pull request as ready for review September 8, 2026 17:55
@jkbennitt
jkbennitt merged commit c9b5147 into master Sep 8, 2026
5 checks passed
@jkbennitt
jkbennitt deleted the cursor/native-live-save-pin-d919 branch September 8, 2026 17:56
cursor Bot pushed a commit that referenced this pull request Sep 8, 2026
Move the post-#76 adapter tests into their own class so the existing
read-endpoint cases stay under TestReadEndpoints.

Co-authored-by: Jason <jkbennitt@users.noreply.github.com>
jkbennitt added a commit that referenced this pull request Sep 8, 2026
…rge) (#77)

* fix: read BuildingDto.def and merge research progress

Post-#76 native pin-match still reported research_bench_present false
and research_target Smithing locked. Live buildings use snake_case def
(label fallback has spaces); /research/summary has no current project
and by-tech-level bucketing dropped Smithing from available.

Map def → def_name → label, strip spaces in the bench matcher, and
merge /research/progress + finished + tree so current can be Smithing.

Co-authored-by: Jason <jkbennitt@users.noreply.github.com>

* test: keep research adapter cases out of TestReadEndpoints

Move the post-#76 adapter tests into their own class so the existing
read-endpoint cases stay under TestReadEndpoints.

Co-authored-by: Jason <jkbennitt@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Jason <jkbennitt@users.noreply.github.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.

2 participants