Skip to main content

Module ecs

Module ecs 

Source
Expand description

Client-side ecs runtime. The renderer-free metadata, asset registry, registration macros, asset-construction API, PipelineContext, the System behavior trait, and the World that runs systems over its data all live in concinnity-core; this module re-exports them under the historical crate::ecs::* paths and adds what only a renderer-bearing runtime has: the system table itself, its gates, the load-time decomposition pass, and the resources the render band parks in a world.

TO ADD A NEW COMPONENT: register it in concinnity-core’s ecs::registry (define_components!). TO ADD A NEW SYSTEM: implement the System behavior trait on it, write its gate in this crate’s ecs::schedule, and add one entry to the define_systems! table in ecs::registry – the table is the registry AND the schedule (table order is run order).

A system concinnity-core owns is listed in ITS table too (ecs::HEADLESS_SYSTEMS, what a world with no host runs), and the two must agree on order, gate description, and the edges among the systems both know about. headless_drift_tests is what holds them to that.

Modules§

asset_id
Build-time name -> dense id interner. Asset names declared in world.jsonl are interned to an AssetId in declaration order; the blob and the runtime carry only the integer, so every cross-reference lookup is an integer compare.
schedule
Gate builders for the system table (define_systems! in registry). Each gate inspects the world’s content and returns the constructed system when its gating components are present, or None to leave it out of the schedule. World::start and World::system_manifest both run these same gates, so what the manifest reports and what start builds cannot drift.

Structs§

