Skip to content

RexarX/HeliosEngine

Repository files navigation

C++23 MIT License

Format Check Linux GCC Linux Clang Windows MSVC macOS Clang


Helios Engine Logo

Helios Engine

A modern, ECS based modular game engine framework built with C++23
Get Started »

Features Architecture Usage Examples Contact


Table of Contents


About The Project

Helios Engine is a modern, high-performance game engine framework written in C++23 that embraces data-oriented design principles. Inspired by Bevy, it features a powerful Entity Component System (ECS) architecture that enables efficient, scalable game development.

Key Features

  • ECS Architecture - Archetype-based design built from scratch for C++23
  • High Performance - Data-oriented design with cache-friendly memory layouts
  • Parallel Execution - Multi-threaded system scheduling with automatic dependency resolution
  • Event System - Type-safe, efficient event handling with readers/writers
  • Query System - Powerful component queries with filters and optional components
  • Resource Management - Global resources accessible from any system
  • Modern C++23 - Leverages coroutines, concepts, and ranges
  • Modular Design - Build only what you need (Core, Renderer, Runtime)
  • Flexible Dependencies - Conan, system packages, or automatic download via CPM

Design Philosophy

Helios Engine is built on three core principles:

  1. Data-Oriented Design: Components are stored in contiguous memory (archetypes) for optimal cache performance
  2. Composability: Entities are composed of components, behavior emerges from systems
  3. Explicitness: System dependencies and data access patterns are declared explicitly

↑ Back to Top


Architecture

Entity Component System (ECS)

Helios uses an archetype-based ECS, similar to Bevy:

Entities

  • Unique identifiers (UUID-based)
  • Lightweight containers for components
  • Efficient creation, deletion, and querying

Components

  • Plain data structures
  • Stored contiguously in memory by archetype
  • No inheritance required
struct Transform {
  float x = 0.0F;
  float y = 0.0F;
  float z = 0.0F;
  float rotation = 0.0F;
};

struct Velocity {
  float dx = 0.0F;
  float dy = 0.0F;
  float dz = 0.0F;
};

struct Health {
  int max_health = 100;
  int current_health = 100;

  bool IsDead() const noexcept { return current_health <= 0; }
};

Systems

  • Classes that operate on entities with specific components
  • Declare data access patterns at compile-time via GetAccessPolicy()
  • Automatically parallelized based on data dependencies
  • Access all data through SystemContext

World

  • Central container for all entities and components
  • Manages component storage and archetype transitions
  • Provides query interface and entity operations

Scheduling

  • Systems are organized into schedules (Main, PreUpdate, Update, PostUpdate, etc.)
  • Automatic parallelization based on declared data access
  • Conflict detection ensures data race freedom
  • Custom schedules supported

Modular Design

The engine is divided into independent modules that can be enabled or disabled:

Module Description Status Documentation
Core ECS, async runtime, event system, utilities Complete Core Module

Each module can be individually enabled or disabled via CMake options:

# Enable/disable specific modules
cmake -DHELIOS_BUILD_WINDOW_MODULE=ON -DHELIOS_BUILD_AUDIO_MODULE=OFF ..

# Build only core (no modules)
python scripts/build.py --core-only

Creating Custom Modules

Helios Engine provides a streamlined system for creating custom modules. Each module:

  • Has its own build option (HELIOS_BUILD_{NAME}_MODULE)
  • Can depend on other modules or external libraries
  • Follows a standardized directory structure
  • Integrates automatically with the build system

Quick Example:

# src/modules/my_module/CMakeLists.txt
helios_define_module(
    NAME my_module
    DESCRIPTION "My custom module"
    SOURCES src/my_module.cpp
    HEADERS include/helios/my_module/my_module.hpp
)

Full Module Creation Guide - Comprehensive documentation on creating custom modules, including:

  • Directory structure and conventions
  • CMake function reference (helios_register_module, helios_add_module, helios_define_module)
  • Module dependencies and build options
  • Best practices and examples

