STORM<!>ENGINE

Learn game programming in real C++.

Inspired by Gustavo Pezzi's C++ Game Engine Programming course, Storm! Engine v2 is a small, ECS-based 2D engine on SDL2. Twelve games ship with it: eight in the repo plus four standalone. Own them, change them, break them - that's how you learn real C++. You download it, you own it.

v2.3.0 C++ / SDL2 Linux · Windows · Switch · Android 531 specs FREE
# Native Debian-based Linux package
sudo apt install ./libstormenginev2_2.3.0_amd64.deb

Download Linux, Raspberry PI, or Windows packages from the Releases page.

First look Center Ice Hockey: a top-down pixel-art hockey game, Calgary against Toronto, 13:05 left in the first period, players contesting the puck at centre ice.
Built with Storm! Engine v2, Center Ice Hockey drops late September 2026. Graphics subject to change.

What you are actually learning

Every system is C++ you can read

There is no scripting layer and no editor generating code behind your back. You write C++, you call into SDL2 when you want to, and the engine's own source is there to read when you want to know how a piece works. Everything lives under namespace storm, so it never collides with your own Entity or Logger.

ECS

Composition, not inheritance

An entity is an id; behaviour comes from the components you attach. A std::bitset signature gives 64 component types per binary - the engine spends five of them, leaving 59 for your game. Ids come from one process-wide counter, so the budget is per binary, not per Registry.

Contacts

Boxes and circles

Contact{a, b, normal, depth} with begin and end callbacks, and a pair filter - which is where layers, masks and sensors live. Overlap is strict: a shared edge is not a contact.

Input

One action, four devices

Bind a game action across keyboard, gamepad, virtual gamepad and touch at once, and get one edge per action rather than four. Added in 2.0.0.

Learn from a game that plays, not a hello world

Every subsystem is demonstrated by something you can actually play. The platformer teaches tilemap loading, tile-based physics and a scrolling camera. 1945 teaches a three-state stack, high entity churn and controller input. Realms teaches a pushed state - a side-on battle runs over a campaign map that is still alive underneath it.

Realms, a Dragon Force-style campaign map with generals marching between castles.

LAN play that ships in the box

UDP host and join with reliable and unreliable chunks, kick, ban and timeout, and snapshot replication with per-client deltas and a prediction cache. Three networking demos come with it: netchat, netrepl and a playable netplay-checkers.

1945, a vertically scrolling shoot-'em-up with HUD and score display.

Paint a map, load it, done

A built-in tile map editor with drag-to-paint, drag-to-erase and layer support. Maps save as .map and the loader auto-detects the format, so there is no export step between painting a level and running it.

The platformer example, showing a tilemap level with a scrolling camera.

Take one piece at a time

The collision math needs none of the engine

You do not have to adopt an architecture to get started. <stormengine2/collision/shapes.h> includes glm and nothing else, so a program with no Registry, no entities and no components can still use it. Adopting the ECS is a choice about the broadphase, not a precondition for the geometry.

#include <stormengine2/collision/shapes.h>
using namespace storm;

ContactCircle puck{x, y, 3.0f};
ContactAABB   post{px0, py0, px1, py1};

glm::vec2 normal;
float depth;
if (Manifold(puck, post, normal, depth)) {
  // normal runs from the puck INTO the post; depth is how far they overlap.
  // Applying MinimumTranslation(normal, depth) to the POST separates them --
  // or negate it and apply it to the puck.
}

Boxes and circles are supported in every combination. Circles matter for anything round - a puck kept off the boards by its edge, characters pushed apart by a separation radius, a shot glancing off a post. A circle against a box corner produces a diagonal normal; approximating it with a box would snap that to an axis and change how the game feels.


Worked examples

Twelve games to own

Twelve games to own, build, run and take apart. Eight ship in the repo; four live as standalone repos against the same public API, with no engine forks and no private headers, so anything you see in an example you can do in your own project. Start with the platformer, then read the one closest to the game you want to make.


Get started

Install it, or build it

Prebuilt packages

Every release attaches Debian packages for amd64 and arm64 - including Raspberry Pi 4 and 5 on a 64-bit OS - and a Windows SDK zip.

Download latest release

Debian / Ubuntu / Mint

sudo apt install ./libstormenginev2_2.3.0_amd64.deb

Windows (x64, MinGW-w64)

unzip stormengine2-2.3.0-win64.zip

No installer. Unzip it, build with -Iinclude -Llib -lstormenginev2, and copy bin\ beside your .exe. MSVC is not supported — the ABI is GCC's.

Browse all releases →

Build from source

SDL2 and its extensions, glm, tinyxml2 and GTK for the editor.

sudo apt update && sudo apt install -y \
    libsdl2-dev libsdl2-image-dev \
    libsdl2-ttf-dev libsdl2-mixer-dev \
    libglm-dev libtinyxml2-dev libgtk-3-dev

Platforms

Linux - amd64 and arm64, prebuilt .deb Windows - MinGW-w64 cross-build from Linux Nintendo Switch - source builds, devkitPro Android - source builds via the NDK iOS - possible via the same SDL layer

Windows is cross-compiled from Linux with mingw-w64 - no Windows toolchain needed, and SDL2 is built from the same vendored sources the Android build uses, so nothing is downloaded. The library, the spec suite and seven of the examples cross-build today, and every release attaches a Windows SDK zip. A native toolchain that runs in cmd or PowerShell is not supported - the import library and the C++ ABI are GCC's, so MSVC cannot link it. WSL2 runs the plain Linux build.

Support the engine

Storm! Engine v2 is free under the WTFPL and always will be. If it taught you something, a coffee helps keep the examples growing.

Donate on Ko-fi

Coming from 1.2.x?

v2.0.0 resets the 1.x API freeze: ten breaking changes land together so the traps they fix are gone for good rather than arriving one per release. It is a rebuild, not a relink - four structs changed size, and MAX_COMPONENTS changed meaning without changing size at all. Read the upgrade guide →