Skip to content

feat(scene): built-in component codecs and UUID reference hooks #717

Description

@JeanPhilippeKernel

Summary

Register production YAML/binary codecs and UUID-reference hooks for every
currently authored built-in ECS component. The existing reflection registrations
are not serializer registrations, and static initialization is not an accepted
production lifecycle.

Scope

  • Add explicit built-in scene-schema registration after feat(scene): stable component schema registry #714 has been initialized
    during engine startup.
  • Implement codecs for the current document components: TransformComponent,
    ParentComponent, MeshComponent, CameraComponent, LightComponent,
    MaterialComponent, NameComponent, and RigidBodyComponent.
  • Materialize the mandatory UUIDComponent from the owning entity record UUID;
    it is not a second component-map payload with an independently editable UUID.
  • Classify authored, runtime-derived, editor-only, and forbidden fields. Runtime
    fields such as RenderInstanceId and GPU handles are excluded.
  • Validate finite transforms, legal component values, UUID syntax, asset UUID
    references, and component-specific constraints.
  • Implement stable field keys and UUID reference enumerate/patch hooks consumed
    by staged load, duplication, undo/redo, and Play restoration.
  • Treat UUID component data as durable identity, enforce uniqueness through the
    scene-document path, and keep EntityID only in loader/runtime maps.

Non-goals

  • Do not use static C++ registration, std::function, reflection offsets, or
    raw-byte serialization.
  • Do not introduce a separate parent/hierarchy format outside the scene document
    and staged resolver.

Dependencies

Acceptance criteria

  • All built-in authored values round-trip through stable YAML and binary codecs.
  • Every loaded entity gets one UUIDComponent whose value exactly equals its
    SceneEntityRecord::UUID.
  • Runtime-derived/render handles are absent after serialization and rebuilt by
    feat(scene): transactional scene load and runtime reconstruction #829.
  • Invalid component payloads produce structured errors rather than being dropped.
  • Tests cover codec values, field keys, reference enumeration, and rejection
    cases for each built-in component.

References

ZEngine/docs/future-plan/scene-serialization.md sections 2, 4, 6, and 11.

Implementation API contract

This function is the sole built-in registration entry point and is called by
engine startup immediately after the registry is initialized. It registers the
following fixed durable schema keys: zengine.ecs.transform,
zengine.ecs.parent, zengine.ecs.mesh, zengine.ecs.camera,
zengine.ecs.light, zengine.ecs.material, zengine.ecs.name, and
zengine.ecs.rigid_body. These names are source compatibility commitments, not
C++ type names.

namespace ZEngine::ECS
{
    [[nodiscard]] Core::VFS::VFSResult<void>
        RegisterBuiltInSceneSchemas(SceneComponentSchemaRegistry* registry,
                                    SceneDiagnostics* diagnostics);
}

Each schema supplies the SceneComponentCodecFns and SceneReferenceFns
defined by #714. ParentComponent uses a parent_uuid source field and is
resolved only after every candidate entity has been created. Mesh/material UUIDs
are enumerated as asset references. Duplication, clipboard, undo/redo, and Play
snapshot remapping operate on SceneValue payloads through Remap; they do not
patch a live ECS scene.

The required authored-field matrix is:

Schema key Authored fields Excluded derived fields
zengine.ecs.transform position, rotation, scale previous_position, world_transform
zengine.ecs.parent parent_uuid runtime EntityID
zengine.ecs.mesh mesh_uuid render_instance_id
zengine.ecs.camera fov_y, near, far, aspect_ratio, is_main padding
zengine.ecs.light type, intensity, range, spot_angle, color padding
zengine.ecs.material material_uuid —
zengine.ecs.name value —
zengine.ecs.rigid_body motion_type, mass, friction, restitution body_id, padding

The loader—not a schema callback—adds UUIDComponent{SceneEntityRecord::UUID}
and rejects a conflicting component-map UUID entry. This prevents two durable
identity sources from drifting apart.

Activity

  1. changed the title [-]feat(scene): register YAML + binary serialize fns for all 8 built-in components[/-] [+]feat(scene): built-in component codecs and UUID reference hooks[/+] on Sep 17, 2026
  2. added
    P1Critical path — blocks other work
    and removed
    P3Medium priority — planned
    on Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P1Critical path — blocks other workenhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions