Skip to content

[CloudCraft Integration] Add authoritative WorldOverlayModel and repair 2D overlay truth path (#2465) - #2475

Draft
OuroborosCollective wants to merge 2 commits into
mainfrom
fix/cloudcraft-2465-2d-truth-slice
Draft

[CloudCraft Integration] Add authoritative WorldOverlayModel and repair 2D overlay truth path (#2465)#2475
OuroborosCollective wants to merge 2 commits into
mainfrom
fix/cloudcraft-2465-2d-truth-slice

Conversation

@OuroborosCollective

Copy link
Copy Markdown
Owner

Summary

First vertical CloudCraft integration slice (#2465). Establishes a pure, server-authoritative WorldOverlayModel and repairs the 2D overlay truth path: LiveGameplaySnapshot -> WorldOverlayModel -> 2D adapter.

Problem

The three overlay marker layers (WorldPoiMarkerLayer, ResourceNodeMarkerLayer, CampNpcMarkerLayer) existed as source files but were never mounted in the real /2d render path. Meanwhile, uiRuntimeManifest claimed "LIVE" + realRenderPath: true for them — a fake LIVE assertion with no causality. The layers also used component-local approximate isometric transforms (hardcoded worldOriginX=460, scale=1.2) instead of the canonical isometricProjection.ts.

What changed

  • WorldOverlayModel.ts — read-only presentation model derived exclusively from LiveGameplaySnapshot (POIs, resource nodes, camp NPCs, worldSurface). Deterministic stable sorting (relational compare), honest status (live/waiting/empty/stale/blocked), frozen output, real evidence counts. No Math.random, no wall-clock.
  • WorldOverlayProjection.ts — canonical isometric projection using shared isometricProjection.ts (iso2), replacing component-local approximate transforms. Viewport is an explicit adapter input.
  • OverlayReachabilityGuard.ts — verifies LIVE marker-layer claims via real import-graph evidence (markOverlayReachable at module-eval time). A layer is only live when its source module is actually imported by an entrypoint.
  • useWorldOverlayModel.ts — reactive hook deriving the overlay model from the live snapshot.
  • main.tsx — mounts the three marker layers in UIOverlayLayer (real /2d render path). They were previously unmounted.
  • All three marker layers refactored to consume WorldOverlayModel + canonical projection instead of duplicate approximate transforms.
  • uiRuntimeManifest.ts — notes updated to reflect the real mount path evidence.
  • ResourceMarker now handles the locked status honestly (was only available/depleted).

Rules honored (from issue)

  • ✅ No second truth: input is always a LiveGameplaySnapshot.
  • ✅ No client authority: model is display-only.
  • ✅ No Math.random() or wall-clock in the presentation model.
  • ✅ Camera/viewport only as explicit adapter input.
  • ✅ LIVE status backed by real import-graph reachability, not a hardcoded claim.
  • ✅ Snapshot evidence present before model is considered live.
  • ✅ Canonical isometric projection used instead of approximate marker transforms.

Validation

  • 18 new unit tests pass: WorldOverlayModel.test.ts (10), WorldOverlayProjection.test.ts (5), OverlayReachabilityGuard.test.ts (3).
  • tsc --noEmit: no new errors in touched files (pre-existing errors in other files unchanged).
  • eslint: clean on touched files.
  • Full client-2d suite: 187 passed (was 186 on main), 24 failed (was 25 on main) — all remaining failures are pre-existing DOM/environment (document is not defined) issues unrelated to this change; one previously-failing test now passes.

What could not be validated

Remaining risks


This PR was created by an AI agent (OpenHands) on behalf of the user.

@OuroborosCollective can click here to continue refining the PR

…rs (#2465)

First vertical CloudCraft integration slice: establish a pure,
server-authoritative WorldOverlayModel and repair the 2D overlay
truth path.

Changes:
- Add WorldOverlayModel: read-only presentation model derived
  exclusively from LiveGameplaySnapshot (POIs, resource nodes, camp
  NPCs, worldSurface). Deterministic stable sorting, honest status
  (live/waiting/empty/stale/blocked). No Math.random, no wall-clock.
- Add WorldOverlayProjection: canonical isometric projection using
  shared isometricProjection.ts (iso2), replacing component-local
  approximate transforms with hardcoded origins/scales.
- Add OverlayReachabilityGuard: verifies LIVE marker-layer claims
  via real import-graph evidence (markOverlayReachable at module-eval
  time), not hardcoded assertions.
- Add useWorldOverlayModel hook: reactive overlay model derivation.
- Mount the three marker layers (WorldPoi, ResourceNode, CampNpc) in
  UIOverlayLayer (main.tsx) — previously they existed as files but
  were never rendered. Now they are in the real /2d render path.
- Refactor all three marker layers to consume WorldOverlayModel +
  canonical projection instead of duplicate approximate transforms.
- Update uiRuntimeManifest notes to reflect real mount path evidence.
- ResourceMarker now handles 'locked' status honestly.

Validation:
- 18 new unit tests pass (WorldOverlayModel, WorldOverlayProjection,
  OverlayReachabilityGuard).
- tsc --noEmit: no new errors in touched files.
- eslint: clean on touched files.
- Full client-2d suite: 187 passed (was 186 on main), 24 failed
  (was 25 on main) — all pre-existing DOM/environment issues.

Co-authored-by: openhands <openhands@all-hands.dev>
…ositive

The determinism-changed-files-guard.mjs matches the literal pattern
Math.random() even in comments. Reworded the JSDoc comment from
'No Math.random() or wall-clock' to 'No nondeterministic RNG or
wall-clock' to avoid the false positive while preserving the intent.

Co-authored-by: openhands <openhands@all-hands.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant