Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
[Milestone 3] - 2025-12-25
Added
Component System Architecture
TransformComponentfor independent transform management (local/world)ScaleComponentfor unit-based sizing with dirty flag trackingAabbColliderComponentfor world-space bounding boxesModelAabbComponentfor original model AABB storageLevelBoundsBehaviorComponentfor configurable boundary reactions (bounce, restitution)- Automatic AABB capture from SceneNode meshes via
onAttach()
Game Systems
Move2DSystemfor 2D physics with rotation, velocity integration, and dampeningScaleSystemfor applying unit-based scaling from ScaleComponentBoundsUpdateSystemfor updating AABB colliders from world transformsLevelBoundsBehaviorSystemfor boundary collisions with bounce behaviorSceneSyncSystemfor synchronizing gameplay transforms with scene graphTransformClearSystemfor clearing dirty flags at end of frameScaleClearSystemfor clearing scale dirty flags at end of frameProjectilePoolSystemfor efficient projectile object pooling
Level System
Levelclass with configurable world bounds- AABB-based arena boundaries
- Root SceneNode reference for level hierarchy
- Unit-aware bounds configuration via
setBounds()
Gameplay Components
Aim2DComponentfor direction tracking and firing frequencyShootComponentfor projectile firing with configurable cooldown and speed
Rendering Assets
Ellipse2D shape primitive for projectile and particle rendering- Configurable width, height, and segment count
Utility
Colorsstruct with comprehensive color palette asvec4f(RGBA)- Standard colors (Black, White, Red, Green, Blue, Yellow, Cyan, Magenta)
- Grayscale variants (LightGray, Gray, DarkGray)
- Extended palette (Coral, Salmon, Orange, Turquoise, Gold, etc.)
withW()method for alpha channel modification
ImGui Widgets
LogWidget: "None" scope option to completely disable logging (default)GamepadWidget: Settings panel with side-by-side stick configuration- Left/Right stick deadzone and inversion in two-column layout
- Settings panel initially expanded by default
Examples
spaceship_shootingdemo showcasing twin-stick shooter mechanics- Complete projectile pool integration with arena boundaries
- Debug gizmo visualization for aim and velocity directions
Changed
SceneNodeComponent
- BREAKING:
setSize()method removed - useScaleComponentinstead onAttach()now automatically captures AABB from SceneNode mesh
GameWorld
- BREAKING: Constructor no longer requires
Scene*parameter - Systems must be explicitly registered for game logic
Move2DComponent
- BREAKING:
position()method removed (transforms managed by TransformComponent) - BREAKING:
rotationAngle()renamed tocurrentRotationAngle() - Component now stores only physics state, not position
Fixed
- Forward declaration conflicts between Component and GameObject modules
- Circular dependency in module imports resolved via shared headers
[Milestone 2] - 2025-12-16
Added
Engine & Tooling
FramePacerclass for frame rate control with configurable target FPS (#111)FrameStatsstructure for frame timing information (frame time, idle time, work time)FpsMetricsclass for frame rate analysis and statisticsStopwatchhigh-resolution timer utility
Scene Graph & Camera System
CameraSceneNodefor camera integration into scene hierarchyTransformTypeenum for selective transform inheritance (Translation, Rotation, Scale) inhelios.math.transformmat4::decompose()member function for extracting transform componentsmat4::transpose()member function for matrix transpositiontransformTypeMatch()helper for bitmask flag testinglookAt()andlookAtLocal()methods for camera orientationonWorldTransformUpdate()virtual callback for transform change notifications- Camera-follows-object pattern via scene graph parenting
Game System (helios.engine.game)
GameObjectbase class for game entities with GUID identificationGameWorldcontainer for game object management and updatesCommandBufferfor deferred command execution patternInputSnapshotfor capturing input state per frameInputHandlerinterface for input-to-command translationsetSize()method for unit-based object sizing
Units System (helios.core.units)
Unitenum (Meter, Centimeter, Seconds, MilliSeconds)- Conversion utilities between unit types
- Standard unit: 1 Meter = 100 Centimeters (cm)
- Time measurement standard: Seconds
Gamepad Input System
GamepadSettingsclass for per-controller configurationDeadzoneStrategyabstract interface for input normalizationRadialDeadzoneStrategyimplementation for circular deadzone handling- Per-stick deadzone thresholds (0.0 to 0.9)
- Individual axis inversion (X/Y for left and right sticks)
InputAdapter::gamepadSettings()for runtime configuration accessInputManager::inputAdapter()non-const overload for settings modification
ImGui Integration Layer
ImGuiBackendabstraction for platform backendsImGuiGlfwOpenGLBackendconcrete implementation for GLFW/OpenGLImGuiOverlaysingleton manager with DockSpace supportImGuiWidgetbase interface for custom widgets- Semi-transparent window backgrounds (configurable)
ImGui Widgets
FpsWidgetfor frame rate display and target FPS controlGamepadWidgetfor real-time gamepad state visualization (#114)- Integrated settings panel for deadzone and axis inversion
- Real-time stick position and button state display
- Connection status indicator
- Multi-controller support (1-4)
LogWidgetfor scrollable log console with advanced filtering- Per-scope message buffers (1000 entries each)
- Filter by log level and scope via ComboBox
- Text search filter
- Auto-scroll with pause on manual scroll
- Scope-specific buffering on scope switch
CameraWidgetfor camera parameter control- Position, LookAt target, and Up vector editing
- Local/World space toggle for transforms
- FOV, Near/Far plane, and Aspect Ratio controls
- Quick view presets (Front, Top, Side, Isometric)
- Reset to initial values
MainMenuWidgetfor application settings- Window transparency control (slider + presets)
- Docking toggle
- Style themes (Dark, Light, Classic)
- Settings persistence via
imgui.ini
Logging System
LogSinkabstract interface with self-registering type identifiersConsoleSinkfor stdout outputImGuiLogSinkfor LogWidget integrationLogManagerwith enable/disable sinks by type identifier- Scope-based filtering support
Changed
Camera Architecture
- BREAKING: Cameras are now managed via
CameraSceneNodeinstead of standaloneCameraobjects Viewportnow holdsCameraSceneNode*instead ofCamera*- View matrix computed from inverse of
CameraSceneNode::worldTransform() - Projection matrix remains responsibility of
Camera(optics)
Logging System
- Refactored to use self-registering sinks
- Sinks define their own
TYPE_IDstring instead of centralSinkFlagsenum LogManager::enableSink("console")/disableSink("imgui")API- Extensible without modifying core logging code
Core & Rendering
- BREAKING: Enum counter entries renamed to
size_(#34) - BREAKING:
MeshDatamerged withMesh(#22) UniformValueMap::float_valreturn type refactored (#33)Materialownership structure improved (#13)
Fixed
- Potential nullptr dereference in
MaterialData(#16)
Documentation
- Added
CONVENTIONS.mdwith LHS coordinate system documentation - Matrix storage format (column-major) documentation
- View matrix construction explanation
- Units system documentation (
helios.core.units) - Updated API documentation for new modules
- Example code comments improved with section headers
[Milestone 1] - 2025-10-21
Added
- Application layer with event system
- Input manager for keyboard, mouse, and gamepad
- Low-level API subsystems integration (GLFW, GLAD)
- Basic rendering pipeline
- Scene graph with transform hierarchy
- Camera system with projection management
- Material and shader system
- Mesh and geometry handling
- Math library (vectors, matrices, transforms)
- Scoped logger implementation (#8)
- Default loggers for specific scopes (e.g.,
helios.rendering.shader) - LogManager for centralized logger access
- Default loggers for specific scopes (e.g.,
Infrastructure
- CMake build system with C++23 modules support
- Cross-platform support (Windows, Linux, macOS)
- Unit testing framework with Google Test
- Example applications (simple cube rendering, game controller input)
Release Notes
Milestone 2 Breaking Changes
The following breaking changes are included in this release:
Camera System Refactor
Cameras are now integrated into the scene graph via CameraSceneNode:
// Before (Milestone 1)
auto camera = std::make_shared<Camera>();
viewport->setCamera(camera.get());
camera->setPosition({0, 0, 5});
camera->lookAt({0, 0, 0}, {0, 1, 0});
// After (Milestone 2)
auto camera = std::make_unique<Camera>();
auto cameraNode = std::make_unique<CameraSceneNode>(std::move(camera));
auto* nodePtr = scene->addNode(std::move(cameraNode));
viewport->setCameraSceneNode(nodePtr);
nodePtr->setTranslation({0, 0, 5});
nodePtr->lookAt({0, 0, 0}, {0, 1, 0});
Migration: Replace Camera usage with CameraSceneNode. Use scene graph methods (translate, rotate) instead of direct camera manipulation.
Transform Inheritance
Child nodes can now selectively inherit transform components using helios::math::TransformType:
import helios.math.transform;
// Camera follows parent position only, maintains own orientation
cameraNode->setInheritance(helios::math::TransformType::Translation);
// Full inheritance (default)
childNode->setInheritance(helios::math::TransformType::All);
// Combine flags
node->setInheritance(helios::math::TransformType::Translation | helios::math::TransformType::Rotation);
Enum Sentinel Naming (#34)
All enum counter/size entries have been renamed to size_:
// Before
enum class Key { A, B, C, COUNT };
// After
enum class Key { A, B, C, size_ };
MeshData Removal (#22)
MeshData has been merged into Mesh:
// Before
MeshData meshData = ...;
Mesh mesh(meshData);
// After
Mesh mesh = ...;
Material Ownership (#13)
Materials now own their shader and material data:
// Before
MaterialData materialData(shader, properties);
Material material(materialData);
// After
auto shader = std::make_shared<Shader>(...);
auto properties = std::make_shared<MaterialProperties>(...);
auto material = std::make_shared<Material>(shader, properties);