Status & Roadmap
Timeline
Project start: ~2026-02-01
Last updated: 2026-09-29
Phase: Foundation Stage — animation and networking in progress; Edit Timeline and GG-UI designed
Stage 1: Foundation
| # | Milestone | Status | Notes |
|---|---|---|---|
| 1 | Editor (bare-bones) | ✅ Complete | 8 panels + Construct / Entity / Prefab editor windows, Construct/Entity/Component generators, node graphs, transform gizmo, PIE (local single-player world + networked 1–4 clients), scene snapshot/restore, asset database (.tnxid sidecars, .tnxdb), JSON .tnxscene, 50-command undo/redo, GPU picking. Panels dock or float in their own windows (GG-UI). Successor designs: Edit Timeline, GG-UI. |
| 2 | Construct/View OOP | ✅ Complete | Construct<T>, Owned<T>, ConstructView<TEntity>, ConstructBatch, JoltCharacter. PlayerConstruct proven. |
| 3 | Networking | In Progress | GNS wrapper, PIE loopback, entity replication, clock sync, input routing, delta compression. LogicThread<TNet,TRollback,TFrame>, ServerClientChannel, AuthoritySim/OwnerSim done. Two network modes (Deterministic/Non-Deterministic), ListenNet mode, host migration, disconnect policy, and mode-split rewrite designed and planned. |
| 4 | Audio | ✅ Complete | SDL3 AudioManager: voice pool, handle-based playback, event registry, per-voice fade, priority voice stealing. Anti-Event compatible. |
| 5 | Camera System | ✅ Complete | CameraManager (per-Soul layer stack), CameraSlot[5], CameraLayer + mixins, ECameraNode (cold), ECamera (hot SoA), CurveHandle. |
| 6 | Game Flow | In Progress | FlowManager, FlowState, GameMode, Soul, NetChannel done. WithSpawnManagement, WithLobby, WithTeamAssignment ModeMixins done. ClientRepState 7-state machine done. |
| 7 | Animation | In Progress | Rollback-safe, replicated animation state: CAnimBase (clip or GPU-evaluated blendspace, cross-fade, root-motion flag, state-machine node for rollback re-derivation) and CAnimLayer (2 overlay slots, bone masks, replace or additive) are Temporal components. AnimConstruct mixin: state machine, root motion, notifies, sockets, FK bone cache. GPU compute skinning with indirect dispatch. glTF skeleton/animation import. Replicated animated character proven on clients. Pending: IK, retargeting, animation graph tooling. |
Stage 2: Hardening
Once Editor + Networking + Audio are stable and a test arena level is running, the engine enters a dedicated cleanup and rewrite phase.
Hardening targets:
- Hot-path data structure audit for cache efficiency
- Archetype field allocation and meta storage cleanup
- ConstraintEntity system (constraint pool, rigid attachment pass, physics root determination)
- Static entity tier (requires asset importing)
- Reflection system robustness (static init ordering — currently fragile across TUs)
TNX_STRIP_NAMESbuild option for shipping builds (strip registration name strings)- Default identity quaternion for
CTransform(RotQW=1.0f) to prevent zero-quaternion rendering bugs
After hardening: Arena shooter test level to prove the full stack — high entity counts, physics, competitive input latency, rollback netcode, networked multiplayer.
Completed Work (Selected)
Architecture
- Three-thread architecture (Sentinel / Brain / Encoder) — fully operational
- Raw Vulkan stack (volk 1.4.304 + VMA 3.3.0,
vk::raii::) replacing SDL3 GPU backend
- GPU-driven compute pipeline (predicate → prefix_sum → scatter, Slang shaders, BDA)
- Dirty-bit-driven selective GPU upload — only modified entities uploaded per frame (2026-05)
- Lock-free job system (MPMC Vyukov ring buffers, futex-based wake, core-aware pinning)
- Tiered storage partition layout (Cold/Static/Volatile/Temporal, dual-ended arena)
- 5 GPU InstanceBuffers (cycling independently of 2 GPU frame-in-flight slots)
ECS
FieldProxy(Scalar / Wide / WideMask,FieldProxyMaskzero-size base)
TemporalComponentCacheSoA ring buffer
TemporalFlagBitstyped enum (Active, Dirty, DirtiedFrame, Replicated, Alive, Tombstone, …)
TNX_TEMPORAL_FIELDS/TNX_VOLATILE_FIELDSwith SystemGroup tag (auto-derives partition)
SchemaValidation.h(no vtable + all fields must be FieldProxy — compile-time)
Physics
- Jolt Physics v5.5.0 (
JoltJobSystemAdapter,CJoltBodyvolatile, slab-direct iteration)
JoltCharacter—CharacterVirtualwrapper for Construct-driven character controllers
- Rollback netcode —
SaveState/RestoreStatesnapshot ring buffer,ExecuteRollbackTest, byte-perfect determinism verified (2026-03-29)
Networking
LogicThread<TNet, TRollback, TFrame>three-axis policy template (2026-05)
AuthoritySim/OwnerSim/SoloSimnet policy types
ServerClientChannel— per-client:PlayerInputLog,Replicated[],PendingActivations,NetChannel,PendingPacketQueue
ClientRepState7-state machine (PendingHandshake→Synchronizing→Loading→LevelLoading→LevelLoaded→Loaded→Playing)
- Delta compression —
EntityDelta(component-level dirty patches),InputFrameDelta(delta-encoded input window)
- Entity destruction replication (
EntityDestroy/ConstructDestroywire types)
- Entity activation pipeline (
EntityActivate,StreamLoad/StreamReady/ChunkActivate)
PredictionLedger— client-side in-flight spawn prediction tracker
- Construct replication consistent with entities for late join and rejoin
- Finer-grained level streaming control (what loads where, when, and how it activates)
- First hook for non-lockstep networking when determinism is disabled
Animation
CAnimBase/CAnimLayerTemporal animation components (rollback + replication)
- Blendspace evaluation on the GPU, cross-fades, masked replace/additive overlay layers
AnimConstructstate machine mixin — root motion, notifies, sockets, FK bone cache
- GPU compute skinning (
SkinningPass, indirect dispatch)
- glTF skeleton and animation import
Rendering
- Per-mesh indirect draws —
build_draws+sort_instancespasses after scatter
Tooling
- Rollback determinism test harness with watchdog thread (CI-safe stall detection)
- Formatting, linting, and presubmit tooling (clang-format, clang-tidy, pre-commit hooks, presubmit build + Testbed)
Math
FixedUnit— unit-range fixed-point for trig output and direction components
Fixed32(int32, 0.1mm precision, all arithmetic ops,FixedSqrt)
SimFloatalias —SimFloatImpl<float>or<Fixed32>viaTNX_DETERMINISM
FixedTrig(FixedSin/FixedCosLUT)
- Jolt fixed-point bridge validated — engine runs deterministically
Game Flow
FlowManager— state stack, travel primitives, World/Level/Mode lifetime management
FlowStatebase class withStateRequirementsdeclaration hook
Soul(OwnerID identity,ClaimBody/ReleaseBody, RPC dispatch)
NetChanneltyped per-connection send wrapper
ModeMixinsystem —WithSpawnManagement,WithLobby,WithTeamAssignment
- Travel toolbox — three orthogonal levers (domain lifetime, Construct lifetime, network continuity)
GameModeManifest/ClientModeManifestCRTP typed payloads
Not Yet Implemented
Networking
- Host, join, and solo in one build — one game executable that plays alone, hosts, or joins, chosen at run time from the game's flow: a
Gamebuild model, aListenSimpolicy that gives one world a run-time role, a general net thread, emptying a world in place, andStartSession/EndSessionon the flow manager. Solo is a Host that is not listening, which also gives a lone game its Soul. Design agreed: Host, Join, and Solo in One Build. The first stage of the entry below; no host migration yet.
ListenNetcompile-time mode —ListenSimTNet policy;AuthorityClasstags (Host/Owner/Fixed) for per-entity authority ownership in listen-server scenarios; runtime authority override table for resolution
- Host migration (ListenNet) — handshake protocol, candidate election (ranked by latency + snapshot recency), authority transfer with zero peer gap; prerequisite: snapshot serialization path
- Snapshot serialization path — serialize/deserialize full world state into snapshot format; feeds host migration, save states, late join, and debug replay
- Disconnect policy —
ClientHealthMetrics,ClientAction,NetDisconnectPolicystructs;ClientHealthCallbackfor game-owned policy; default threshold enforcement wired to NetThread health checks
- Deterministic / Non-Deterministic mode split — separate
AuthoritySim/OwnerSimpaths for non-deterministic mode; uses server timestamps (server_time_us) instead of frame numbers, state replication as primary sync signal, variable client Hz, 30Hz snapshot interpolation
- Networking without rollback — owner-only prediction and replay, per-client missing-input policy (no global stall outside lockstep), continuous clock sync with client time dilation (designed as pacing in Simulation Time), discrete input event injection,
PlayerInputLogsynchronization. See Networking Without Rollback.
- Server-only rollback — Authority re-simulates from its input log while Owners run without rollback (build flags already independent; PIE's server already does this — shipped server/client split pending)
- Lag compensation — server-side hit-validation history
- Remote entity representation — open design ("shooting a shadow of the target")
- Phase 0 tentative despawn — per-frame
TentativeDestroysring buffer for rollback-safe entity death (Phase 1–3 done; Phase 0 tracking not yet implemented)
Simulation
- Simulation time: falling behind and catching up — time the Brain owes is kept, not dropped past 250 ms, and repaid by mechanisms a game turns on and tunes together. Designed, decisions pending: Simulation Time (Known Issue 35).
- Local, testable in the resilience demo: debt counted in steps against a reference clock, with a suspension rule and the cutoff as a setting; pacing (run slightly fast or slow); the fallback camera on real time; quiet catch-up frames; input placed by timestamp; variable step in builds without rollback; coarse steps for cosmetic entities. A demo control for each.
- Networked, with Host and join: an Owner paces itself against its Authority with continuous clock sync, and the Authority's stall for a late Owner becomes lockstep-only (Known Issues 17, 19); shared slowdown; resync from the Authority's state (needs the snapshot path).
- Trinyx physics solver (long-term) — solver state in slab fields; prerequisite for full client prediction of physics-driven entities
- Constraint system — constraint entities (rollback + replication), handle-based bodies, depth-sorted resolve list, sim and render rigid attachment passes, physics root determination; basis of the Trinyx solver. See Physics
- Space partition cell registry — cell world origins, cell assignment at spawn, cross-cell reparenting
- Standalone Soul synthesis — create a local Soul in
FlowManagerfor offline/solo play (currently Soul creation is gated behind network handshake). Comes with Host, join, and solo in one build above: Solo runs the Authority's path, which makes owner 0's Soul.
Editor & UI
- Edit Timeline — Brain as sole slab writer in edit mode, edits committed as frames, transaction-based undo with the history ring as fast path, frame/entity snap, PIE time travel. See Edit Timeline.
- GG-UI — engine-native retained-mode UI for the editor and games; replaced Dear ImGui and ImGuizmo; GPU-expanded world UI; shared UI/2D renderer. See GG-UI.
- M1 platform, M2 core, M3 rendering, M4 interaction, M5 styling, M5b–c core at scale, M6 editor widgets. See the roadmap and measured numbers.
- M7 docking and multi-window (status). Done on Windows; the Wayland cross-window drag is left, on Linux.
- M8 the editor on GG-UI, M8b node graphs, M10 ImGui and ImGuizmo removed. Left in M8b: the code editor.
- Engine string table (
TnxStringTable: languages, files, editable from the editor) that fills the UI'sGGStringTable(Localisation).
- Input actions for the engine (Interaction). GG-UI has the slim one (key, chord, action named by a tag, action map, commands). Planned:
TnxInputActionover it for mouse, gamepad, axes, triggers, stacked contexts, and a map per player, with bindings resolved where input is read so the simulation and input log carry actions, not keys. Needs its own design.
- Configurable UI input for games: focus rules, wrapping, what brings the keyboard to the UI (Interaction).
Developer Experience
After the widget designer (GG-UI M9 step 8).
- Projects — the editor as its own program that opens a project: a
.tnxprojectfile, the project's C++ as a module loaded into the editor (the engine a shared library in development builds), engine and project built together in one IDE or by the editor, a Project Browser, New Project from templates (Blank first) and templates you can save and share as.tnxtemplatefiles, and Package Project / Package Engine from the editor and the command line. Staged: the editor opens a project, then projects from inside the editor, then engine upgrades and packaging profiles. Design: Projects.
- Reloadable game code — in development builds the game's code is a module the editor loads again after a build: registries owned by the module that made them, one safe point at the spawn handshake, ECS data kept (changed layouts copied by field name), Constructs and widget-class instances made again. Staged: edit mode (shared with the Projects foundation), then while playing, then patching in place. Design: Code Reload.
- Gotchas reported loudly — a debug check wherever a mistake is possible but not certain, warning once with what to change, across the engine. First: kept GG-UI content whose captures can't be compared reliably (a pointer or an index captured without a change stamp; padding bytes), and a debug mode that re-runs kept content now and then and reports output that changed without a re-run. Then an audit of the engine for other silent failures of the same kind.
- Tutorials — step-by-step guides beside the reference pages and the generated API reference, each building something that runs: a first project, a first Construct, a first HUD with the designer, a networked game. Each concept page leads with the five things most people need and leaves the rest to the reference.
- The engine screenshots itself — any build (game, editor, demo) can write its window, or one UI document, to an image on request (a console command, a command-line flag, a test call), so tests can compare against reference images and docs can be illustrated from real runs, with nothing outside the engine driving the desktop. Started:
RendererCore::andRequestScreenshot TNX_SCREENSHOTwrite the main window's document as a BMP, in the game and the editor. Left: PNG, a console command and flag, other windows, the 3D scene outside UI images, and a comparison helper for tests.
- Naming audit — every public name in GG-UI and the engine read once more, before more code depends on them: known UI terms where the meaning is the same (props, slots, bindings, styles), a bespoke name only where nothing known fits, prefixes applied consistently.
Demo and Test Builds
- Resilience demo project — one project that is both the showcase and the test environment for GG-UI and for the engine under load. A large cube grid and a physics pyramid (adjustable height, reset), with toggles for each "running behind" scenario and a live stats overlay (thread rates, sim time behind real time, age of the drawn frame, Input-to-Photon, rollbacks per second).
- Stage 1 — hooks and checks (no UI needed):
StressInjectionmakes Brain, Encoder, or Sentinel run long (constant delay or a stall);GNSContext::injects lag and loss. Testbed checks the policies: a constantly slow Brain falls behind with bounded debt and recovers; a stall inside the 250 ms debt limit is caught up fully and a longer one loses only the excess; a slow Encoder does not slow the sim.SetFakeNetwork
- Stage 2a — the stats overlay (GG-UI M3):
--statsshows thread rates, sim time behind real time, frame age, measured input-to-photon, rollbacks per second, and injected load, as a GG-UI document bound toEngineStats. Tested under each stress scenario.
- Stage 2b — the project itself (GG-UI M4 steps 1–3): the
ResilienceDemotarget. A wall of 10,000 cubes, a floor, and a physics pyramid; a GG-UI panel with a switch and a severity slider for each thread's load, a periodic Brain stall, a layer count and a rebuild for the pyramid, and the stats overlay beside it.ResilienceDemo --selftestworks the controls itself and checks what they did; presubmit runs it after the windowed Testbed. - Stage 3 — sessions: a menu, and playing alone, hosting, or joining from it, with the controls acting on the Host's simulation. See Host, Join, and Solo in One Build. Until then the demo has no player and a fixed camera, and its controls act on the local process.
- More scenarios (no networking needed):
StressInjectionalso keeps job workers occupied (BusyWorkers), draws the scene many more times a frame for the graphics card's sake (GpuDraws), and forces a rollback of a set depth every so many steps (RollbackEvery,RollbackDepth; rollback builds). Each has a switch and a slider in the demo's panel and a row in the overlay's injected-load section. Testbed checks each policy (Stress_WorkersBusy,Stress_ForcedRollback,Stress_GpuLoad); the demo's self-test turns each on from the UI and, running inside Sentinel's loop, also checks what Testbed could not: Sentinel made slow loses its own rate while the simulation keeps its own. - Stress scenarios still to add, each with a control in the panel:
- Network lag and loss (
GNSContext::exists; it needs a session to act on). With the Host and join work.SetFakeNetwork - A heavier load for the graphics card. Drawing the scene again is vertex work that the depth test mostly throws away: two hundred more draws of a small scene cost a fast card little. A pass that shades every pixel many times would load any card.
- Network lag and loss (
- Releasing it: the demo finds its configuration and content from its source directory (
TNX_); a packaged build needs them beside the executable.PROJECT_ DIR
- Stage 1 — hooks and checks (no UI needed):
- Playground net build — packaged build with a main menu (Host, Join); proves the full packaging path and a real network connection end to end
- Test console — local test runs (Testbed, presubmit) open a small console window showing progress (current test, passed / failed / skipped, time) and the live log with filters. One GG-UI console document: drawn in a window when a display is available (needs the console view, M4) and rendered to the terminal for headless and CI runs (terminal backend, M13).
Presentation
- Presentation Reconciler — Anti-Events (RapidFadeOut, SoftCancel, RapidDecay) for rollback-driven effect correction.
AudioManager::FadeOutis Anti-Event-compatible; diff logic not implemented.
Rendering
- Frustum culling — SIMD 6-plane test + GPU-side predicate enhancement
- Texture pipeline, material model, shadows — not yet designed; prerequisites for the VizBuffer material resolve and for GG-UI rendering
- State-sorted rendering — 64-bit sort keys, GPU radix sort after scatter
- Present-timing frame pacing — use measured display times (
VK_KHR_present_wait) to start render + sim-frame pickup just before vblank; brings Mailbox/FIFO close to Immediate latency. Game default is Mailbox until then. See Presentation & Latency.