This page walks you through everything you need to get MiniECS running on your machine. By the end you will have cloned the repository, compiled the project with CMake, and executed a working scene that creates aDocumentation 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.
World, attaches a TransformModule and a RendererModule to a Unit, sets a 2D position, and starts the main loop — all in about five minutes.
Install Prerequisites
Before you build MiniECS you need three things on your system:On Ubuntu / Debian:
- C++20 compiler — GCC 10+, Clang 10+, or MSVC 19.29+ all work.
- CMake ≥ 3.30 — the
CMakeLists.txtsetscmake_minimum_required(VERSION 3.30). - GLM — the header-only OpenGL Mathematics library. GLM is used by
TransformModulefor itsglm::vec2position, rotation, and scale fields.
TransformModule.h hardcodes the GLM include path as /opt/homebrew/include/glm/glm.hpp (the default Homebrew location on Apple Silicon). If GLM is installed elsewhere on your system you will need to update that path before building. See the Building page for details.Clone the Repository
Clone MiniECS from GitHub and enter the project directory:The repository root contains the
CMakeLists.txt and a src/ directory with all source files. There are no submodules or external dependencies to fetch beyond GLM.Configure with CMake
Run CMake from the project root to generate the build files:CMake reads
CMakeLists.txt, sets the C++ standard to C++20, and produces a Makefile (or the equivalent for your platform’s default generator) in the current directory. You should see output ending with -- Build files have been written to: .../MiniECS.Build the Project
Compile the project with:This compiles all sources listed in
CMakeLists.txt — main.cpp, the Module, Unit, World, RendererModule, and TransformModule translation units — and links them into the MiniECS executable.Run the Executable
Execute the compiled binary:You will see the following lines printed during startup, then the program enters its infinite game loop repeating the last two lines every ~16 ms (press Ctrl-C to stop):Each line maps directly to a lifecycle event: the
Unit constructor fires first, then the Module base constructor logs each attachment as it is pushed onto the module vector. Once World::play() is called it enters a while(true) loop — invoking callModuleStart() on every unit, which calls start() on each module, then sleeping 16 ms before the next iteration.Understand the Example Code
The complete Key points to notice:
src/main.cpp that produced the output above is shown here with inline comments explaining each step:World::createUnitconstructs aUnitwith the given name and takes ownership viaunique_ptr.addModule(ModuleType::Renderer)andaddModule(ModuleType::Transform)each instantiate the corresponding subclass and push it into the unit’s module vector. TheModulebase constructor prints"Added <TypeName>"for each.getModule<TransformModule>()is the type-safe template accessor. It walks the module vector and returns a raw pointer cast toTransformModule*, ornullptr(and logs tostd::cerr) if the module has not been added.- Setting
position = {22.5f, 33.4f}assigns aglm::vec2aggregate.rotationandscaleremain zero-initialised. play()enters awhile(true)loop. It callscallModuleStart()on each unit, which invokes the virtualstart()on every attached module, then sleeps for 16 ms. The loop runs forever — stop the program with Ctrl-C.
Modifying the Example
Now that the project builds, opensrc/main.cpp and experiment. A few things to try:
make after each change and observe how the console output shifts. Because the framework is small, every std::cout and std::cerr call in the source maps directly to a visible output line — making it straightforward to trace execution flow.