Access
A system’s declared data access.
ActiveRenderBackend
The world’s live render backend, parked here between system steps. GraphicsSystem’s init builds it and parks it; each system that drives the GPU (GraphicsSystem’s frame encode, InputSystem’s poll) takes it out at the top of its step and puts it back before returning, so the backend and the PipelineContext are never borrowed together. None while a step has it taken, or once the editor’s live SAVE transplanted it out.
Arena
A bump allocator over one fixed reservation, reset as a whole.
AudioClipHandle
Index into the runtime audio-clip table.
BlobAssetDef
One component record in the blob’s def stream.
BlobMeshBounds
The blob’s baked per-mesh geometry summaries (AABB + counts by mesh-source handle), published at blob load so graphics init can build draw records for deferred scene-owned meshes without decoding their payloads.
BlobSceneGroups
The blob’s baked per-scene exclusive content groups, published at blob load for the streaming/residency wiring to consume at graphics init.
BuiltSystem
A constructed system and the table entry name it was built from.
Clock
A monotonic microsecond source, installed as a world resource by the host.
ColumnTicks
The tick stamps a column keeps. changed is the maximum over every kind of write and drives whole-column change detection. added marks the last appended row. bulk marks the last whole-column mutable access, after which every row must be assumed written. structural marks the last row add or removal, after which row positions and membership have moved. A consumer that tracks rows individually reads bulk and structural to decide whether the per-row stamps alone still describe what changed.
ComponentId
A component’s dense id, its bit position in a ComponentMask.
ComponentMask
A set of component ids, one bit each.
ComponentStorage
One Column<T> per registered component type, the entity allocator that stamps each row’s id, the change tick stamped on every structural edit, and the join index that maps an entity to its row in each column. Field columns are the caller’s field idents, reached through the $slot trait; callers never name them directly.
CursorState
The latest sampled cursor state (window pixels, top-left origin), published by InputSystem after each poll. GraphicsSystem reads it when building the next frame’s draw list: follow_cursor sprites are positioned a frame after the input that moved them, and the in-engine cursor stops drawing once the real cursor has left the window (outside_window is false in fullscreen, where the backend confines the cursor, and on backends without window-bounds tracking).
DesiredCursor
The silhouette the in-engine cursor sprite should draw this frame.
DropdownView
What GraphicsSystem needs to draw an open dropdown list: the anchor control rect (reference space), the option labels top-to-bottom, the selected + hovered OPTION indices to highlight, the scroll position (first, the top shown option of a list longer than the layout window), and the row value label’s font / scale / color so the list text matches the row it drops from.
Entity
A live entity handle: a slot index plus the generation that slot carried when the handle was minted.
EventCursor
A reader’s position in an Events queue.
EventStore
Type-keyed event queues, one per event type in use.
Events
A double-buffered event queue: events stay readable for two frames.
ExecutionTrace
What the behavior system observed over one simulated tick, published while a TraceRequest stands. frame increments per published tick so the observer can tell fresh data from the stale resource a paused world leaves behind. events are the nodes that ran (deduplicated); vars the world variables with their current values in slot order; locals the requested entity’s per-behavior locals; hit the first executed breakpoint, if any.
FlyCam
The editor’s fly-camera state. While true (published only by the cn editor HUD drive), InputSystem keeps the navigation keys and mouse deltas live and GraphicsSystem captures the cursor even though the world is frozen behind the editor’s menu override – the editor integrates Camera3D itself, so the viewport can be flown without running the simulation. Absent / false in a shipped runtime.
FontHandle
Index into the runtime font table.
FrameContext
Frame-scoped facilities a system may use for the duration of its step.
FrameRateCap
The live frame-rate cap in FPS (0 = unlimited), published by GraphicsSystem (from GraphicsConfig at init, refreshed by the settings row’s live change) and read by the App-level frame pacer before each world step. Independent of the quality preset (a user/hardware preference, like vsync).
GpuMemoryPressure
Device-memory pressure signal, published by GraphicsSystem whenever GPU work fails for lack of device memory. Renderer-free counters so the streaming valve can react (tighten budgets, evict) without naming the renderer; nothing consumes it yet.
HiddenAssets
Assets suppressed from rendering for this frame. GraphicsSystem collapses each listed asset’s draw slots to a degenerate transform (so it neither rasterizes nor casts shadows) and drops it from the PickIndex. Authored data is untouched, and the collapse is re-derived every frame, so clearing an id restores the object immediately. Published by the cn editor HUD drive; absent / empty otherwise.
HudLayers
Per-frame draw-layer overrides for HUD Sprites / TextLabels / TextInputs, keyed by asset id and published by the cn editor HUD so its floating panels occlude cleanly. Overlay draw calls render in two passes (all sprites, then all text), so two overlapping panels’ contents merge – one panel’s text draws over the other’s background. GraphicsSystem stable-sorts the overlay calls by this layer (higher draws on top) when the map is non-empty, so the focused panel’s whole content sits above the others’. An id absent from the map is layer 0; an empty / absent resource (the shipped runtime) leaves draw order at insertion order, unchanged.
HudPrefs
Per-frame stats-HUD visibility, published as a resource by GraphicsSystem (which runs first) and read by StatHudSystem the same tick. Each field is the effective on/off for that chip: the master “Display performance stats” toggle AND the per-readout toggle from the video settings. Absent (a HUD-only unit test with no GraphicsSystem) is treated as both shown.
MaterialHandle
Index into the runtime material table.
MenuActive
Per-frame menu state, published as a resource by the overlay build (which runs first in the schedule) and read by the simulation systems the same tick. true while any world-pausing screen is open: physics and animation then freeze so they stop consuming resources behind the menu. Each system keeps its own clock aligned across the freeze, so resuming costs one normal frame – no catch-up burst, no pose jump.
MenuOverride
An external per-frame driver (the cn editor HUD) can force the world’s “menu active” state through this resource: Some(true) frees the cursor and freezes gameplay/physics/animation (edit mode), Some(false) captures the cursor and lets the world run (play mode), both regardless of whether the world has its own menu UI. GraphicsSystem also puts the backend in menu mode while it is set, so a click frees to a UI action instead of re-capturing the camera. None (the default absence) leaves the world’s own menu logic in charge; a shipped runtime never publishes it.
MeshBoundsRecord
Baked geometry summary of one static mesh payload, keyed by its unified mesh-source handle. Lets the runtime build draw records (AABB) and size geometry reservations (counts) without decoding the payload; a payload with no record decodes eagerly.
MeshHandle
Index into the runtime mesh table.
OpenDropdown
A settings dropdown’s open floating option list, or None when none is open. UiInputSystem owns the interaction state (open on a setting:<key>:open click, close on a pick / outside click / Escape / scroll) and publishes this each frame; GraphicsSystem reads it the next tick to draw the list on top of the menu. GraphicsSystem runs first, so the list appears one frame after the row is clicked (the same lag the cursor + cycle labels already carry).
OverlayImage
One extra RGBA8 image for the sprite/text atlas pool, bound to a reserved TextureHandle the inserting tool chose. The handle space must stay clear of the compiled world’s dense texture handles (tools use a high base).
OverlayImages
Extra images appended to the sprite/text atlas pool at graphics init: a sprite whose texture names one of these handles samples the image like any compiled texture. Opt-in like PickIndex: inserted before start (the cn editor HUD injection adds baked asset thumbnails); absent everywhere else, so a shipped runtime never pays for it. Read once at init – images added to the resource later join the pool on the next world rebuild.
PayloadLocator
Points to an asset’s compiled binary payload within the data blob files.
PendingBackend
A render backend transplanted out of a previous world, carried into a freshly built world so its GraphicsSystem reuses the live GPU device + window instead of constructing a new one. Published by the cn editor live SAVE swap between building the post-edit world and starting it; GraphicsSystem run_init takes it and calls RenderBackend::reload_world (reusing the window) instead of init_backend, so a save applies without recreating the OS window. A shipped runtime never publishes it; it exists only on the editor’s live-update path.
PickEntry
One pickable entity in the PickIndex: its asset id and current world-space AABB. Ray-tested by the editor with gfx::pick::ray_aabb.
PickIndex
The per-frame viewport-picking index: every renderable prop entity’s asset id and world-space AABB, refreshed by GraphicsSystem from the live transforms. Opt-in: GraphicsSystem only builds it when the resource is already present at init (the cn editor HUD injection inserts an empty one), so a shipped runtime never pays for it. Rooms, instanced clusters, and voxel chunks are not indexed; picking targets authored prop placements.
PipelineContext
A system’s view of the world for the duration of one step: the five things it borrows, and the accessors that reach them.
Resources
Type-keyed singleton storage: one value per resource type.
SceneGroup
One scene’s exclusively-owned blob content: the resource-stream entries and payload-carrying component defs reachable only from that scene’s members. Content shared between scenes (or used outside any scene) belongs to no group and loads with the world. Groups are listed in scene declaration order; their payloads are packed into dedicated blobs after the global set.
ScratchStats
What one frame’s scratch reserve cost and whether it held. A non-zero overflows means some frame fell back to the heap, so peak understates what the frame actually wanted.
ScreenStack
The active screen stack, published by UiInputSystem at init and whenever the stack changes, and read a frame later (the same one-frame lag screen visibility flips already have). layers maps each active Screen’s id to its computed draw layer (authored layer band + stack position; screen-less HUD elements sit at 0); the overlay build spreads these onto the elements each screen owns. pauses_world is true while any active screen pauses the world; captures_input is true while any active screen captures input (gameplay keys are suppressed even when the world keeps simulating). Absent / empty in a world with no active screen.
SimTiming
Fixed-timestep budget for the current frame, published by the App-level simulation clock before each world step. ticks is how many fixed steps the simulation systems (physics, behavior) run this frame; tick_dt is the seconds each step advances; alpha is the accumulator remainder as a fraction of tick_dt, used to blend the previous and current simulated states when writing render-facing transforms. Absent (a directly-stepped world with no App), the default is exactly one tick per step with no blending, which makes bare World::step loops deterministic.
SkinnedMeshHandle
Index into the runtime skinned-mesh table.
SystemEntry
One row of the system table. Table order is run order.
SystemTable
A host’s system table and the load-time passes only the host can supply.
TextureHandle
Index into the runtime texture table.
Tick
A change-detection stamp. Wraps; comparisons use a signed window bounded by MAX_CHANGE_AGE.
TraceEvent
One node execution: which behavior, and the node’s compile-assigned pre-order id (an index into that behavior’s TracePaths entry).
TracePaths
Each behavior’s node paths, indexed by the node ids ExecutionTrace events carry. Published once when tracing is first requested (the compile that derives it runs at init either way; the publish just exposes it).
TraceRequest
An external observer’s request for execution tracing, published per frame by the cn editor HUD while its Behavior panel is open and removed when it closes. While present, the behavior system records which nodes ran each simulated tick and publishes ExecutionTrace; absent (the shipped runtime, or the panel closed), the system does no recording work beyond noticing the absence. entity selects whose per-entity locals to surface; breakpoints are nodes whose execution should be reported as a ExecutionTrace::hit so the observer can pause the simulation.
TransientSaves
Keeps a preview session out of the user’s real save files: while present and true, the systems that persist play state (behavior variables / once flags, story position) neither read nor write their disk saves – every session starts fresh and leaves no trace. In-memory state is unaffected, so a save node still works within the session. Published by the cn editor HUD injection (sampled at each system’s init); a shipped runtime never publishes it.
ViewOverrides
The viewport’s view mode + show flags, published per frame by the editor. GraphicsSystem forwards it to the backend’s FrameParams: the mode selects what the composite presents, the flags skip feature passes for the frame. Absent outside the editor, which reads as the lit default.
World
A world: its component storage, its resources, the compiled payloads it loads from, and the systems that run over all three.
WorldLines
World-space lines to draw this frame (trajectories, tethers, path previews, the editor’s origin axes), republished by their producer every frame: GraphicsSystem expands whatever it finds into ribbon geometry and hands it to the backend, so a stale list would keep drawing. Absent when nothing draws lines, which keeps the line pass out of the frame graph.