↑ Back to Top


Getting Started

Requirements

Tool Minimum Version Recommended
CMake 3.25+ 3.28+
C++ Compiler GCC 14+, Clang 19+, MSVC 2022+ GCC 15+, Clang 21+
Python 3.8+ 3.10+

Compiler Support:

  • GCC 14+ (tested on 14.2.0)
  • Clang 19+ (tested on 20.1.8)
  • MSVC 19.34+ (Visual Studio 2022 17.4+)

Dependencies

Core Dependencies

  • Boost (1.87+) - stacktrace, pool, unordered containers
  • spdlog (1.12+) - Fast logging
  • stduuid (1.2+) - UUID generation
  • Taskflow (3.10+) - Parallel task programming

Test Dependencies

  • doctest (2.4+) - Testing framework

Installation Methods

Option 1: Conan (Recommended)

# Quick install with automatic Conan setup
make install-deps

# Or manually with Python script
python scripts/install-deps.py

Option 2: System Packages

# Arch Linux
sudo pacman -S boost intel-tbb spdlog

# Ubuntu/Debian (22.04+)
sudo apt install libboost-all-dev libtbb-dev libspdlog-dev

# Fedora
sudo dnf install boost-devel tbb-devel spdlog-devel

# macOS
brew install boost tbb spdlog

Option 3: CPM (Automatic Fallback)

  • Dependencies are automatically downloaded if not found
  • No manual intervention required

Quick Start

1. Clone the Repository

git clone --recursive https://github.com/RexarX/HeliosEngine.git
cd HeliosEngine

2. Install Dependencies

# Interactive installation (asks about Conan)
make install-deps

# Or directly with Python
python scripts/install_deps.py

3. Configure the Project

# Interactive configuration
python scripts/configure.py

# Or non-interactive with specific options
python scripts/configure.py --type Release --compiler gcc --use-conan

4. Build the Project

# Build (calls configure.py first if needed)
make build

# Or directly with Python
python scripts/build.py

# Specific build configurations
python scripts/build.py --type Debug --core-only --tests

5. Run Tests

# Run tests
make test BUILD_TYPE={debug,relwithdebinfo,release}

# Or run specific test manually with ctest
cd build/debug/linux  # or your platform
ctest -L core

Build Options

Using Makefile (Recommended)

# Install dependencies
make install-deps

# Configure and build
make build

# Or configure separately
make configure
make build

# Clean and rebuild
make clean build

Using Python Scripts Directly

# 1. Install dependencies (interactive)
python scripts/install_deps.py

# 2. Configure CMake (interactive)
python scripts/configure.py

# 3. Build the project
python scripts/build.py

# Or with specific options (non-interactive)
python scripts/install_deps.py --use-conan --no-interactive
python scripts/configure.py --type Release --compiler gcc --use-conan --no-interactive
python scripts/build.py --type Release --jobs 8

Using CMake Presets

# List available presets
cmake --list-presets

# Configure with preset
cmake --preset linux-gcc-debug

# Build
cmake --build --preset linux-gcc-debug

# Test
ctest --preset linux-gcc-debug

Available Presets:

  • linux-gcc-debug / linux-gcc-release / linux-gcc-relwithdebinfo
  • linux-clang-debug / linux-clang-release / linux-clang-relwithdebinfo
  • windows-msvc-debug / windows-msvc-release / windows-msvc-relwithdebinfo
  • macos-clang-debug / macos-clang-release / macos-clang-relwithdebinfo
  • dev - Development preset with all features
  • ci-* - CI presets with strict warnings

↑ Back to Top


Usage Examples

Basic Application Setup

#include <helios/core/app/app.hpp>
#include <helios/core/app/module.hpp>

using namespace helios::app;
using namespace helios::ecs;

// Define a simple system
struct TimeUpdateSystem final : public System {
  static constexpr std::string_view GetName() noexcept {
    return "TimeUpdateSystem";
  }

