A practical versioning scheme for game development
1.3.7.42
majorminorpatchbuild
Major Minor Patch Build (not recommended)
Ma
Major
New save file recommended
A major version bump signals a milestone so significant that old save files may no longer be compatible. This tells your players: "start fresh for the best experience." Think large-scale reworks — restructured progression, overhauled save data schemas, or a full content reset like moving from Early Access to 1.0.
✓ When to increment major
// Save file format changed — old saves can't load properly0.12.4 → 1.0.0 // Early Access → Full Release// Complete progression rework, save data restructured1.8.3 → 2.0.0 // Major expansion overhaul// Core systems rewritten (e.g. inventory, combat)2.4.1 → 3.0.0 // Engine migration or deep refactor
Mi
Minor
New features, save-compatible
A minor bump means new content or features that don't break existing saves. Players can keep playing without starting over. New levels, new mechanics layered on top, new items, quality-of-life additions — anything additive that enriches the experience while respecting existing progress.
✓ When to increment minor
// Added a new biome with enemies and loot
1.3.7 → 1.4.0 // New content drop// New game mode (e.g. endless mode, co-op)
1.4.2 → 1.5.0 // Feature addition// New crafting system that works alongside existing saves
2.1.0 → 2.2.0 // New system, backward-compatible
Pa
Patch
Fixes and tweaks, no new content
A patch covers bug fixes, balance tweaks, performance improvements, and small adjustments that don't add meaningful content. These are the updates players barely notice — except that the game feels more polished afterward. Also use this to absorb what would otherwise be a "build" increment (see below).
In theory, a build number tracks every compilation attempt or build-settings change — useful internally but meaningless to players. In practice, adding a fourth segment creates compatibility headaches. Many platforms and APIs expect a strict a.b.c format: iOS requires it, most store APIs parse only three segments, and tools like SemVer are designed around three numbers. Folding build-level changes into patch keeps your version string universally parseable.
✗ Four-segment version
// Looks fine in your editor...bundleVersion = "1.4.3.12"// ...but iOS rejects it// ERROR: CFBundleShortVersionString// must be "X.Y.Z" format// Steam API, Google Play, most CI/CD// pipelines also expect a.b.c
✓ Three-segment version
// Works everywhere, no exceptionsbundleVersion = "1.4.8"// iOS ✓ CFBundleShortVersionString// Android ✓ versionName// Steam ✓ Depot versioning// Consoles ✓ Submission format// SemVer ✓ Standard compliance
✦ Example — version history of a game
0.1.0— First playable prototype
0.2.0— Added inventory system
0.2.1— Fixed item duplication bug
0.2.2— Tweaked drop rates, updated build settings
0.3.0— New combat system
0.4.0— Multiplayer co-op mode
0.4.1— Netcode stability patch
1.0.0— Full release — new save recommended
1.1.0— Post-launch DLC: new dungeon
1.1.1— Hotfix for DLC crash, IL2CPP rebuild
2.0.0— Massive expansion, save schema changed
✦Keep it simple: stick to three segments. Using major.minor.patch gives you enough granularity to communicate intent to players while staying compatible with every platform, store, and CI/CD pipeline. If you need an internal build counter, track it separately in your build system — don't bake it into the version string.
⚠Resetting lower segments. When you bump a higher segment, reset everything below it to zero. Going from 1.4.8 to 2.0.0 — not 2.4.8. Same for minor: 1.5.0 — not 1.5.8. This keeps your version history clean and predictable.