Storming Engine: C++ Core Architecture
This document provides a technical overview of the C++ Core of the Storming Engine. The engine is designed as a high-performance, decoupled renderer that communicates with the Java Editor via a strict JSON-based IPC (Inter-Process Communication) protocol.
Dual-Engine Architecture
The engine supports two distinct operational modes, allowing for a Godot-style workflow where the Editor workspace and the Game runtime remain separate.
1. Editor Mode (--editor)
Used for the background workspace view.
- Visual Overlays: Renders an infinite grid and coordinate origin cross (Red X, Green Y).
- Selection Highlighting: Draws a yellow bounding box around the currently selected entity.
- Stateful Tracking: The engine maintains an internal
m_SelectedEntityIDto facilitate relative transformations.
2. Runtime Mode (Default)
Used for the Simulation Window.
- Clean View: No grid or editor-specific overlays.
- Performance Focused: Optimized for running game logic and scripts without editor overhead.
Core Systems
Application Lifecycle (Application.cpp)
The Application class manages the main engine loop, windowing (via SDL3), and the IPC bridge.
- Initialization: Sets up the OpenGL 4.5 Core context and configures the
Renderer2D. If launched with--shm, it initializes aFrameBufferlinked to Shared Memory. - Robust IPC: Processes commands using a line-buffered non-blocking
STDINreader. This ensures that high-frequency data (like mouse dragging) is processed reliably without dropping packets. - The Run Loop:
- Poll Events: Handles SDL window events.
- Process Commands: Parses and executes incoming JSON commands immediately.
- Render Frame: Clears the buffer and calls
Scene::OnUpdate. - Editor Overlays: If in Editor Mode, renders the grid, origin, and selection box.
- Sync/Swap: In Editor Mode,
glFinish()is called to ensure memory consistency before Java reads the pixel buffer. - Telemetry: Performance stats (FPS, Draw Calls, Quads) are broadcast to
STDOUTevery 500ms.
Entity Component System (ECS)
The engine uses EnTT, a fast, cache-friendly ECS library.
Scene: The container for all game objects. It owns theentt::registry.OnUpdate(float ts): Iterates through entities with aSpriteRendererComponentand submits them to theRenderer2D.PickEntity(float x, float y): Performs AABB (Axis-Aligned Bounding Box) physics checks to find and select entities under the mouse cursor.Serialize(): Converts the entire registry into a formatted JSON string for saving.
Components: Pure data structures.TagComponent: The entity's name (visible in Hierarchy).TransformComponent: Position (Translation), Rotation (Euler Z for 2D), and Scale.SpriteRendererComponent: Color (RGBA) and Texture reference.
Rendering Pipeline (Renderer2D.cpp)
A high-performance batch-oriented 2D renderer.
- Batching: Quads and Lines are accumulated in CPU-side buffers and uploaded to the GPU in bulk.
- Lines: Supports a secondary batching path for debug lines, grids, and selection boxes.
- Textures: Supports up to 16 texture slots per draw call using a dynamic array sampler
u_Textures[16].
Inter-Process Communication (IPC)
Commands (Java -> C++)
| Action | Payload | Description |
|---|---|---|
load_scene | {"path": "..."} | Clears the current scene and loads entities from a file. |
select_entity | {"id": 123} | Selects an entity and requests its full details. |
translate_selected | {"dx": val, "dy": val} | Moves the selected entity by a delta world amount. |
rotate_selected | {"da": val} | Rotates the selected entity by a delta angle (radians). |
scale_selected | {"ds": val} | Uniformly scales the selected entity by a delta amount. |
update_component | {"id": 1, ...} | Directly updates a specific component field (e.g., Color). |
create_entity | {"name": "...", "sprite": bool} | Spawns a new entity in the active registry. |
delete_entity | {"id": 123} | Destroys the specified entity. |
request_save | {} | Requests a full JSON dump of the scene state. |
request_picking | {"x": val, "y": val} | Performs a hit test at normalized coordinates. |
Telemetry (C++ -> Java)
Broadcast to STDOUT with the [TELEMETRY] prefix.
| Type | Payload | Description |
|---|---|---|
scene_tree | {"entities": [...]} | The full hierarchy list. Sent on any scene change. |
entity_details | {"components": {...}} | Full component state for the Inspector panel. |
telemetry | {"fps": 60, ...} | Real-time performance and renderer stats. |
scene_data_dump | {"data": "..."} | The raw JSON string of the scene, ready for disk writing. |
Build System
- CMake: Manages the C++ build process.
- Key Dependencies:
SDL3,GLAD,EnTT,GLM,nlohmann/json.