  static constexpr auto GetAccessPolicy() noexcept {
    return AccessPolicy().WriteResources<GameTime>();
  }

  void Update(SystemContext& ctx) override {
    auto& time = ctx.WriteResource<GameTime>();
    time.delta_time = 0.016F;
    time.total_time += time.delta_time;
    ++time.frame_count;
  }
};

int main() {
  App app;

  // Insert resources
  app.InsertResource(GameTime{});

  // Add systems to schedules
  app.AddSystem<TimeUpdateSystem>(kMain);

  // Run the application
  return std::to_underlying(app.Run());
}

Creating Entities

Systems can create entities through SystemContext:

struct SetupSystem final : public System {
  static constexpr std::string_view GetName() noexcept {
    return "SetupSystem";
  }

  static constexpr AccessPolicy GetAccessPolicy() noexcept {
    return {};
  }

  void Update(SystemContext& ctx) override {
    // Reserve an entity and get its command buffer
    auto entity_cmd = ctx.EntityCommands(ctx.ReserveEntity());

    // Add components to the entity
    entity_cmd.AddComponents(
        Transform{0.0F, 0.0F, 0.0F},
        Velocity{1.0F, 0.0F, 0.0F},
        Health{100, 100});
  }

Querying Entities

Systems query entities using ctx.Query():

struct MovementSystem final : public System {
  static constexpr std::string_view GetName() noexcept {
    return "MovementSystem";
  }

  static constexpr auto GetAccessPolicy() noexcept {
    return AccessPolicy().Query<Transform&, const Velocity&>().ReadResources<GameTime>();
  }

  void Update(SystemContext& ctx) override {
    const auto& time = ctx.ReadResource<GameTime>();
    auto query = ctx.Query().Get<Transform&, const Velocity&>();

    query.ForEach([&time](Transform& transform, const Velocity& velocity) {
      transform.x += velocity.dx * time.delta_time;
      transform.y += velocity.dy * time.delta_time;
      transform.z += velocity.dz * time.delta_time;
    });
  }

Using Modules

Organize systems and resources into reusable modules:

struct GameModule final : public Module {
  void Build(App& app) override {
    app.InsertResource(GameTime{})
        .InsertResource(GameStats{})
        .AddSystem<TimeUpdateSystem>(kMain)
        .AddSystem<MovementSystem>(kUpdate)
        .AddSystem<RenderSystem>(kPostUpdate);
  }

  void Destroy(App& app) override {}

  static constexpr std::string_view GetName() noexcept {
    return "GameModule";
  }
};

// Use the module
App app;
app.AddModule<GameModule>();

↑ Back to Top


Core Module

Overview

See the Core Module Documentation for details.

↑ Back to Top


Roadmap

Completed

  • Core ECS implementation (archetype-based)
  • System scheduling with automatic parallelization
  • Event system with readers/writers
  • Resource management
  • Query system with filters and optional components
  • Command buffers
  • Comprehensive test suite
  • Cross-platform build system (Linux, Windows, macOS)
  • Flexible dependency management (Conan, system, CPM)
  • Python build scripts with full automation

In Progress

Runtime modules

  • Actual engine implementation (scenes, assets, scripting, etc.)

Renderer modules

  • Modern graphics API abstraction
  • DiligentEngine integration for cross-platform rendering

↑ Back to Top


Acknowledgments

This project was inspired by and builds upon ideas from:

  • Bevy Engine - ECS architecture and design philosophy
  • EnTT - High-performance ECS implementation
  • Taskflow - Modern parallel task programming
  • DiligentEngine - Cross-platform graphics engine

↑ Back to Top


License

Distributed under the MIT License. See LICENSE for more information.

↑ Back to Top


Contact

RexarX - who727cares@gmail.com

Project Link: https://github.com/RexarX/HeliosEngine

↑ Back to Top

About

A modern, ECS based modular game engine framework built with C++23

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •