Status & Roadmap

Home | Design Decisions → | Known Issues →


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

#MilestoneStatusNotes
1Editor (bare-bones)✅ Complete8 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.
2Construct/View OOP✅ CompleteConstruct<T>, Owned<T>, ConstructView<TEntity>, ConstructBatch, JoltCharacter. PlayerConstruct proven.
3NetworkingIn ProgressGNS 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.
4Audio✅ CompleteSDL3 AudioManager: voice pool, handle-based playback, event registry, per-voice fade, priority voice stealing. Anti-Event compatible.
5Camera System✅ CompleteCameraManager (per-Soul layer stack), CameraSlot[5], CameraLayer + mixins, ECameraNode (cold), ECamera (hot SoA), CurveHandle.
6Game FlowIn ProgressFlowManager, FlowState, GameMode, Soul, NetChannel done. WithSpawnManagement, WithLobby, WithTeamAssignment ModeMixins done. ClientRepState 7-state machine done.
7AnimationIn ProgressRollback-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_NAMES build 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

  • TemporalComponentCache SoA ring buffer
  • TemporalFlagBits typed enum (Active, Dirty, DirtiedFrame, Replicated, Alive, Tombstone, …)
  • TNX_TEMPORAL_FIELDS / TNX_VOLATILE_FIELDS with SystemGroup tag (auto-derives partition)

Physics

  • JoltCharacter — CharacterVirtual wrapper for Construct-driven character controllers
  • Rollback netcode — SaveState/RestoreState snapshot ring buffer, ExecuteRollbackTest, byte-perfect determinism verified (2026-03-29)

Networking

  • LogicThread<TNet, TRollback, TFrame> three-axis policy template (2026-05)
  • ClientRepState 7-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 / ConstructDestroy wire types)
  • Entity activation pipeline (EntityActivate, StreamLoad/StreamReady/ChunkActivate)
  • 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

  • Blendspace evaluation on the GPU, cross-fades, masked replace/additive overlay layers
  • AnimConstruct state machine mixin — root motion, notifies, sockets, FK bone cache
  • glTF skeleton and animation import

Rendering

  • Per-mesh indirect draws — build_draws + sort_instances passes 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)
  • SimFloat alias — SimFloatImpl<float> or <Fixed32> via TNX_DETERMINISM
  • FixedTrig (FixedSin/FixedCos LUT)
  • Jolt fixed-point bridge validated — engine runs deterministically

Game Flow

  • FlowManager — state stack, travel primitives, World/Level/Mode lifetime management
  • Soul (OwnerID identity, ClaimBody/ReleaseBody, RPC dispatch)
  • Travel toolbox — three orthogonal levers (domain lifetime, Construct lifetime, network continuity)
  • GameModeManifest / ClientModeManifest CRTP 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 Game build model, a ListenSim policy that gives one world a run-time role, a general net thread, emptying a world in place, and StartSession / EndSession on 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.
  • ListenNet compile-time mode — ListenSim TNet policy; AuthorityClass tags (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, NetDisconnectPolicy structs; ClientHealthCallback for game-owned policy; default threshold enforcement wired to NetThread health checks
  • Deterministic / Non-Deterministic mode split — separate AuthoritySim/OwnerSim paths 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, PlayerInputLog synchronization. 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 TentativeDestroys ring 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 FlowManager for 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's GGStringTable (Localisation).
    • Input actions for the engine (Interaction). GG-UI has the slim one (key, chord, action named by a tag, action map, commands). Planned: TnxInputAction over 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 .tnxproject file, 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 .tnxtemplate files, 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::RequestScreenshot and TNX_SCREENSHOT write 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): StressInjection makes Brain, Encoder, or Sentinel run long (constant delay or a stall); GNSContext::SetFakeNetwork 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.
    • Stage 2a — the stats overlay (GG-UI M3): --stats shows 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 to EngineStats. Tested under each stress scenario.
    • Stage 2b — the project itself (GG-UI M4 steps 1–3): the ResilienceDemo target. 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 --selftest works 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): StressInjection also 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::SetFakeNetwork exists; it needs a session to act on). With the Host and join work.
      • 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.
    • Releasing it: the demo finds its configuration and content from its source directory (TNX_PROJECT_DIR); a packaged build needs them beside the executable.
  • 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::FadeOut is 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.