How I version my games

Happy Plight uses Semantic Versioning with one twist: the minor number is reserved for gameplay. Here's what MAJOR.MINOR.PATCH means on my patch notes.

Every build I ship carries a version number like 2.4.1. It isn’t decoration, it’s a promise about what changed. I follow Semantic Versioning (SemVer), the same scheme most software uses, with one deliberate twist for games: the minor number is reserved for gameplay.

The short version

A version is three numbers, MAJOR.MINOR.PATCH. Read left to right, each one answers a bigger question about whether your muscle memory, your save file, and your strategies still hold up:

PartI bump it when…For you, that means
MAJOR X.0.0I break compatibility, so save formats, mods, or the core contract of the game change.Back up your saves. Old habits (and old mods) may not carry over.
MINOR 2.X.0Anything about gameplay changes, like new mechanics, tuning, balance, enemy behaviour, or level design.The game plays differently. Worth reading the notes.
PATCH 2.4.XI ship fixes or additions that don’t touch gameplay, like bug fixes, performance, UI polish, new cosmetics, or localization.Same game, running better. Update and carry on.

Why I moved MINOR onto gameplay

Classic SemVer talks about a “public API”: MAJOR for incompatible API changes, MINOR for backward-compatible new features, PATCH for backward-compatible bug fixes. Games have an API too, and it’s made of controls, systems, and the way the thing feels to play. The contract I care about isn’t a function signature, it’s how the game plays.

So I translate SemVer’s three questions into a player’s three questions:

  • Will my saves and setup still work? → MAJOR
  • Will the game play differently? → MINOR
  • Is this just better, not different? → PATCH

The important reframe is the middle one. In plain SemVer, a new feature is a minor bump as long as it’s backward compatible. For me, “new feature” isn’t the deciding factor. What matters is whether it changes how you play, and that’s why a feature can legitimately land in a point release.

Features can ship in a point release

This surprises people, so I’ll say it plainly: a new feature is allowed in a PATCH release, as long as it doesn’t change gameplay. A photo mode, a new hat, an extra language, a colour-blind palette, a rebindable key, a settings toggle: none of these change what happens when you play, so they ride along in a point release.

The moment a feature reaches into gameplay, whether it alters balance, adds a mechanic, changes what the enemies do, or retunes a level, it’s a MINOR bump, no matter how small it looks in the code.

Some quick calls the way I make them:

  • New cosmetic skins and emotes → PATCH (they don’t change play).
  • A new weapon or ability → MINOR (it changes play).
  • Fixing a weapon that dealt the wrong damage → MINOR if the intended balance shifts as a result, or PATCH if it was simply doing the wrong thing and now does what the notes always said.
  • Frame-rate and load-time improvements → PATCH.
  • Re-tuning enemy aggression because the game was too easy → MINOR.
  • A save format change, or removing content people relied on → MAJOR.

The rules I actually follow

Straight from the SemVer spec, lightly translated:

  1. Versions are X.Y.Z, non-negative integers, no leading zeroes. Once a version is released its contents never change, and a fix means a new number.
  2. PATCH (Z) is for backward-compatible changes that don’t alter gameplay: bug fixes, performance, polish, and features that leave play untouched.
  3. MINOR (Y) is for anything that changes gameplay. When Y goes up, Z resets to 0.
  4. MAJOR (X) is for backward-incompatible changes, like saves, mods, or fundamentals. When X goes up, Y and Z reset to 0.
  5. While a game is still in early development I use major version zero (0.y.z): anything can change at any time, and I don’t make stability promises yet. 1.0.0 is the launch build, the first version whose feel I commit to.
  6. Test builds get a pre-release tag on the end, like 1.4.0-beta.2. A pre-release always sorts before the final 1.4.0.

That’s the whole system. If you only remember one thing: the middle number is the gameplay number. When it moves, the game moved with it.