Enums§

ComponentAsset
A loaded component of any registered type.
CursorShape
The silhouette the in-engine cursor sprite should draw this frame. Published by the cn editor HUD when the pointer is over a resizable panel’s edge or corner (or while a resize drag is in flight) and read by the overlay build, which draws the matching shape at the pointer in place of the arrow. Default is the plain arrow; the four resize shapes are double-headed arrows along a window edge (east/west), edge (north/south), and the two diagonals. A shipped runtime never publishes it, so the arrow always stands.
FrameVec
A frame temporary: in the scratch arena when it fit, on the heap when it did not. Reads as &[T] either way, so a caller never branches on which it got.
ScheduleMode
How a tick’s independent work executes. Parallel lets systems fan their safe internal work across the job pool; Serial (or the resource being absent, the editor’s case) keeps every system’s work on the stepping thread – the determinism oracle and the escape hatch (cn run --serial-schedule). Both modes must produce identical world state; the engine’s schedule-determinism test is the gate on that claim.
StepResult
What a system asks the world to do after its step.
TraceStep
One hop of a behavior-node address, mirroring the world checker’s fault paths: object fields by key, list members by position. A node’s path walks from the behavior’s args to the node (e.g. do[1].if.then[0] is [Field("do"), Index(1), Field("if"), Field("then"), Index(0)] minus the node’s own trailing verb), so the editor can resolve a traced node to the same outline row / chart card its checker faults land on. Field names are the fixed authoring keys, so they borrow statically.
TraceVal
A behavior-body value in its cross-boundary form: what Val publishes to an observer. Entities travel as their id bits.

