v2.0.0
If you're reading this, the release is out: the .deb and the source tag are both up.
This is the release where we fix the bugs we couldn't fix before.
Storm! Engine v2 has kept a promise since 1.0: a game that built against one 1.x version keeps building against every later one. That promise protected you, but it also meant a handful of real bugs had to stay. Fixing them meant changing the things your game is compiled against, and we weren't going to do that inside 1.x.
2.0.0 is where that promise resets - once, deliberately, all at the same time. Ten breaking changes land together, so the traps they fix are gone for good rather than arriving one per release for the next two years.
You will need to rebuild your game. Not relink - rebuild. More on that at the end.
What's fixed that couldn't be before
Old entity handles can't damage your game any more. This is the big one. The engine reuses entity slots when things die, so a handle you kept to a bullet that already exploded could quietly end up pointing at whatever took its place - a pickup, an enemy, the player. Killing that "bullet" destroyed something else. Reading its position gave you someone else's. It was silent, it was rare, and it was miserable to track down. Entities now carry a generation stamp, so the engine can tell a dead handle from a live one and refuses to act on it.
A system that ran on your whole world now runs on nothing. If your game declared more component types than the engine could track, the system that asked for the type it couldn't fit ended up matching every entity instead of none - so a system meant for, say, projectiles quietly started processing the entire game world. Now it switches itself off instead. Failing quietly in the harmless direction is a much better place to be.
The tile editor's animation settings finally do something. The editor has always let you set up animated tiles, and always written that into your .map files. The engine then read those settings and threw them away, because there was nowhere to put them - so your animated water rendered as a still frame and nobody could work out why. Now it reaches your game. While fixing it we found the collider offset was being discarded the same way, which means a collider you nudged in the editor was colliding from where it used to be.
Twice as many component types. The limit went from 32 to 64. If you'd been rationing them, stop.
Copying the wrong thing no longer corrupts memory. Two engine types - the networking objects and the game state machine - could be copied by accident, and copying either gave you two objects that both thought they owned the same memory. Now they refuse to be copied, and your compiler tells you at build time instead of your game crashing at 2am.
What's new
One binding for every input device. Four different input sources ship with the engine - keyboard, controller, on-screen gamepad, touch - and until now, supporting all four meant writing this in every state, for every action:
if (keyboard.WasPressed(SDL_SCANCODE_SPACE) ||
gamepad.Pressed(GamepadButton::A) || vpad.a || touch.jump) Jump();Now you describe the action once:
ActionBinding jump;
jump.key = SDL_SCANCODE_SPACE;
jump.pad = GamepadButton::A;
jump.vpad = VPadControl::A;
jump.touch = TouchControl::Jump;
actions.Bind(Action::Jump, jump);
if (actions.WasPressed(Action::Jump)) Jump();Every source is optional, so your desktop build and your phone build share one binding table and differ only in what they hand it.
A keyboard that doesn't lose your input. Also new: a proper keyboard wrapper with press and release detection. It's fed the events you already read rather than polling for its own, because the engine deliberately owns no main loop - and two things polling one event queue is exactly how input goes missing.
The engine tells you when you've made one of its classic mistakes. Adding a component after the engine has already sorted your entity into systems. Registering a system after the entities it wanted already exist. A sprite whose source rectangle falls off its texture. These were all silent before - your game just quietly didn't do the thing. They're now reported in your log, a handful of times each so they can't spam you. If you see one, it's a real bug, not a warning to suppress.
Everything is in a namespace now
Every engine type moved into namespace storm. If your game declared its own Entity or Logger, it no longer collides with ours.
For an existing game this is the one change that touches every file - so it ships with a bridge that means you don't have to. Add one line to your build:
CXXFLAGS += -include stormengine2/compat/global.hand every engine name works exactly as before. That header exists to be deleted: use it to get building again, then drop it when you're ready and add using namespace storm; instead. A future release removes it.
About rebuilding
Four of the engine's structures changed size, and one internal limit changed meaning without changing any size at all. That last one is the dangerous kind: nothing in your build - not the compiler, not the linker - can detect a file still compiled against the old value. It links cleanly and then misbehaves.
So: rebuild the library, the editor, and every game against the same headers, in one go. Don't drop the new .so under a game you built yesterday.
docs/UPGRADING.md walks through all ten changes with the code to change.
One more thing
Before tagging this we ran an adversarial review over the whole release - not "does this look right", but "prove this claim is false". It found real bugs in four of the five things it was pointed at, including one where the code was fine but the test was the problem: a check had been passing for years while covering nothing, and we'd read that as evidence the code was correct.
Three of those turned out to share a shape. A test that couldn't fail. A spec that only checked the names we happened to remember. A build that passing proved only that the code parsed. Each time, we'd written the conclusion down somewhere permanent, where it read like a decision rather than an assumption.
All of it is fixed, and the checks that couldn't fail have been replaced with ones that can - generated from the engine itself rather than from anyone's memory of it. The details are in docs/ROADMAP.md if you want them.
Installation
Debian / Ubuntu / Linux Mint (amd64)
sudo dpkg -i libstormenginev2_2.0.0_amd64.debRaspberry Pi 4/5 with 64-bit OS (arm64)
sudo dpkg -i libstormenginev2_2.0.0_arm64.debAfter installing, link with -lstormenginev2.
Upgrading from 1.x: docs/UPGRADING.md walks through all ten breaking changes with the code to change. The namespace break - the one that touches every file - is a single line in your build.
Full detail: CHANGELOG.md · Still open: KNOWN_ISSUES.md