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
AssetIdin 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!inregistry). Each gate inspects the world’s content and returns the constructed system when its gating components are present, orNoneto leave it out of the schedule.World::startandWorld::system_manifestboth run these same gates, so what the manifest reports and whatstartbuilds cannot drift.
Structs§
- Access
- A system’s declared data access.
- Active
Render Backend - 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
PipelineContextare never borrowed together.Nonewhile 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.
- Audio
Clip Handle - Index into the runtime audio-clip table.
- Blob
Asset Def - One component record in the blob’s def stream.
- Blob
Mesh Bounds - 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.
- Blob
Scene Groups - The blob’s baked per-scene exclusive content groups, published at blob load for the streaming/residency wiring to consume at graphics init.
- Built
System - 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.
- Column
Ticks - The tick stamps a column keeps.
changedis the maximum over every kind of write and drives whole-column change detection.addedmarks the last appended row.bulkmarks the last whole-column mutable access, after which every row must be assumed written.structuralmarks the last row add or removal, after which row positions and membership have moved. A consumer that tracks rows individually readsbulkandstructuralto decide whether the per-row stamps alone still describe what changed. - Component
Id - A component’s dense id, its bit position in a
ComponentMask. - Component
Mask - A set of component ids, one bit each.
- Component
Storage - 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$slottrait; callers never name them directly. - Cursor
State - 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_cursorsprites 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_windowis false in fullscreen, where the backend confines the cursor, and on backends without window-bounds tracking). - Desired
Cursor - The silhouette the in-engine cursor sprite should draw this frame.
- Dropdown
View - 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.
- Event
Cursor - A reader’s position in an
Eventsqueue. - Event
Store - Type-keyed event queues, one per event type in use.
- Events
- A double-buffered event queue: events stay readable for two frames.
- Execution
Trace - What the behavior system observed over one simulated tick, published while a
TraceRequest stands.
frameincrements per published tick so the observer can tell fresh data from the stale resource a paused world leaves behind.eventsare the nodes that ran (deduplicated);varsthe world variables with their current values in slot order;localsthe requested entity’s per-behavior locals;hitthe first executed breakpoint, if any. - FlyCam
- The editor’s fly-camera state. While true (published only by the
cn editorHUD 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. - Font
Handle - Index into the runtime font table.
- Frame
Context - Frame-scoped facilities a system may use for the duration of its
step. - Frame
Rate Cap - 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).
- GpuMemory
Pressure - 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.
- Hidden
Assets - 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 editorHUD drive; absent / empty otherwise. - HudLayers
- Per-frame draw-layer overrides for HUD Sprites / TextLabels / TextInputs, keyed
by asset id and published by the
cn editorHUD 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
StatHudSystemthe 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. - Material
Handle - Index into the runtime material table.
- Menu
Active - 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.
truewhile 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. - Menu
Override - An external per-frame driver (the
cn editorHUD) 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. - Mesh
Bounds Record - 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.
- Mesh
Handle - Index into the runtime mesh table.
- Open
Dropdown - A settings dropdown’s open floating option list, or
Nonewhen none is open.UiInputSystemowns the interaction state (open on asetting:<key>:openclick, 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). - Overlay
Image - 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).
- Overlay
Images - Extra images appended to the sprite/text atlas pool at graphics init: a
sprite whose
texturenames one of these handles samples the image like any compiled texture. Opt-in like PickIndex: inserted before start (thecn editorHUD 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. - Payload
Locator - Points to an asset’s compiled binary payload within the data blob files.
- Pending
Backend - 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 editorlive SAVE swap between building the post-edit world and starting it; GraphicsSystemrun_inittakes it and callsRenderBackend::reload_world(reusing the window) instead ofinit_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. - Pick
Entry - One pickable entity in the PickIndex: its asset id and current world-space
AABB. Ray-tested by the editor with
gfx::pick::ray_aabb. - Pick
Index - 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 editorHUD 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. - Pipeline
Context - 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.
- Scene
Group - 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.
- Scratch
Stats - What one frame’s scratch reserve cost and whether it held. A non-zero
overflowsmeans some frame fell back to the heap, sopeakunderstates what the frame actually wanted. - Screen
Stack - 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).
layersmaps 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_worldis true while any active screen pauses the world;captures_inputis 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.
ticksis how many fixed steps the simulation systems (physics, behavior) run this frame;tick_dtis the seconds each step advances;alphais the accumulator remainder as a fraction oftick_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 bareWorld::steploops deterministic. - Skinned
Mesh Handle - Index into the runtime skinned-mesh table.
- System
Entry - One row of the system table. Table order is run order.
- System
Table - A host’s system table and the load-time passes only the host can supply.
- Texture
Handle - Index into the runtime texture table.
- Tick
- A change-detection stamp. Wraps; comparisons use a signed window bounded
by
MAX_CHANGE_AGE. - Trace
Event - One node execution: which behavior, and the node’s compile-assigned pre-order id (an index into that behavior’s TracePaths entry).
- Trace
Paths - 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).
- Trace
Request - An external observer’s request for execution tracing, published per frame by
the
cn editorHUD 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.entityselects whose per-entity locals to surface;breakpointsare nodes whose execution should be reported as a ExecutionTrace::hit so the observer can pause the simulation. - Transient
Saves - 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
savenode still works within the session. Published by thecn editorHUD injection (sampled at each system’s init); a shipped runtime never publishes it. - View
Overrides - 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.
- World
Lines - 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§
- Component
Asset - A loaded component of any registered type.
- Cursor
Shape - The silhouette the in-engine cursor sprite should draw this frame. Published
by the
cn editorHUD 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.Defaultis 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. - Frame
Vec - 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. - Schedule
Mode - How a tick’s independent work executes.
Parallellets 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. - Step
Result - What a system asks the world to do after its step.
- Trace
Step - 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. - Trace
Val - A behavior-body value in its cross-boundary form: what
Valpublishes 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::startruns 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. - Component
Slot - 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
$slotimpl, andDISCRIMINANTis its stable id, used as itsComponentIdin the join index.'static: components own their data, and the generic ops hand out borrows of (and owned vectors of) the type. - Runtime
Component - 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::startconstructs it from world components (via the system’s ownnew(..)), so a system is never loaded from or written to a blob.initruns once atWorld::start;stepruns every tick.
Functions§
- gpu_
profile - The detected GPU’s capability + memory profile, published by graphics init.
Nonebefore init runs, andGpuProfile::UNKNOWNwhen the backend could not classify the device. - memory_
budget - The world’s memory budget, once
starthas published one. - memory_
drift - Long-session memory drift, folded from the same throttled sample as the
back-off valve.
Noneuntil the session settles enough for a baseline, and for the same reasonsstreaming_pressureis absent. - renders
- Whether the world needs a renderer. True when it declares a
GraphicsConfig(pre-start) or has a constructedGraphicsSystem(post-start, after the config component has been drained), so callers can decide on the render loop regardless of timing. - state_
tree - The state tree
App::startpublished: where this world reads and writes.Nonefor a world running against no tree, which is a world that touches no disk. What every system reads instead of resolving a path of its own. - streaming_
pressure - Live process-RAM back-off pressure on streaming, published by
StreamingSystem on its throttled RSS sample.
Nonebefore the first sample or when noMemoryBudget/ RSS is available (the valve is inert). - streaming_
stats - Per-pool
(resident, pending, unloaded)streaming counts from the parkedStreamingState(StreamingSystem drives it against the backend each frame).Nonebefore graphics init parks it, and from inside a system step, which takes the state out. Read by thecn debugserver’sstreamingcommand 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 debughot-reload drive: it applies backend edits through a system’s init-captured bookkeeping, so it needs both at once. The backend isNonewhile 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 editorlive SAVE swap transplants it into the rebuilt world (via aPendingBackendresource) so the edit applies without recreating the OS window / re-initialising the GPU device.Nonewhen the world never built a backend (or it was already yielded). - thread_
budget - The process thread budget App published at start.
NonebeforeApp::startinstalls it. Read by thecn debugserver’sbudgetcommand.
Type Aliases§
- Trace
Path - A behavior node’s address: the hops from the behavior’s args down to it.