Skip to content

fix(loader): unknown components no longer spawn ghost nested entities (#808) - #908

Merged
apotema merged 2 commits into
mainfrom
fix/808-unknown-component-ghost-entities
Sep 28, 2026
Merged

apotema merged 2 commits into
mainfrom
fix/808-unknown-component-ghost-entities

Conversation

@apotema

@apotema apotema commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #808.

Problem

loadEntityInternal (and the prefab-spawn / nested recursion) called spawnAndLinkNestedEntities for every component entry, including components that miss the registry and no-op in applyComponent (RFC #596 Axis 4). A typo such as "industry__Romm": { "workstations": [ {...} ] } spawned and tracked real scene entities and attached a ChildrenComponent to the parent. No component field existed to receive their ids, so they were unreachable ghosts. The only signal was the generic unknown-component warn-once.

Fix (design: nested spawning follows the component's fate)

  • ComponentApply.isKnownComponent(name) returns true for the engine built-ins applyComponent special-cases plus every name in the Components registry.
  • spawnAndLinkNestedEntities checks it first. For an unknown component it returns before creating any entity. That one choke point covers all three callers: scene entities, prefab spawn, and nested recursion.
  • The RFC RFC: unify scenes and prefabs #560 §B2 gate ({prefab + children}) still runs on the skipped items, so malformed input remains a hard InvalidFormat error. The existing unified_format_test case depends on this.
  • New warn-once unknown-component-nested:<name> fires when entity-like items were dropped. It applies to any key shape, so dropped authored entities are always reported.

Tests

test/jsonc/unknown_component_nested_test.zig (registered in build.zig):

  • Control: a registered component's entity array still spawns and links (2 scene entities, 1 ChildrenComponent, no nested warning).
  • Typo'd namespaced component in a components map: scene-entity count stays 1, no Desk, no ChildrenComponent. Both unknown-component: and unknown-component-nested: fired.
  • Flat unknown PascalCase component inside a prefab: same assertions.
  • An unknown component on a nested entity: its grandchildren don't spawn.
  • An unknown component without entity arrays: no nested diagnostic.
  • A §B2 violation under an unknown component: still error.InvalidFormat.

On the base commit, the 3 ghost-count tests fail on their entity-count assertion, which reproduces the bug. With the fix all pass. The other local zig build test failures on Windows (preview sockets, storage, and a few compile errors in unrelated tests) are the same set with and without this change.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Caqyi5Snr6yKssztYFztzZ


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

…#808)

`spawnAndLinkNestedEntities` ran for every component entry, including
ones that missed the registry and no-op'd in `applyComponent`. Entities
nested in an unknown component's arrays were spawned, tracked as scene
entities and linked via ChildrenComponent, with no field to patch their
ids into.

The nested-spawn walk now checks `ComponentApply.isKnownComponent`
(engine built-ins + registry) first and skips an unknown component's
value before creating anything. The RFC #560 B2 format gate still runs
on the skipped items, and a new warn-once
(`unknown-component-nested:<name>`) reports dropped entities for any key
shape.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Caqyi5Snr6yKssztYFztzZ
@coderabbitai

coderabbitai Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 47 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 101 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

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).

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 592330fb-0eb2-4bbe-baaa-99f0870422fd

📥 Commits

Reviewing files that changed from the base of the PR and between 28dd1d7 and fbe6464.

📒 Files selected for processing (5)
  • build.zig
  • src/jsonc/component_apply.zig
  • src/jsonc/scene_loader/nested_spawn.zig
  • src/jsonc/unified_format.zig
  • test/jsonc/unknown_component_nested_test.zig

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

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-28T23:36:36.617318Z fbe6464 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2c59680635

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/jsonc/component_apply.zig Outdated
/// entities have no component to patch their ids into and could
/// only ever be ghosts (#808).
pub fn isKnownComponent(name: []const u8) bool {
const builtins = [_][]const u8{ "Position", "Sprite", "Shape", "Tilemap", "Camera", "Image", "Emitter" };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Derive known components from the canonical built-in registry

Use scene.builtins.names here instead of introducing another hand-maintained built-in list. scene/src/builtins.zig is explicitly the single source of truth and is designed so adding a built-in updates every dispatch site; with this duplicate, a future built-in can be implemented in applyComponent yet omitted here, causing its entity-bearing arrays to be classified as unknown and dropped by spawnAndLinkNestedEntities even though the component itself is applied.

Useful? React with 👍 / 👎.

…view)

Codex P2: use the single built-in source of truth (#881) instead of a
hand-maintained list, so a future built-in can't be applied yet treated
as unknown by the nested-spawn gate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Caqyi5Snr6yKssztYFztzZ
@apotema

apotema commented Sep 28, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: fbe64641a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@apotema
apotema merged commit 1f238a7 into main Sep 28, 2026
4 checks passed
@apotema
apotema deleted the fix/808-unknown-component-ghost-entities branch September 28, 2026 23:41
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.

Unknown components with entity-bearing arrays spawn ghost entities

1 participant