ScriptRegistry class

Singleton registry for runtime-defined component schemas and their blob storage.

Intended for early-project iteration: define components in the editor without recompiling. Storage is AoS (no SIMD sweep, no rollback). When a schema is stable, use ComponentGeneratorPanel to export a compile-time .h and migrate.

Thread safety: schema mutations (Register*, AddField) must occur outside the Logic thread hot path — during handshake or while PIE is stopped. Field reads/writes (Get*‍/Set*) are expected from the Logic thread only.

Public static functions

static auto Get() -> ScriptRegistry&

Public functions

void Initialize(uint32_t maxCachedEntities)
void Shutdown()
Release all blob storage. Called on World shutdown.
auto RegisterComponent(const char* name, SystemID sysID, CacheTier tier) -> ComponentTypeID
auto AddField(ComponentTypeID id, const char* fieldName, ScriptFieldType type) -> bool
auto RegisterOrUpdate(const char* name, SystemID sysID, CacheTier tier, const ScriptFieldType* fieldTypes, const char*const* fieldNames, uint8_t fieldCount, bool* bBreakingChange = nullptr) -> ComponentTypeID
auto GetSchema(ComponentTypeID id) const -> const ScriptSchema*
auto GetSchema(const char* name) const -> const ScriptSchema*
auto GetStorage(ComponentTypeID id) const -> const ScriptComponentStorage*
void ForEachSchema(const std::function<void(const ScriptSchema&, const ScriptComponentStorage&)>& fn) const
auto GetComponentCount() const -> uint8_t
void Attach(uint32_t cacheEntityIndex, ComponentTypeID id)
void Detach(uint32_t cacheEntityIndex, ComponentTypeID id)
auto HasComponent(uint32_t cacheEntityIndex, ComponentTypeID id) const -> bool
void OnEntityMoved(uint32_t oldIndex, uint32_t newIndex)
Called by DefragSystem when an entity moves from oldIndex to newIndex.
auto GetFloat(uint32_t cacheIdx, ComponentTypeID id, uint16_t offset) const -> float
void SetFloat(uint32_t cacheIdx, ComponentTypeID id, uint16_t offset, float val)
auto GetInt32(uint32_t cacheIdx, ComponentTypeID id, uint16_t offset) const -> int32_t
void SetInt32(uint32_t cacheIdx, ComponentTypeID id, uint16_t offset, int32_t val)
auto GetUInt32(uint32_t cacheIdx, ComponentTypeID id, uint16_t offset) const -> uint32_t
void SetUInt32(uint32_t cacheIdx, ComponentTypeID id, uint16_t offset, uint32_t val)
auto GetBool(uint32_t cacheIdx, ComponentTypeID id, uint16_t offset) const -> bool
void SetBool(uint32_t cacheIdx, ComponentTypeID id, uint16_t offset, bool val)
auto FindField(ComponentTypeID id, const char* fieldName) const -> const ScriptFieldDesc*
Named field lookup — linear search, editor use only.

Function documentation

void ScriptRegistry::Initialize(uint32_t maxCachedEntities)

Parameters
maxCachedEntities MAX_CACHED_ENTITIES from EngineConfig (post-ApplyDefaults).

Called once at World init. Allocates blob storage for all already-registered schemas.

ComponentTypeID ScriptRegistry::RegisterComponent(const char* name, SystemID sysID, CacheTier tier)

Register a new script component. Safe to call before Initialize. Returns the assigned ComponentTypeID, or 0 on failure.

bool ScriptRegistry::AddField(ComponentTypeID id, const char* fieldName, ScriptFieldType type)

Add a field to an existing schema. Zero-initialises the field in all live blobs. Returns false if the TypeID is unknown, the field limit is reached, or the name collides.

ComponentTypeID ScriptRegistry::RegisterOrUpdate(const char* name, SystemID sysID, CacheTier tier, const ScriptFieldType* fieldTypes, const char*const* fieldNames, uint8_t fieldCount, bool* bBreakingChange = nullptr)

Register from a complete field list. Adds only new trailing fields (additive). Sets *bBreakingChange = true if existing fields were removed or reordered. Returns the TypeID (existing or new), or 0 on hard failure.