Repository navigation
feat(codegen): SceneSerializer blocks for AssetHandle/UUID-field components (#451) - #467
Merged
Merged
Conversation
…ield components (#451) OloHeaderTool's scene-serializer codegen now recognizes AssetHandle/UUID (a u64 wrapper) as a trivial-ish field type, so a component whose only non-primitive fields are asset handles / entity-reference UUIDs is fully auto-generated instead of needing a hand-written serializer block — closing the most pervasive instance of the "forgot the handle block -> silent scene-data loss" footgun. First #451 slice; enums / vector / map / nested struct / Ref<T> remain follow-up slices. - SceneSerType maps AssetHandle/UUID to a new PropType::AssetHandle. Serialize emits static_cast<u64>; deserialize reads .as<u64>(static_cast<u64>(...)) and bridges back via the implicit UUID(u64) ctor — format-identical to every existing hand-written handle block. - UIWorldAnchorComponent (UUID m_TargetEntity + glm::vec3) is now fully generated; its hand-written serialize/deserialize blocks were removed from SceneSerializer.cpp. - DialogueComponent / IKTargetComponent / PerceptionComponent / IDComponent newly classify as trivial but are kept hand-written via kComponentsCustomSerialize: the first three have Sanitize/clamp deserialize logic; IDComponent is entity identity (its UUID is the top-level "Entity:" line, re-applied via CreateEntityWithUUID), which auto-gen would turn into a bogus sub-map + a double-AddComponent on load. Neither coverage test catches that case, so the exclusion is the only guard. Verified: OloEngine-Tests builds (MSVC Debug, exit 0); ComponentSerializerCoverage existence + disjointness pass; ComponentRoundTrip.UIWorldAnchorComponent exercises the generated UUID path; tuple/handler/save-game meta-tests and fuzz/prefab serializer tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
📝 WalkthroughWalkthrough
ChangesAssetHandle codegen and UIWorldAnchorComponent migration
Possibly related issues
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This was referenced Jul 1, 2026
Closed
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
First slice of #451 — OloHeaderTool's scene-serializer codegen now recognizes
AssetHandle/UUID(au64wrapper) as a trivial-ish field type, so a component whose only non-primitive fields are asset handles / entity-reference UUIDs is fully auto-generated instead of needing a hand-writtenSceneSerializer.cppblock. This closes the single most pervasive instance of the "forgot the handle block → silent scene-data loss" footgun (#451 lists AssetHandle/UUID as "pervasive: materials, meshes, colliders, dialogue, streaming, …").Follow-up to #380 / #450 (which generated blocks for all-primitive components).
How
PropType::AssetHandle;SceneSerTypemapsAssetHandle/UUID→ it.static_cast<u64>(comp.field); deserialize emitsfield = node["K"].as<u64>(static_cast<u64>(field)), bridging the implicitUUID(u64)ctor. Format-identical to every existing hand-written handle block (verified againstEncodeUUIDand the emitter's implicitoperator u64()) — no scene-file format change.Migration & exclusions
Of the 5 components that newly classify as trivial:
UIWorldAnchorComponent(UUID+glm::vec3) — clean round-trip; hand-written blocks deleted, now fully generated.DialogueComponent/IKTargetComponent/PerceptionComponent— kept hand-written (added tokComponentsCustomSerialize): they haveSanitize*/clamp deserialize logic the plain round-trip would drop.IDComponent— kept hand-written/excluded: it's entity identity, serialized as the top-levelEntity: <uuid>line. Auto-generating it would emit a bogus sub-map and callAddComponent<IDComponent>on an entity that already has one (EnTT double-add). Neither coverage test catches this (existence skipskRuntimeOnly, disjointness only catches hand-written double-emits) — manual exclusion is the only guard. Documented in the generator comment + CLAUDE.md.Out of scope (remaining #451 follow-up slices)
enums,
std::vector/ map / set, nested structs,Ref<T>,glm::quat/mat/ivec.Testing
OloEngine-Testsbuilds (MSVC Debug, exit 0) — the generated AssetHandle/UUID C++ compiles + links.ComponentSerializerCoverage.*(existence + inverse + disjointness) — 3/3 pass.ComponentRoundTrip.*— 69/69 pass;UIWorldAnchorComponentSurvivesYAMLRoundTripnow exercises the generated UUID path end-to-end (sets a distinctivem_TargetEntity, asserts it survives).Part of #451 (first slice; does not close the epic).
🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Documentation