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::Module is the base class for all behaviour components in MiniECS. Every piece of per-frame logic — rendering, physics, gameplay — is expressed as a Module subclass attached to a Unit. This maps directly to the Unity Component model: just as you add a Rigidbody or MeshRenderer component to a GameObject, you add a TransformModule or RendererModule to a Unit. The key entry point is the virtual start() method, which the World’s game loop calls once per tick on every attached Module.

Class Overview

namespace MiniECS
{
    enum class ModuleType
    {
        ModuleBase = 0,
        Transform  = 1,
        Renderer   = 2
    };

    class Module
    {
    public:
        Module(const ModuleType setType);
        virtual ~Module();

        virtual void start();

        std::string  getTypeName();
        ModuleType   getType();

    private:
        ModuleType  type;
        std::string moduleTypeName;
    };
}
Every Module stores two identifying values: a ModuleType enum entry and a human-readable moduleTypeName string. Both are set in the constructor based on the setType argument, using a switch statement that maps enum values to strings ("ModuleBase", "Transform", "Renderer").

Constructor

Module(const ModuleType setType);
The constructor accepts a ModuleType enum value. It assigns type, derives moduleTypeName from a switch, and prints "Added <typeName>" to stdout. You do not call this constructor directly — Unit::addModule() calls it when constructing a concrete subclass.
// Internally, Unit::addModule does this for Transform:
modules.push_back(std::make_unique<TransformModule>(ModuleType::Transform));
// This prints: "Added Transform"
The destructor prints "Removed <typeName>" to stdout when the Module is destroyed (e.g. when removeModule() is called or the owning Unit is destroyed).

Key Methods

start()

virtual void start();
The primary override point. Called by Unit::callModuleStart() once per frame tick during the game loop. The base implementation prints "Start / Start module\n" to stdout. Override it in a subclass to provide real behaviour.

getType()

ModuleType getType();
Returns the ModuleType enum value stored in this Module. Used by Unit::addModule() to detect duplicates and by Unit::removeModule() to locate the correct entry for erasure.

getTypeName()

std::string getTypeName();
Returns the human-readable string derived from ModuleType — for example "Transform" or "Renderer". Useful for logging and debugging.

Extending Module

To create a custom Module, subclass Module, inherit its constructor with using Module::Module;, and override start().
#include "modules/module_base/Module.h"
#include <iostream>

namespace MiniECS
{
    class PhysicsModule : public Module
    {
    public:
        using Module::Module; // inherit Module(const ModuleType setType)

        void start() override
        {
            std::cout << "Physics tick\n";
        }
    };
}
1

Add an enum value

Add your type to the ModuleType enum in Module.h:
enum class ModuleType
{
    ModuleBase = 0,
    Transform  = 1,
    Renderer   = 2,
    Physics    = 3   // new entry
};
2

Update the constructor switch

Add a case in Module.cpp so the constructor sets the correct moduleTypeName:
case ModuleType::Physics:
    moduleTypeName = "Physics";
    break;
3

Add a case to Unit::addModule()

Register the new concrete class in the switch inside Unit.cpp:
case ModuleType::Physics:
    modules.push_back(std::make_unique<PhysicsModule>(ModuleType::Physics));
    break;
4

Override start()

Implement your per-frame logic in the start() override of your new class.
Because Unit::getModule<T>() uses dynamic_cast, you can retrieve your custom Module by its concrete type without touching any other part of the framework:
auto* physics = unit->getModule<MiniECS::PhysicsModule>();

Built-in Derived Classes

MiniECS ships with two concrete Module implementations.

TransformModule

Stores GLM vec2 fields for position, rotation, and scale. Its start() override prints the current transform state to stdout every frame.
namespace MiniECS
{
    class TransformModule : public Module
    {
    public:
        using Module::Module;

        glm::vec2 position;
        glm::vec2 rotation;
        glm::vec2 scale;

        void start() override;
    };
}
// start() output each frame:
// "Update / Transform -> Position: 22.5, 33.4, Rotation: 0, 0, Scale: 0, 0"
void MiniECS::TransformModule::start()
{
    std::cout << "Update / Transform -> Position: " <<
        position.x << ", " << position.y <<
        ", Rotation: " << rotation.x << ", " << rotation.y <<
        ", Scale: " << scale.x << ", " << scale.y << "\n";
}

RendererModule

A minimal rendering stub whose start() override prints "Start / Started rendering..." each frame.
namespace MiniECS
{
    class RendererModule : public Module
    {
    public:
        using Module::Module;

        void start() override;
    };
}
void MiniECS::RendererModule::start()
{
    std::cout << "Start / Started rendering...\n";
}

Further Reading

Custom Module Guide

Full walkthrough of creating, registering, and using a custom Module type.

TransformModule

Position, rotation, and scale fields plus per-frame state output.

RendererModule

Built-in rendering stub and how to extend it.

Build docs developers (and LLMs) love