Version resolution¶
pack_format is a declaration of which asset layout a pack targets, not a version of the pack.mcmeta file. Turning
it into Minecraft versions is what this library is for.
Declared vs effective¶
Overlays are how one pack supports several game versions: the root assets target one range, and each overlay directory swaps in replacements for another. So there are two honest answers, and both are exposed.
IdentificationResult.Identified identified = ...;
identified.declaredVersions(); // what the root "pack" section claims
identified.effectiveVersions(); // widened by every overlay range
For a pack declaring min_format 69.0 / max_format 88.0 with an overlay covering 55–63:
assertEquals("1.21.9 - 26.2", ((VersionResolution.Releases) identified.declaredVersions()).range().toString());
assertEquals("1.21.5 - 26.2", ((VersionResolution.Releases) identified.effectiveVersions()).range().toString());
Report only the declared range and you under-report every serious multi-version pack. Report only the effective range and you have silently merged ranges the author never claimed as one unit. Pick whichever suits the question you are answering.
The same distinction exists on the metadata itself as declaredRange() and effectiveRange(), in PackFormat terms
rather than game versions.
The four resolutions¶
VersionResolution is sealed:
VersionTable table = VersionTable.bundled();
table.resolve(PackFormat.of(64)); // Releases 1.21.7 - 1.21.8
table.resolve(PackFormat.of(20)); // Snapshots never shipped in a release
table.resolve(PackFormat.of(23)); // Unrecognised no build ever used it
table.resolve(PackFormat.of(9999)); // NewerThanKnown from the future
| Case | Meaning |
|---|---|
Releases |
The format shipped in at least one release. Carries the release range |
Snapshots |
The format existed only in snapshots |
NewerThanKnown |
Beyond the table's ceiling. Carries the highest format the table knows |
Unrecognised |
Within range but matching nothing — formats 10, 23 and 27 are real examples |
NewerThanKnown is a useful answer, not an error: it tells you the pack is from a newer Minecraft than this build of
the library knows about, which is different from the pack being broken.
Every case has describe() for a human-readable summary.
Format numbering¶
PackFormat(major, minor) models both eras. Minecraft switched to major.minor at 69.0 (1.21.9); before that a
format was a bare integer. A bare 82 is PackFormat(82, 0), exactly as the game coerces it.
toString() always renders major.minor. Legacy formats therefore print as 18.0 rather than 18 — uniform and
unambiguous, at the cost of being slightly verbose for the pre-1.21.9 era.
The version table¶
The bundled table covers 485 Minecraft versions across 98 formats, snapshot-exact, and carries an asOf marker.
VersionTable table = VersionTable.bundled();
table.asOf(); // the newest version in the table
table.highestKnown(); // its pack format
table.lowestKnown(); // PackFormat.of(1)
table.versions(); // newest first
It is generated, not hand-maintained:
That merges misode/mcmeta — machine-readable and updated every snapshot, covering
1.14 onwards — with a frozen hand-curated table for 1.6.1 – 1.13.2. It never runs during a normal build, so builds stay
offline and reproducible.
Supply your own table with VersionTable.load(InputStream) if you need to run ahead of a release. Required fields are
validated, so a malformed table fails loudly instead of silently resolving everything to format 0.0.