Constants§

MAX_CHANGE_AGE
Half the u32 range. A tick older than this relative to the current tick is clamped forward so the signed-window comparison never aliases.
SYSTEMS
The system table: one entry per system, in run order, plus the load-time passes that bracket them. World::start runs each gate against the world’s content and builds the systems they return.

Traits§

Component
Component – pure serializable data, no behavior. The runtime-facing surface only: a component loads from its baked blob bytes and receives its injected identity/payload hooks. All authoring metadata (origin, payload kind, reference fields, args schema, validators) lives in the build-side registry (concinnity-cook), derived from the for_each_component! metadata blocks.
ComponentSlot
Resolves a component type to its column inside the storage at compile time, so the generic storage operations above need no runtime dispatch. A registered component is exactly a type with a $slot impl, and DISCRIMINANT is its stable id, used as its ComponentId in the join index. 'static: components own their data, and the generic ops hand out borrows of (and owned vectors of) the type.
RuntimeComponent
A component a world can hold after the cook: every type an authored world declares that survives into a blob, plus every type only the runtime mints.
System
System – has behavior, receives a PipelineContext each tick. Every system is internal engine code: World::start constructs it from world components (via the system’s own new(..)), so a system is never loaded from or written to a blob. init runs once at World::start; step runs every tick.

Functions§

gpu_profile
The detected GPU’s capability + memory profile, published by graphics init. None before init runs, and GpuProfile::UNKNOWN when the backend could not classify the device.
memory_budget
The world’s memory budget, once start has published one.
memory_drift
Long-session memory drift, folded from the same throttled sample as the back-off valve. None until the session settles enough for a baseline, and for the same reasons streaming_pressure is absent.
renders
Whether the world needs a renderer. True when it declares a GraphicsConfig (pre-start) or has a constructed GraphicsSystem (post-start, after the config component has been drained), so callers can decide on the render loop regardless of timing.
streaming_pressure
Live process-RAM back-off pressure on streaming, published by StreamingSystem on its throttled RSS sample. None before the first sample or when no MemoryBudget / RSS is available (the valve is inert).
streaming_stats
Per-pool (resident, pending, unloaded) streaming counts from the parked StreamingState (StreamingSystem drives it against the backend each frame). None before graphics init parks it, and from inside a system step, which takes the state out. Read by the cn debug server’s streaming command and the editor’s Health panel.
systems_and_render_backend
Disjoint mutable borrows of the system list and the parked render backend, for the cn debug hot-reload drive: it applies backend edits through a system’s init-captured bookkeeping, so it needs both at once. The backend is None while a step has it taken (never the case between ticks, where the drive runs) or when no backend was built.
take_render_backend
Take the live render backend out of the world’s parked slot, leaving the world backend-less. The cn editor live SAVE swap transplants it into the rebuilt world (via a PendingBackend resource) so the edit applies without recreating the OS window / re-initialising the GPU device. None when the world never built a backend (or it was already yielded).
thread_budget
The process thread budget App published at start. None before App::start installs it. Read by the cn debug server’s budget command.

Type Aliases§

TracePath
A behavior node’s address: the hops from the behavior’s args down to it.