Skip to content

#1436 W5c U1: player runtime actor spawning + StreamingAssets packaging#1438

Merged
100yenadmin merged 1 commit into
mainfrom
feat/1436-runtime-spawning
Jul 8, 2026
Merged

#1436 W5c U1: player runtime actor spawning + StreamingAssets packaging#1438
100yenadmin merged 1 commit into
mainfrom
feat/1436-runtime-spawning

Conversation

@100yenadmin

Copy link
Copy Markdown
Member

Closes part of #1436 (W5c Unit 1; Unit 2 = harness follows). Refs #1322.

What

The player consumed /combat-surface live (#1435) but only repositioned actors baked into the static scene — a token with no matching Actor_<id> GameObject rendered nothing, so only the campaign the scene was baked from showed a board. CombatSurfaceClient now spawns the missing actor at runtime, mirroring paint_combat_v1.cs's registry-resolved spawn, so any campaign renders.

Spawn path (mirrors the editor donor, runtime-safe)

Slot lookup + default fallback per the registry invariant (goblin/hero kind-defaults + #1423 albedo nuance, resolved inline — not AssetRegistry.Resolve, whose floor diverges to hero for unknown monsters) → load model from the bundle → #1397 SkinnedMeshRenderer pitch guard → #1418 bind-pose scale lock → idle pose (embedded idle clip, else #1408 humanoid donor retarget) → ground+center on the engine cell → #1423/#1425 albedo → AO blob + selection-ring siblings. Renderer stays a pure consumer (reads engine cells + registry only; engine is the sole writer). Deterministic reconcile each surface: present tokens spawned/repositioned, runtime-spawned actors no longer present are despawned (baked actors never despawned).

Packaging — the chosen mechanism (and why)

A player build cannot AssetDatabase.Load an Assets/ path at runtime. BuildMacOSPlayer.EnsurePackaged() (runs first in the build; also a standalone MenuItem):

  • StreamingAssets/worldos_actors — a StandaloneOSX AssetBundle of every registry-referenced model/albedo/idle clip, keyed by their exact registry path. The runtime loader passes registry.model_ref verbatim as the bundle key → zero path transform, so an asset swap stays a registry edit + repackage, zero renderer edits (the registry invariant). AssetBundle over Resources precisely because the bundle load key IS the Assets/... path already in the registry — Resources would force copying assets under Resources/ and mangling the path into a resources-relative key, breaking that invariance.
  • StreamingAssets/registry.json — the manifest copied verbatim (the same file paint_combat_v1.cs reads), so the runtime SLOT resolution reads exactly what the editor bakes from.

The editor capture path (paint_combat_v1.cs, AssetRegistry.cs) is untouched → byte-identical captures. The runtime client parses the registry map-of-maps with a self-contained nested parser (MiniJson lives in the editor-only assembly, unavailable to a runtime MonoBehaviour).

Validation (GEX44, Unity 6000.5.1f1) — evidence qa/evidence/1436/

  • Compile-clean (no CS errors from either script).
  • Editor-mode spawn test: three tokens with no baked Actor_* (Goblin→goblin exact, Aldric→alias fighter, Wren→alias innkeeper) spawned via SpawnActor loaded from the bundle in StreamingAssets — all grounded, bind-pose scaled, idle-posed, with cyan/red rings + AO on the painterly plate (spawn1436_editortest.png).
  • Bundle = 26 assets (worldos_actors.manifest); 3 non-existent @moveset/audio paths correctly skipped.
  • Player rebuilt: result=Succeeded totalErrors=0, Universal x64ARM64 (build-report.txt); StreamingAssets (bundle + registry) verified inside WorldOSPlayer.app/Contents/Resources/Data/StreamingAssets/.
  • Delivered: ~/worldos-session-notes/w5a-build/WorldOSPlayer.app.zip (overwritten) for local smoke against a live campaign with foes.

Unit 2 (harness) needs

Drive the PLAYER window (native macOS app: screenshot/click on the window, not the browser) for the T3 blind-playtest quest loop. Launch the delivered .app with WORLDOS_ENGINE_BASE_URL + WORLDOS_CAMPAIGN_ID env pointed at a live campaign with foes; assert runtime-spawned foes/party appear + /move round-trips. Then run the T3 gate per #1322.

CombatSurfaceClient now SPAWNS actors at runtime for tokens with no baked
Actor_<id> GameObject (mirroring paint_combat_v1's registry-resolved spawn:
slot lookup + default fallback, bind-pose scale lock #1418, SkinnedMeshRenderer
pitch guard #1397, albedo #1423, humanoid idle retarget #1408, AO/ring siblings),
so ANY campaign renders — not just the baked scene's cast. Despawns runtime-
spawned actors on token removal; baked actors untouched. Pure consumer (reads
engine cells + registry only; engine stays sole writer).

Packaging (player can't AssetDatabase.Load Assets/ paths at runtime):
BuildMacOSPlayer.EnsurePackaged() bakes registry-referenced models/albedos/idle
clips into a StandaloneOSX AssetBundle at StreamingAssets/worldos_actors keyed by
their EXACT registry path (runtime passes model_ref verbatim -> zero transform,
registry invariant intact) + copies registry.json verbatim to StreamingAssets.
AssetBundle over Resources precisely because its load key is the registry path.
Editor capture path (paint_combat_v1.cs / AssetRegistry.cs) untouched.

Validated on GEX44 (Unity 6000.5.1f1): compile-clean, editor-mode spawn of 3
non-baked tokens (goblin/fighter-alias/innkeeper-alias) grounded+ringed on plate,
bundle=26 assets, player rebuilt (Succeeded, Universal x64ARM64), StreamingAssets
verified inside the .app. Evidence qa/evidence/1436/.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 26 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5f4f9fe9-c5de-4797-b5e3-343c928963ea

📥 Commits

Reviewing files that changed from the base of the PR and between 90981f2 and 61b41b5.

⛔ Files ignored due to path filters (1)
  • qa/evidence/1436/spawn1436_editortest.png is excluded by !**/*.png
📒 Files selected for processing (5)
  • extensions/renderers/unity/scripts/BuildMacOSPlayer.cs
  • extensions/renderers/unity/scripts/CombatSurfaceClient.cs
  • qa/evidence/1436/README.md
  • qa/evidence/1436/build-report.txt
  • qa/evidence/1436/worldos_actors.manifest
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/1436-runtime-spawning

Comment @coderabbitai help to get the list of available commands.

@evaos-code-review-bot

evaos-code-review-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown

evaOS review status: closed or merged before review

PR: #1438 - #1436 W5c U1: player runtime actor spawning + StreamingAssets packaging
Head: 61b41b558990d2da48613cbda9b05bd58fa4ce73
Updated: 2026-07-08T17:29:36.174Z

evaOS review stopped because the PR closed or merged before this queued head could be reviewed.

Automation note: agents should wait for this comment to reach completed, stale_head, closed_or_merged_before_review, skipped, or failed before treating evaOS review as settled for this head. provider_deferred means evaOS still intends to retry.

PR URL: #1438

Details: state=closed

@100yenadmin 100yenadmin merged commit a2d1906 into main Jul 8, 2026
25 of 32 checks passed
@100yenadmin 100yenadmin deleted the feat/1436-runtime-spawning branch July 8, 2026 17:30
100yenadmin added a commit that referenced this pull request Jul 8, 2026
…lision-validated clicks (#1446)

* #1441 W5d: grounded reposition + engine-path glide + walk clips + click pre-validation

- PlaceActor -> UpdateActor: reposition now re-grounds feet->FloorY via the SAME BakeMesh
  Measure as SpawnActor (float fix; old path preserved raw Y). First-sight snap, changed-cell
  glide, same-cell no-op (poll never interrupts an in-flight glide).
- GlideTo: cell->cell tween at GlideSpeed following the engine-confirmed lastPath polyline
  (straight-line fallback when absent); rings/AO follow every frame; walk clip during glide
  (own walk/run -> humanoid donor-walk retarget -> glide-only fallback), idle at rest.
- Click pre-validation: reject clicks on impassable/occupied cells with a red ring flash
  (UX pre-filter only; engine stays authoritative — it already rejects illegal cells).
- Reconcile actor heights to named consts (ActorHeightFoe 4.2 / ActorHeightChar 3.2, the
  paint_combat_v1 #1418-calibrated source); flag replay_v1's stale 5.0.
- Parse impassable+lastPath via the runtime Json parser (poll + move-response paths).

Refs #1441 #1436 #1322 (PRs #1438/#1440).

* #1441 W5d: QA evidence — compile-clean, editor sanity capture, build+scp notes

Box validation: 0-error compile (component compiled + attached), editor sanity screenshot
(grounded actors + rings, painterly camp scene), Universal build Succeeded (0 errors), zip
scp'd to ~/worldos-session-notes/w5a-build/WorldOSPlayer.app.zip (overwrite).

---------

Co-authored-by: Eva <arncalso@gmail.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