A modular, high-performance 2D Game Engine and Editor built with C++20, SFML 3.2, and Dear ImGui (docking branch).
Elysium has evolved from a standalone 2D physics engine into a full-featured 2D Game Engine featuring a dockable editor suite, type-safe event architecture, decoupled layer/overlay hierarchy, offscreen viewport rendering, and interactive component reflection.
- Overview & Architecture
- Key Features
- Project Directory Layout
- Subsystem Guides
- 1. Application & Layer Lifecycle
- 2. Event System & Input Handling
- 3. Game Engine Editor & Docking UI
- 4. Viewport & Rendering Pipeline
- 5. Scene, Entities & Components
- 6. 2D Physics Simulation
- 7. Audio Subsystem & Spatial Sound
- 8. Asset Management & Registry
- 9. Project Architecture & Native File Dialogs
- Prerequisites & Dependencies
- Building & Running
- Developer & Contributor Guide
- Roadmap
- License
Elysium follows a modular, decoupled engine design:
+-------------------------------------------------------------------------+
| ElysiumApp |
| (Client Entry Point / Sandbox Application) |
+-------------------------------------------------------------------------+
|
v
+-------------------------------------------------------------------------+
| Application Core |
| - Master Game Loop (Variable/Fixed Timestep via sf::Clock) |
| - LayerStack (Game Layers & Editor UI Overlays) |
| - Window Abstraction (sf::RenderWindow + SFML 3 Event Pump) |
+-------------------------------------------------------------------------+
| |
v v
+------------------------+ +------------------------+
| Event System | | Editor Layer |
| - Type-Safe Events | | - ImGui DockSpace |
| - EventDispatcher | | - Menu Bar & Hotkeys |
| - Key & Mouse Codes | | - Modular Panels |
+------------------------+ +------------------------+
| |
v v
+------------------------+ +------------------------+
| Scene & Entities | | Offscreen Viewport |
| - GameObject System | | - sf::RenderTexture |
| - Component Pipeline | | - 2D Editor Camera |
| - SpriteRenderer | | - SimpleRenderer |
+------------------------+ +------------------------+
|
v
+-------------------------------------------------------------------------+
| Physics Engine |
| - RigidBody Dynamics & Inertia Tensors |
| - BroadPhase Spatial Grid & NarrowPhase SAT Detection |
| - Circle & Box Colliders |
+-------------------------------------------------------------------------+
- Dockable Engine Editor:
- ImGui docking branch with workspace persistence and custom modern dark theme.
- Comprehensive Main Menu Bar (
File,Edit,Scene,Entities,View,Options). - Play, Pause, and Single-Frame Step toolbar controls to toggle between Edit Mode and Simulation Mode.
- Off-Screen Viewport:
- Scene is rendered into an
sf::RenderTextureand displayed viaImGui::Image. - Independent 2D Editor Camera with smooth panning (Right-Click / Middle-Click drag) and zooming (Mouse Wheel), completely decoupled from the editor UI.
- Scene is rendered into an
- Scene Hierarchy & Entity Inspector:
- Filterable live entity list with selection highlight.
- Interactive component reflection for
Transform(Position, Rotation, Scale),RigidBody2D(Mass, Linear/Angular Velocity, Static/Dynamic toggle, Friction, Restitution),Collider2D(Sphere radius, Box extents), andSpriteRenderer. - Instant two-way synchronization: inspector edits sync physics bodies and transforms in real time.
- Application & LayerStack:
Applicationsingleton owns the master game loop, window, andLayerStack.- Distinguishes standard
Layers (gameplay, simulation) fromOverlays (editor, diagnostics).
- Zero-Allocation Event System:
- Type-safe event hierarchy (
WindowCloseEvent,WindowResizeEvent,KeyPressedEvent,MouseButtonPressedEvent,MouseScrolledEvent, etc.). - Templated
EventDispatcherrouting events with category bitmasks.
- Type-safe event hierarchy (
- Real-Time Diagnostics:
- In-engine Console Panel hooked directly into
spdlogvia a custom ring-bufferedEditorLogSink. - Stats & Profiler Panel showing real-time FPS graphs, frame timing breakdown (Update, Physics, Render), entity counts, and draw call statistics.
- In-engine Console Panel hooked directly into
- 64-Bit UUID & Safe Entity Handles:
- High-performance
UUIDclass backed by hardware entropy (std::random_device) and standard 64-bit Mersenne Twister (std::mt19937_64). - Persistent, unique 64-bit identifiers assigned to all
GameObjects with full support for explicit IDs during scene deserialization. - O(1) hash map scene lookups and safe deletion (
Scene::GetEntityByUUID,Scene::DestroyEntityByUUID). - Safe, lightweight templated
EntityHandlereference wrapper preventing dangling pointer crashes.
- High-performance
- Asset Manager & Registry (
AssetManager):- Centralized static/singleton system mapping 64-bit UUID
AssetHandles to assets (sf::Texture,sf::Font,sf::SoundBuffer,Scene). - Thread-safe dual-mutex asset caching eliminating redundant disk reads or GPU/audio memory allocations.
- Manifest serialization (
assets.meta) persisting asset UUID-to-path relationships across engine sessions.
- Centralized static/singleton system mapping 64-bit UUID
- Interactive Content Browser Panel (
ContentBrowserPanel):- ImGui panel inheriting from
EditorPanelwith folder tree navigation on the left and directory content grid on the right. - Navigation history stack (Back, Forward, Up), path breadcrumbs, search filtering, and thumbnail resizing.
- Procedural visual icons tailored for folders, textures, audio files, fonts, and scene documents.
- Automatic filesystem watcher and manual refresh button.
- Drag-and-drop source with payload support (
CONTENT_BROWSER_ITEM_TEXTURE,CONTENT_BROWSER_ITEM_AUDIO, etc.) received directly by component inspectors (e.g. dragging.pngintoSpriteRenderer).
- ImGui panel inheriting from
- Project Management System (
Project&ProjectSerializer):- Dynamic project architecture driven by
.elyprojproject files tracking active project directories, asset roots, and start scenes. - Automatic project directory initialization creating
<Project>/Assets/,<Project>/Assets/Scenes/, and<Project>/Assets/assets.meta. - Canonical absolute path resolution removing hardcoded workspace dependencies.
- Dynamic project architecture driven by
- Cross-Platform Native File Dialogs (
FileDialog):- Native OS folder selector and file picker dialogs on Linux (Zenity/KDialog), Windows (Win32
IFileDialog/GetOpenFileName), and macOS (osascript). - Seamlessly integrated with
File -> New Project...andFile -> Open Project...in the editor menu bar.
- Native OS folder selector and file picker dialogs on Linux (Zenity/KDialog), Windows (Win32
- 2D Physics Simulation:
- Continuous impulse-based rigid body dynamics, broadphase spatial hash grid, and narrowphase SAT collision response.
- Audio Subsystem:
- Decoupled
AudioEnginesingleton/application subsystem managing streamed background music (sf::Music) and an asset-cached pool of sound effects (sf::Sound/sf::SoundBuffer). AudioSourceComponentproviding GameObject-attached 3D spatial audio synchronized with entityTransforms and SFML 3'ssf::Listener.- Full editor reflection in the Entity Inspector with file path picker, volume/pitch sliders, loop/spatial toggles, and live playback preview controls.
- Decoupled
ElysiumEngine/
├── CMakeLists.txt # Root build configuration (FetchContent for ImGui & ImGui-SFML)
├── README.md # Main engine documentation
├── PLAN.md # Long-term development roadmap and technical design
├── LICENSE # MIT License
├── app/
│ └── main.cpp # Client entry point (instantiates Sandbox Application)
├── engine/
│ ├── CMakeLists.txt # Engine library build target (ElysiumEngine)
│ ├── core/ # Application core, windowing, and entity systems
│ │ ├── include/
│ │ │ ├── Application.hpp # Application singleton and master loop
│ │ │ ├── AudioEngine.hpp # High-level Audio Subsystem & sound pool
│ │ │ ├── AudioSourceComponent.hpp # GameObject spatial audio component
│ │ │ ├── Window.hpp # sf::RenderWindow encapsulation and event pump
│ │ │ ├── Layer.hpp # Base class for engine layers
│ │ │ ├── LayerStack.hpp # Ordered layer and overlay stack
│ │ │ ├── Timestep.hpp # Frame delta time wrapper (seconds/ms)
│ │ │ ├── KeyCodes.hpp # Platform-independent key codes
│ │ │ ├── MouseCodes.hpp # Platform-independent mouse codes
│ │ │ ├── GameObject.hpp # Entity definition and component container
│ │ │ ├── EntityHandle.hpp # Lightweight templated entity reference handle
│ │ │ ├── UUID.hpp # 64-bit UUID class and std::hash specialization
│ │ │ ├── Component.hpp # Component base interface
│ │ │ ├── SpriteRenderer.hpp # Visual shape/sprite renderer component
│ │ │ ├── Scene.hpp # Scene container and physics world binding
│ │ │ ├── SimpleRenderer.hpp # Off-screen & target-agnostic 2D renderer
│ │ │ ├── Input.hpp # Static keyboard and mouse polling
│ │ │ ├── FileDialog.hpp # Cross-platform native file and folder pickers
│ │ │ ├── Project.hpp # Project configuration and active management
│ │ │ ├── ProjectSerializer.hpp # YAML/JSON project serialization (.elyproj)
│ │ │ ├── Log.h # spdlog logging macros
│ │ │ ├── Core.hpp # Platform macros and DLL exports
│ │ │ ├── EntryPoint.hpp # Platform main() bootstrap
│ │ │ └── Elysium.hpp # Umbrella engine header for client apps
│ │ └── src/
│ │ ├── Application.cpp # Engine game loop and event distribution
│ │ ├── AudioEngine.cpp # Audio subsystem, sound pool & buffer cache
│ │ ├── AudioSourceComponent.cpp # AudioSourceComponent lifecycle & spatialization
│ │ ├── FileDialog.cpp # Native OS dialog implementation (Linux/Win/Mac)
│ │ ├── GameObject.cpp # GameObject lifecycle & logging
│ │ ├── Project.cpp # Project initialization, loading, and directories
│ │ ├── ProjectSerializer.cpp # .elyproj serialization and deserialization
│ │ ├── Scene.cpp # Scene entity registry and physics integration
│ │ ├── UUID.cpp # 64-bit Mersenne Twister & entropy generator
│ │ ├── Window.cpp # SFML 3 event pump and translation
│ │ ├── Layer.cpp # Layer base implementation
│ │ ├── LayerStack.cpp # LayerStack management
│ │ └── Log.cpp # spdlog initialization
│ ├── editor/ # Dear ImGui Editor UI module
│ │ ├── include/
│ │ │ ├── AssetManager.hpp # Centralized asset manager, registry, and caching
│ │ │ ├── EditorLayer.hpp # Engine layer driving ImGui lifecycle & docking
│ │ │ ├── EditorContext.hpp # Shared state (camera, selection, play state, stats)
│ │ │ ├── EditorPanel.hpp # Abstract modular editor panel interface
│ │ │ ├── EditorLogSink.hpp # spdlog memory sink for in-editor console
│ │ │ └── panels/ # Concrete panel definitions
│ │ │ ├── ContentBrowserPanel.hpp # Interactive directory tree & grid asset browser
│ │ │ ├── SceneViewportPanel.hpp # Off-screen texture & pan/zoom camera
│ │ │ ├── SceneHierarchyPanel.hpp # Entity list, search, add/delete
│ │ │ ├── EntityInspectorPanel.hpp # Component reflection and mutation
│ │ │ ├── ToolbarPanel.hpp # Play, Pause, Step controls
│ │ │ ├── ConsolePanel.hpp # Filtered log viewer
│ │ │ └── StatsPanel.hpp # Profiler, FPS plot, and timings
│ │ └── src/
│ │ ├── AssetManager.cpp # Thread-safe caching and manifest serialization
│ │ ├── EditorLayer.cpp # DockSpace, theme, menu bar, and shortcuts
│ │ ├── EditorLogSink.cpp # Circular log buffer implementation
│ │ └── panels/ # Panel implementations
│ │ └── ContentBrowserPanel.cpp # Folder tree, grid, thumbnails, and drag-and-drop
│ ├── events/ # Event system architecture
│ │ ├── Event.hpp # Base Event, EventDispatcher, categories
│ │ ├── ApplicationEvent.hpp# WindowCloseEvent, WindowResizeEvent
│ │ ├── KeyEvent.hpp # KeyPressedEvent, KeyReleasedEvent, KeyTypedEvent
│ │ └── MouseEvent.hpp # MouseMovedEvent, MouseScrolledEvent, MouseButtonEvent
│ └── physics/ # 2D Physics Engine
│ ├── include/
│ │ ├── RigidBody.hpp # Mass, inertia, velocities, colliders
│ │ ├── Collider.hpp # Sphere and Box collider geometry
│ │ ├── PhysicsWorld.hpp # Simulation manager and solver loop
│ │ ├── BroadPhase.hpp # Spatial hash grid
│ │ ├── NarrowPhase.hpp # SAT collision detection and resolution
│ │ ├── AABB.hpp # Axis-aligned bounding boxes
│ │ ├── CollisionPair.hpp # Potential contact pair representation
│ │ └── CoreMath.hpp # Vec2, Vec3, Mat3, Quat math primitives
│ └── src/
│ ├── AABB.cpp
│ ├── Collider.cpp
│ ├── PhysicsWorld.cpp
│ └── RigidBody.cpp
├── external/ # Git submodules
│ ├── SFML/ # SFML 3.2.0 source
│ └── spdlog/ # spdlog header-only logging
└── test/ # Unit tests and benchmarks
├── AssetManagerTest.cpp
├── BoundaryTest.cpp
├── BroadPhasePerformanceTest.cpp
├── FrictionTest.cpp
├── PhysicsPerformanceTest.cpp
├── ProjectTest.cpp
├── RigidBodyDecouplingTest.cpp
└── UUIDEntityTest.cpp
Client applications inherit from Elysium::Application. The engine owns the window and controls the main loop:
#include <Elysium.hpp>
class Sandbox : public Elysium::Application {
public:
Sandbox() : Application("My Elysium Game") {
// Push regular game layers:
// PushLayer(new GameplayLayer());
// Push the editor UI as an overlay (rendered on top):
PushOverlay(new Elysium::EditorLayer());
}
~Sandbox() override = default;
};
// Engine entry point defines the factory function:
Elysium::Application *Elysium::CreateApplication() {
return new Sandbox();
}The master loop in Application::Run() executes every frame:
- Calculates frame delta time and constructs a
Timestep. - Calls
Window::OnUpdate(), polling OS events and translating them into engine events. - Iterates front-to-back through
LayerStack, callinglayer->OnUpdate(timestep). - Executes the ImGui rendering pass for all layers (
layer->OnImGuiRender()). - Calls
Window::Display()to swap frame buffers.
Events inherit from Event and carry category bitmasks:
void MyLayer::OnEvent(Elysium::Event& event) {
Elysium::EventDispatcher dispatcher(event);
// Bind type-safe event handlers
dispatcher.Dispatch<Elysium::KeyPressedEvent>([this](Elysium::KeyPressedEvent& e) {
if (e.GetKeyCode() == Elysium::Key::Space) {
ELYSIUM_INFO("Space key was pressed!");
return true; // Mark as handled so layers below do not receive it
}
return false;
});
}Events are dispatched down the LayerStack in reverse order: Overlays (such as the Editor) receive events first. If an overlay handles the event (event.Handled = true), lower gameplay layers will not receive it.
EditorLayer is implemented as an engine Overlay. It manages:
- DockSpace: Full-screen docking host window (
ImGui::DockSpaceOverViewport()), allowing tabs, split panes, and floating tool windows. - Theme: Slate dark theme styled with rounded corners and high-contrast accents.
- Main Menu Bar:
File: New Scene, Open, Save, Save As, Exit.Edit: Undo, Redo, Delete Selected Entity, Deselect.Scene: Play, Pause, Step, Reset Camera View, Clear All.Entities: Quick-create Empty Entity, Ball, Box, or Platform.View: Toggle visibility for any active panel.Options: Switch themes (Dark, Classic, Light), toggle Debug Grid, Colliders, or AABBs.
- Shortcuts:
Space: Toggle Play / Pause simulation.F: Focus viewport camera on selected entity.Delete: Delete currently selected entity.
The Scene Viewport Panel (SceneViewportPanel) achieves full decoupling between the Editor UI and game graphics:
- Dynamically resizes an off-screen
sf::RenderTextureto match the ImGui window's available region. - Applies the
EditorCameraview matrix (position and zoom level). - Renders the active scene via
SimpleRenderer. - Displays the resulting texture within ImGui using
ImGui::Image(). - Viewport camera controls:
- Pan: Hold Right Mouse Button or Middle Mouse Button and drag inside the viewport.
- Zoom: Scroll the Mouse Wheel to zoom between 5% and 2000%.
- HUD Overlay: On-screen coordinates and quick "Reset View" button.
Game objects are represented by GameObject:
- Identity & UUID: Every
GameObjectis uniquely identified by a 64-bitUUID(entity->GetUUID()). Supports explicit UUIDs upon creation for deserialization. - Transform:
position(Vec3),rotation(Quat),scale(Vec3). - Physics: Optional attached
std::unique_ptr<RigidBody>. - Components: Extensible component array (
std::vector<std::unique_ptr<Component>>). - Lookup: Query components via
entity->GetComponent<T>()or check existence withentity->HasComponent<T>(). - Visuals: Attach
SpriteRendererfor color, rectangle sizes, or circle shapes.
Scene maintains an internal std::unordered_map<UUID, std::shared_ptr<GameObject>> for fast O(1) entity management:
// Look up an entity by UUID
GameObject* entity = scene.GetEntityByUUID(uuid);
// Safely destroy an entity (unregisters physics, map entry, and list)
bool success = scene.DestroyEntityByUUID(uuid);To prevent dangling pointers across frames when entities are destroyed, components can use the lightweight templated EntityHandle<T>:
// Store handle instead of raw pointer
Elysium::EntityHandle<GameObject> targetHandle(targetEntity->GetUUID());
// Safely resolve at runtime
if (GameObject* liveTarget = targetHandle.Resolve(&scene)) {
// Entity is alive and safe to access
}
// Or resolve a specific component type
if (HealthComponent* health = targetHandle.ResolveComponent<HealthComponent>(&scene)) {
health->TakeDamage(10.0f);
}In the Entity Inspector, modifying any transform parameter automatically invokes entity->SyncTransform(), instantly synchronizing the physics body's position, centroid, and orientation.
The physics engine (engine/physics/) provides robust 2D dynamics:
- RigidBody: Mass, inverse mass (0 for static objects), linear and angular velocities, friction, restitution, and inertia tensors.
- Colliders:
Collider::CreateSphere(radius, density)andCollider::CreateBox(halfExtents, density). - BroadPhase: Uniform spatial grid for rapid collision pair candidate pruning.
- NarrowPhase: Separating Axis Theorem (SAT) for box-box, sphere-sphere, and box-sphere contact manifold generation.
- Simulation Control: Toggle between Edit Mode (physics paused, live manual transform positioning) and Play Mode (active physics stepping).
Elysium features a decoupled, high-level audio system built with SFML 3.2:
-
AudioEngine Subsystem:
- Accessible via
AudioEngine::Get()orApplication::Get().GetAudioEngine(). - Background music streaming via
sf::Music(PlayMusic,PauseMusic,ResumeMusic,StopMusic). - Cached sound buffers (
sf::SoundBuffer) and dynamic sound pool recycling (AcquireSound,PlaySound). - Master volume control modulating SFML 3's
sf::Listener::setGlobalVolume.
- Accessible via
-
AudioSourceComponent:
- Attach audio playback directly to entities:
auto entity = std::make_shared<GameObject>("AudioEmitter"); auto& audio = entity->AddComponent<Elysium::AudioSourceComponent>("assets/sounds/ambient.ogg"); audio.isSpatial = true; audio.loop = true; audio.playOnAwake = true; audio.minDistance = 2.0f; audio.attenuation = 1.0f;
- In spatial mode (
isSpatial = true), the component tracks the entity's 3D transform (Vec3 position) and updatessf::SoundSource::setPositionin real-time relative to the global listener.
- Attach audio playback directly to entities:
-
Editor Reflection:
- Exposes sound file selection, live play/pause/stop previews, volume/pitch sliders, and spatial attenuation parameters inside the Entity Inspector.
Elysium provides a centralized, thread-safe asset management pipeline centered on 64-bit UUID handles:
-
Asset Handles & Metadata:
- Every asset is identified by an
AssetHandle(UUID). AssetMetadatastores the handle,AssetType(Texture,Font,Audio,Scene), normalized relative file path, and memory residency state.- Deduced automatically from file extensions (
.png,.jpg,.wav,.ogg,.ttf,.elyscene).
- Every asset is identified by an
-
Thread-Safe Caching (
Load<T>):- Assets are cached in memory using dual-mutex synchronization, preventing redundant disk I/O and GPU/audio allocations:
// Fast O(1) cached lookup or thread-safe lazy load std::shared_ptr<sf::Texture> texture = AssetManager::Get().Load<sf::Texture>(handle);
- Assets are cached in memory using dual-mutex synchronization, preventing redundant disk I/O and GPU/audio allocations:
-
Manifest Persistence (
assets.meta):- Automatically reads and serializes the asset manifest across sessions, resolving relative project paths to persistent 64-bit UUIDs across engine and editor restarts.
-
Interactive Content Browser (
ContentBrowserPanel):- Split-view editor panel featuring an interactive folder tree on the left and an adaptive thumbnail grid on the right.
- Complete navigation history (Back, Forward, Up), path breadcrumbs, search filtering, and thumbnail scaling.
- Drag-and-drop source using engine payloads (
CONTENT_BROWSER_ITEM_TEXTURE,CONTENT_BROWSER_ITEM_AUDIO, etc.) received directly by component slots (e.g., dropping.pngonto aSpriteRendererslot).
Elysium organizes games into standalone, portable projects decoupled from the engine binary:
-
Project Configuration (
ProjectConfig):- Encapsulates
Name,ProjectDirectory(canonical absolute path),AssetDirectory(relative to project, defaults toAssets), andStartScenePath. - Serialized to/from
.elyprojfiles usingProjectSerializer.
- Encapsulates
-
Project Creation & Directory Initialization:
- Creating a new project automatically establishes the full workspace hierarchy:
/path/to/MyGame/ ├── MyGame.elyproj # Project configuration └── Assets/ # Project-isolated asset root ├── assets.meta # Initialized registry manifest └── Scenes/ # Default scene storage
- Creating a new project automatically establishes the full workspace hierarchy:
-
Cross-Platform Native File Dialogs (
FileDialog):- Native OS directory selector and file picker dialogs without external dependencies:
- Linux: Invokes native
zenity(orkdialogfallback). - Windows: Win32
IFileDialog/GetOpenFileNameAandSHBrowseForFolderA. - macOS: Native
osascriptAppleScript dialogs.
- Linux: Invokes native
- Triggered directly from the Editor menu:
File -> New Project...(Ctrl+Shift+N): Select any folder on disk to initialize a project.File -> Open Project...(Ctrl+Shift+O): Browse and load existing.elyprojfiles.
- Dynamically updates the window title, dockspace header, and reloads
AssetManagerandContentBrowserPanelto the selected project root.
- Native OS directory selector and file picker dialogs without external dependencies:
- OS: Linux, Windows, or macOS
- Compiler: C++20 compliant compiler (GCC 11+, Clang 13+, MSVC 2022+)
- Build System: CMake 3.20+
- Linux Packages:
libx11-dev,libxrandr-dev,libxcursor-dev,libxi-dev,libudev-dev,libgl1-mesa-dev
- SFML 3.2.0: Included as submodule under
external/SFML - spdlog: Included as submodule under
external/spdlog(header-only mode) - Dear ImGui: Automatically fetched via CMake (
v1.91.5-dockingbranch) - ImGui-SFML: Automatically fetched via CMake (
v3.0tag)
git clone --recursive https://github.com/Devsoc-BPGC/ElysiumEngine.git
cd ElysiumEngine(If cloned without submodules, run git submodule update --init --recursive)
# Configure Release build
cmake -B build -DCMAKE_BUILD_TYPE=Release
# Build engine, editor app, and dependencies
cmake --build build -j$(nproc)./build/bin/ElysiumAppcmake -B build -DBUILD_TESTING=ON
cmake --build build -j$(nproc)
ctest --test-dir build --output-on-failureTo create a gameplay layer, inherit from Elysium::Layer:
#include <Elysium.hpp>
class GameLayer : public Elysium::Layer {
public:
GameLayer() : Layer("GameLayer") {}
void OnAttach() override {
ELYSIUM_INFO("GameLayer attached!");
}
void OnUpdate(Elysium::Timestep ts) override {
// Run gameplay logic, update timers, move entities
}
void OnImGuiRender() override {
// Optional in-game debug HUD
}
void OnEvent(Elysium::Event& event) override {
// Handle gameplay events
}
};Push the layer in your application: PushLayer(new GameLayer());.
All editor panels inherit from Elysium::EditorPanel:
#include "EditorPanel.hpp"
#include <imgui.h>
namespace Elysium {
class MyCustomPanel : public EditorPanel {
public:
MyCustomPanel() : EditorPanel("Custom Panel") {}
void OnImGuiRender(EditorContext& context, Scene& scene, SimpleRenderer& renderer) override {
if (ImGui::Begin(name.c_str(), &isOpen)) {
ImGui::Text("Hello from custom panel!");
ImGui::Text("Active entities: %zu", scene.objects.size());
}
ImGui::End();
}
};
} // namespace ElysiumRegister it in EditorLayer: AddPanel<MyCustomPanel>();.
Inherit from Component:
#include "Component.hpp"
#include "GameObject.hpp"
class HealthComponent : public Component {
public:
float currentHealth = 100.0f;
float maxHealth = 100.0f;
void Update(float dt) override {
// Regenerate or check health
}
// Required: Play mode copies the scene, components included
std::unique_ptr<Component> Clone() const override {
return std::make_unique<HealthComponent>(*this);
}
};
// Attach to an entity:
auto entity = std::make_shared<GameObject>("Hero");
entity->AddComponent<HealthComponent>();Upcoming milestones as detailed in PLAN.md:
- Scene Serialization: YAML-based
.elyscenescene saving and loading viayaml-cpp. - Renderer2D Batching: Batched quad and circle drawing pipeline utilizing vertex buffers.
- Entity Component System (ECS): Transitioning internal storage to
EnTT. - Scripting Engine: Embedding Lua via
sol2for dynamic runtime gameplay scripting. - Audio Subsystem: Integrating SFML 3.2's spatial audio module, buffer caching, and sound pooling.
- Asset Registry & Cache: 64-bit UUID asset handles, thread-safe memory caching, and manifest serialization (
assets.meta). - Content Browser Panel: Directory tree navigation, thumbnail grid, file watcher, and drag-and-drop integration.
- Project Management & Native Dialogs: Standalone
.elyprojproject files, directory auto-initialization, and OS file/folder pickers.
Elysium Engine is open-source software licensed under the MIT License.