MIT Licensed · C++23 · SDL3

A Simple Game Engine, built to stay out of your way.

ASGE is a modular, lightweight, cross-platform 2D game engine written in modern C++ (C++23) on top of SDL3. Small composable subsystems, an ECS-based gameplay layer, and a growing set of runnable examples — targeting Windows, Linux and macOS.

20runnable examples
C++23modern, header-driven API
3target platforms
SDL3current render backend

Built around four ideas

Performance

Thin abstractions over SDL3, custom allocators, and a thread pool for concurrent work — the engine tries to stay out of your frame budget's way.

Simplicity

Small, composable subsystems instead of one monolithic framework. Pull in what a game needs through the ASGE.hpp umbrella header.

Extensibility

An ECS-based gameplay layer plus a signal/event system (asge::signals::Signal) for decoupling systems from each other.

Tooling

A debug logger, timing/profiling utilities (ScopedTimer), a virtual filesystem, and a growing set of runnable examples.

Repository layout

PathContents
src/ASGE/Engine source — Application, Core, Events, Game, Input, Video, Audio
examples/Small standalone programs demonstrating each subsystem
editor/The Dear ImGui level editor (asge-editor)
tests/GoogleTest unit test suite
docs/roadmap/Design docs and the phased implementation roadmap
docs/level_editor_roadmap/Design docs and phases for the level editor
docsite/This documentation site: generators, content and the Doxygen config
scripts/Dependency-fetching scripts (SDL3, stb, Dear ImGui) for each platform
third-party/Vendored dependencies, fetched by the scripts above
cmake/CMake package config used when ASGE is installed

Roadmap status

ASGE is under active development, worked through a phased roadmap. Tiers are priority order; each system also has its own phase docs for scope/maturity.

Tier 0 — Foundation

Core EngineDonedocs →
Rendering PrimitivesDonedocs →

Tier 1 — MVP-critical

Entity-Component-SystemDonedocs →
Input SystemDonedocs →
Asset PipelineDonedocs →
Scene ManagementDonedocs →

Tier 2 — Makes it feel like a game

PhysicsDonedocs →
AudioDonedocs →
UI FrameworkIn progressdocs →

Tier 3 — Revisit once Tier 1-2 exist

Rendering System (2D camera, compositing)In progressdocs →
Scripting & EventsPlanneddocs →

Tier 4 — Explicitly deferred

NetworkingPlanneddocs →
OptimizationIn progressdocs →
DocumentationIn progressdocs →

Jump into an example

Every example ships with real screenshots and its full embedded source.

Shapes Moving Box Textures Text Rendering Sprite Animation ECS Camera & Viewport Camera Follow All 20 examples →

Minimal game

A Game<TStateId> subclass drives a stack of IGameStates — TStateId is whatever identifies a screen. See Moving Box for the complete, playable version of this.

main.cpp
#include <ASGE/ASGE.hpp>

class MyGameState : public asge::game::state::IGameState<int>
{
public:
    std::optional<asge::game::state::Transition<int>>
    Update(float inDeltaTime, asge::input::InputState const& inInput) override
    {
        // Game logic goes here
        return std::nullopt; // engaged instead: push/pop/replace to another state
    }

    void Render(asge::video::IRenderer& inRenderer) override
    {
        // Draw calls go here
    }

    void OnSystemEvent(asge::event::SystemEvent const& inSysEvent) override
    {
        // Handle window/system events
    }
};

class MyGame : public asge::game::Game<int>
{
public:
    explicit MyGame(asge::video::IRenderer& inRenderer) : Game(inRenderer)
    {
        SetInitialState(0);
    }

protected:
    std::unique_ptr<StateType> CreateState(int inId) override
    {
        return std::make_unique<MyGameState>();
    }
};

int main()
{
    asge::Application<MyGame> app(asge::ApplicationConfig{});
    app.Run();
    return 0;
}