Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/raoulkdev/MiniECS/llms.txt

Use this file to discover all available pages before exploring further.

MiniECS is a lightweight C++ framework that brings the Entity-Component-System (ECS) architectural pattern down to its essentials. Rather than abstracting away the mechanics behind a large engine, MiniECS exposes them clearly so that developers learning game architecture — or anyone prototyping a simulation system — can read, understand, and extend every part of the codebase. If you have ever wondered how Unity organises GameObjects and Components under the hood, MiniECS gives you a working, minimal answer written in modern C++20.

Core Concepts

MiniECS is built around three primitives that map directly to the classic ECS pattern and will feel immediately familiar to anyone with Unity experience.

World

MiniECS::World is the top-level scene container. It owns a collection of Unit objects through std::unique_ptr, manages their lifetimes, and drives the main game loop when you call play(). Every simulation starts by constructing a World.
MiniECS::World scene("Scene");
scene.play(); // starts the infinite game loop (~60 fps via 16 ms sleep)
Key methods on World:
MethodDescription
createUnit(name)Allocates and registers a new Unit by name.
getUnitByName(name)Returns a reference to the unique_ptr<Unit> with that name.
getUnitByIndex(index)Returns a Unit by its position in the internal vector.
removeUnitByName(name)Destroys and removes the named Unit.
removeUnitByIndex(index)Destroys and removes the Unit at the given index.
getUnitsVector()Returns a const reference to all units, useful for iteration.
play()Enters an infinite while(true) loop, calling callModuleStart() on each unit every frame and sleeping 16 ms between iterations.

Unit

MiniECS::Unit is the entity — the direct equivalent of a Unity GameObject. A Unit has a name and owns a vector of Module pointers. On its own a Unit does nothing; behaviour is added by attaching Module instances.
scene.createUnit("u1");
scene.getUnitByName("u1")->addModule(MiniECS::ModuleType::Renderer);
scene.getUnitByName("u1")->addModule(MiniECS::ModuleType::Transform);
Key methods on Unit:
MethodDescription
addModule(ModuleType)Constructs and attaches the module of the given type. Prevents duplicate module types.
removeModule(ModuleType)Detaches and destroys the module of the given type.
getModule<T>()Type-safe template that returns a T* via dynamic_cast, prints to std::cerr and returns nullptr on a miss.
callModuleStart()Calls the virtual start() on every attached module (invoked each frame by World::play()).
getName()Returns the unit’s string name.
getModulesVector()Returns a reference to the internal modules vector.

Module

MiniECS::Module is the base class for all components. It carries a ModuleType enum value and a string name, and exposes a virtual start() method that subclasses override to implement per-frame behaviour. Two concrete modules ship with MiniECS:
  • TransformModule — holds glm::vec2 fields for position, rotation, and scale. Its start() override prints the current transform values to stdout each frame.
  • RendererModule — a minimal renderer stub whose start() override prints Start / Started rendering... to stdout each frame.
You extend MiniECS by inheriting from Module, overriding start(), adding a value to the ModuleType enum, and registering the new type in the factory inside Unit::addModule.
// Module type enum (Module.h)
enum class ModuleType {
    ModuleBase = 0,
    Transform  = 1,
    Renderer   = 2
};
Key methods on Module:
MethodDescription
start()Virtual lifecycle method called every frame by callModuleStart(). Override in subclasses to add behaviour.
getType()Returns the ModuleType enum value for this module instance.
getTypeName()Returns the string name of the module type (e.g., "Transform", "Renderer").

Unity-Inspired Metaphor

Unity conceptMiniECS equivalent
SceneMiniECS::World
GameObjectMiniECS::Unit
ComponentMiniECS::Module
AddComponent<T>()Unit::addModule(ModuleType)
GetComponent<T>()Unit::getModule<T>()
Start() / game loopWorld::play()Unit::callModuleStart()Module::start()
The analogy is intentional. MiniECS lets you build intuition for how Unity works internally without the noise of a production engine.

Key Features

Minimal, Readable Codebase

Every class is small enough to read in a single sitting. The entire framework fits in a handful of headers and source files, making it ideal for study and experimentation.

Composable Modules

Attach any combination of modules to a unit at runtime using addModule. Modules are stored as unique_ptr<Module> so ownership is always clear and memory is automatically managed. Duplicate module types are rejected automatically.

Type-Safe getModule<T>()

Retrieve any attached module by its concrete C++ type using getModule<T>(). The template uses dynamic_cast internally and returns nullptr on a miss rather than causing undefined behaviour.

Infinite Game Loop at ~60 fps

World::play() enters a while(true) loop that calls callModuleStart() on every unit and then sleeps for 16 ms, approximating a 60 fps tick rate and giving you a realistic entry point for per-frame logic.

Extensible via Custom Modules

Add new behaviour by inheriting from Module, overriding start(), and registering your type in the ModuleType enum. No other framework internals need to change.

C++20 + CMake

Built with CMAKE_CXX_STANDARD 20 and a single CMakeLists.txt requiring CMake 3.30. No build system magic — just cmake . and make.

GLM Math Library

TransformModule uses the industry-standard GLM header-only math library for glm::vec2 position, rotation, and scale — the same library used by OpenGL and Vulkan applications.

MIT Licensed

MiniECS is released under the MIT License. Read it, fork it, extend it, and use it as a reference or starting point for your own projects.
MiniECS is built for learning and prototyping, not production game engines. It deliberately omits advanced ECS features such as archetype-based storage, sparse sets, and multi-threaded scheduling so that the core pattern remains easy to follow.

What’s Next

Quickstart

Clone the repo, build with CMake, and run your first MiniECS scene in under five minutes.

Building

Detailed CMake configuration guide, GLM path setup, and IDE integration instructions.

Build docs developers (and LLMs) love