Architecture at a glance
The engine boots through EntryPoint.h into a singleton Application that owns
the window, the render thread, the event queue, and the layer stack. The editor is
itself a layer. Layers create Scenes, which own everything that simulates: ECS registry,
physics worlds, scripts, observers. Rendering reads scenes; physics writes them; scripts can do either.
Subsystems
Application
Singleton root: window, layer stack, render-thread context, main loop. Threading policy chooses real render thread (runtime) vs same-thread queue drain (editor).
Window / Platform
Abstract Window with GLFWWindow (desktop, Vulkan) and NullWindow (headless). Watch for GLFW-only methods missing on the base.
Scene / ECS
entt-backed registry plus TimeManager, ScriptStorage, PrefabManager. Entities identified by stable UUIDs; transform hierarchy with shear-safe local↔world.
Asset System
Editor (file-based) and Runtime (packed) backends behind one AssetManager facade. Sync + async loads, dependency notifications, ~22 asset types.
Physics (Jolt)
3D rigid bodies behind a PhysicsAPI abstraction. Phased stepping: Acquisition → Control → Physics → Validation → Export. Layered collision filtering.
Physics (MuJoCo)
Robotics-grade simulator. Z-up to engine Y-up conversion via fixed axis matrices. CoACD convex decomposition. Substeps run per-phase callbacks.
Physics (Box2D)
2D mechanics directly via b2World — no abstraction layer. TimeManager callbacks for stepping and transform sync.
Renderer
NVRHI-backed Vulkan. SceneRenderer drives the deferred pipeline: pre-depth, cascaded shadows, GTAO, SSR, bloom, DOF, SMAA. HLSL shaders, cached pipelines.
Animation
Skeletal animation driven by AnimationGraph assets and bone entity hierarchies. TimeManager-driven update.
Scripting
C# on .NET 9 via Coral interop. InternalCalls bridge into the engine; per-entity field storage; hot reload invalidates managed refs — never cache them.
Editor
EditorLayer orchestrator plus a panel registry. EditorLayer is protected — new features go in their own panel. Strict ImGuiEx styling.
Audio
miniaudio engine with spatial audio, sound graphs, DSP, and runtime sound bank packaging. Singleton MiniAudioEngine; ECS components for source / listener.
Input
All-static frame-accurate keyboard, mouse, and controller polling. Update() per frame transitions key states.
Robot / MotionGraph
Graph-authored behaviour + per-entity ONNX policies. Policies override the graph on claimed joints; per-substep merge rules govern routing to actuators or qfrc.
Data / Observation
Records joint states, sensor data, camera frames → Parquet, LeRobot-compatible. Recording gated on LuckyHub approval; never stalls on hub latency.
Project / Build
Premake5, Conan, C++20. Make on Linux/Mac, VS2022 on Windows. ~38 vendor libs. CI in .github/workflows/.
MCP Server (Hazel-Bridge)
JSON-RPC 2.0 server. TCP + streamable HTTP. Localhost-only. Tool handlers marshal to the main thread via MainThreadDispatcher.
LuckyEditor-Agent
In-editor LLM agent. Static lib with plugin-shaped public surface. Uses Hazel-Bridge to expose harness/* and tool/* tools to clients.
Cross-cutting topics
Cross-cutting concerns
Smart pointers (Ref, WeakRef, Scope), events, serialization, logging, math, error handling.
Implementation playbook
How to add a component, asset type, panel, render pass, C# binding, MuJoCo integration, periodic system, worker.
Directory map
Visual tour of Hazel/, LuckyEditor/, LuckyRuntime/, scripts and CI.
gRPC + cross-system
Service boundary, SimulationContract, observation flow, change-where matrix to LuckyRobots / LuckyLab.
Threading model
Editor vs runtime threading, TimeManager phases, render thread semantics, std::jthread worker rules, gRPC marshaling.
Recording integrity
The four recording-data guarantees and the must-fix patterns the local code-review skill enforces.
Conventions
Style, helper reuse, ImGui patterns, naming, asserts and verifies — the rules a PR must respect.
This site mirrors .claude/docs/Architecture-LuckyEngine.md and its companion docs
(Conventions.md, Threading.md, RecordingIntegrity.md,
Architecture-LuckyRobots.md). For API-level signatures, read the headers in
Hazel/src/Hazel/… — they never go stale.