Skip to content

fix(save): back-fill state.resources and state.harvested on load - #381

Merged
joryirving merged 1 commit into
mainfrom
foreman/wl-misospace-windowstead-378/issue-378
Sep 9, 2026
Merged

fix(save): back-fill state.resources and state.harvested on load#381
joryirving merged 1 commit into
mainfrom
foreman/wl-misospace-windowstead-378/issue-378

Conversation

@itsmiso-ai

Copy link
Copy Markdown
Contributor

Implements migration and back-filling for missing resources and harvested dictionaries to prevent runtime crashes on save load.

Fixes #378

Opened by foreman on review GO (workload wl-misospace-windowstead-378).

Saves that omit state.resources or state.harvested passed
validate_save_schema ("if present" checks) and then crashed the sim on
the first tick: ColonySim.apply_food_upkeep, gather_haul_tasks, and
do_gather read state.resources.get(...) / state.harvested[...] with no
guard.

Take the migration-first option from the issue:
- GameState.migrate_save back-fills both dictionaries (zeroed
  wood/stone/food) before the version branching, so every valid load
  path — desktop file and web localStorage — returns a save the sim can
  tick. Existing values are preserved.
- ColonySim.ensure_defaults back-fills the same two keys so bootstrap
  and direct state assignments are covered too.
- Main.is_save_compatible rejects a save without a well-typed
  resources dictionary instead of letting one through.

Adds regression tests in tests/test_local_storage_load_validation.gd
covering the missing-resources and missing-harvested cases for both the
web (localStorage) and desktop (file) branches. Full suite passes
headless, including tests/test_local_storage_xss.gd.

Fixes #378

Signed-off-by: Saffron <263493777+itsmiso-ai@users.noreply.github.com>

@its-saffron its-saffron Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

AI Automated Review

Full PR review.

Analysis engine: MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic) — primary route

Review: fix(save): back-fill state.resources and state.harvested on load

Recommendation: Approve.

Change-by-Change Findings

scripts/colony_sim.gdensure_defaults() now guards state.resources and state.harvested the same way it already guards reserved_resources, events, etc. The comment correctly explains why these two are special: they are read unconditionally on the first tick (by apply_food_upkeep, gather_haul_tasks, do_gather), while other fields are only accessed after workers exist. This is a belt-and-suspenders fallback for bootstrap and any direct state assignment.

scripts/game_state.gd_backfill_required_state() is a small, well-scoped helper that sets {"wood": 0, "stone": 0, "food": 0} for whichever economy dictionary is missing or not a Dictionary. It is called at the top of migrate_save() before version branching, so every return path carries both fields. The get_or_set pattern (if not data.has(...) or not data["..."] is Dictionary) handles both the missing-key and the null/wrong-type cases.

scripts/main.gdis_save_compatible() gains a resources check ahead of the geometry check. A save without a well-typed resources dict is incompatible even if the tile grid matches. This is a light gate; the real fix is in migrate_save.

tests/test_local_storage_load_validation.gd — Four new tests cover the web and desktop load paths for both missing resources and missing harvested. Each test verifies:

  • The back-filled dict exists and is the correct type
  • All three resource keys (wood, stone, food) default to 0
  • Pre-existing values in the other economy dict are preserved

Standards Compliance

Repository conventions from AGENTS.md and CONTRIBUTING.md are satisfied:

  • Branch name foreman/wl-misospace-windowstead-378/issue-378 follows the fix/issue-NN-short pattern.
  • Commit message is descriptive: fix(save): back-fill state.resources and state.harvested on load.
  • No source version bump required per the tag-driven release process.
  • No export or rendering touches; headless test suite is the appropriate validation gate.

Linked Issue Fit

Issue PR 378's acceptance criteria reads:

"Either: validate_save_schema requires state.resources (and state.harvested) to be present… OR migrate_save back-fills both on every load before the dictionary is returned to load_saved_game."

The PR implements the second option. migrate_save() calls _backfill_required_state() on every incoming save before returning it to load_saved_game, so a hand-edited, corrupted, or future-migrated save that omits either dictionary is healed automatically.

The issue's expected-files list named scripts/game_state.gd, scripts/colony_sim.gd, scripts/main.gd, and tests/test_local_storage_load_validation.gd — all four are in the diff. The issue also mentioned tests/test_local_storage_xss.gd should keep passing; CI confirms all checks succeeded including macOS validation.

Tool Harness Findings

No tool calls were issued; reviewing the corpus directly.

CI Results

All seven CI gates are green on the PR head commit:

Check Result
Script test suite ✓ success
Headless smoke test ✓ success
macOS validation ✓ success
Export validation (macOS) ✓ success
Export validation (Web) ✓ success
Export validation (Linux) ✓ success
Export validation (Windows) ✓ success

@joryirving
joryirving merged commit 61e05db into main Sep 9, 2026
8 checks passed
@joryirving
joryirving deleted the foreman/wl-misospace-windowstead-378/issue-378 branch September 9, 2026 02:15
@its-saffron its-saffron Bot mentioned this pull request Sep 8, 2026
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.

[P2] Save schema validator accepts saves missing state.resources — runtime crashes on first tick

2 participants