Files
stickman/docs/specs/phase_9_prop_editor_round5.md
T

2.7 KiB

Phase 9 Prop Editor — Round 5 (File → Recent + save-serialization fix)

Status: implemented (2026-09-19; direct bugfix + feature round).

Source: two user feedback points against the shipped Round 4 Prop Editor.

Feedback summary

  1. File → Recent: show the last 5 opened props (sandbox-stage pattern).
  2. Loading content/props/eye.prop draws nothing (the prop name shows, geometry is blank).

Diagnosis (point 2 — root cause)

PropFile._serialize_shape() declared

var points: PackedVector2Array = shape.get("points", PackedVector2Array())

but the editor always serializes export-format shapes whose points is an Array of {x, y} dictionaries. The implicit Array → PackedVector2Array conversion cannot construct Vector2 from a dictionary and silently yields Vector2.ZERO per element, preserving the count but zeroing every coordinate. Every save therefore wrote all points as (0, 0) — verified in content/props/eye.prop and content/props/box.prop (all x: 0.0, y: 0.0), which load as a degenerate, invisible shape. The round-1 tests only asserted point counts and dict shape, so the corruption slipped through.

Fix: _serialize_shape() now uses the existing _coerce_points() helper (which handles both PackedVector2Array and Array-of-{x,y} inputs). Regression assertions were added so point values are verified through to_file_dict and the full round-trip.

The two already-saved user files (content/props/eye.prop, content/props/box.prop) are unrecoverable (every coordinate was zeroed at save time) and must be re-authored.

Changes

Target Change
scripts/editors/prop/prop_file.gd _serialize_shape uses _coerce_points (bug fix).
scripts/editors/prop/prop_editor.gd SETTINGS_PATH := "user://prop_editor_settings.json", RECENT_MAX := 5, _recent_props; update_recent_list(list, path, max) static (dedupe + front-insert + trim); 🕑 Recent submenu in the File menu (RecentProps child popup, updated on about_to_popup, missing files pruned, "(No recent props)" placeholder); _load_settings/_save_settings; _push_recent(path) on every successful load; missing recent → error dialog + removal.
tests/test_prop_editor_file.gd New value-preservation assertions (serialized x == 64, round-trip (64,0)/(64,64)).
tests/test_prop_editor_round3.gd New _test_recent_list (dedupe, front-insert, trim).

Verification

  • --check-only clean; all five suites green: file 66, theme 53, canvas 87, thumb 10, round3 21.
  • Manual F6: save a prop with shapes at distinct coordinates, reload — geometry must match; File → 🕑 Recent lists the last 5 opens and opens them; missing recent file shows the error and prunes itself.