Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MC-Mapping-Reference

Repository: MC-Mapping-Reference

This project generates several useful artifacts from the official Minecraft mappings:

  1. Compact Markdown reference per mapping type and version (the all-mappings documentation).
  2. V1 changelog: a file diff based on the generated .md documents ("what changed?").
  3. V2 changelog: a core mapping comparator that reads the .tiny mapping files directly and detects real renames via a stable identity.

Goal: a coding agent (or human) that ports code to/between Minecraft versions should quickly learn which class names truly changed — without any obfuscation noise.


Pipeline Overview

cache/mappings/<version>/  ──►  takenaka (md generator)  ──► all-mappings/<ns>/<version>/
       (raw .tiny/.txt)                                        (per-class .md + classes.md)
                                                                    │
                                                   generate_changelog.py (V1, file diff)
                                                                    │
                                                           changelog/<ns>/<version>.md
                                                                    │
cache/mappings/<version>/*.client+server.tiny  ──► generate_changelog_v2.py (V2)
                                                                    │
                                                           changelog-v2/<ns>/<version>.md

There are three separate building blocks that work together but run independently.


2. Background: Minecraft mappings

Minecraft code is obfuscated (unreadable names such as a, ec, eza). Mappings are official or community mappings that map these cryptic names back to readable ones. Different mod loaders use different mapping systems:

Mapping type Internal namespace Output folder Used by
Mojang mojang all-mappings/mojang/ Modern Mojang mappings (Vanilla, Paper ≥ 1.20.4)
Yarn yarn all-mappings/yarn/ Fabric & Quilt (community)
Fabric intermediary all-mappings/fabric/ Fabric runtime (internal intermediate name)
Forge searge all-mappings/forge/ Forge/NeoForge (Searge names)
Obf source all-mappings/obf/ Original obfuscation (reference only)

Versions

Every mapping type has subdirectories per Minecraft version.

  • 1.21 to 1.21.11: all mapping types available (16 versions).
  • 26.1 to 26.2: Mojang and Obf only. There are no Yarn/Intermediary/Searge mappings for these versions — only mojang is available.

Important: obfuscated names are NOT stable

When comparing two versions, the obfuscated source names change completely on every version jump (overlap only ~60-99%). Comparing classes via the obfuscated names yields thousands of false "changes" (noise). The mapped names (mojang/yarn/intermediary/searge), on the other hand, are ~98-99% stable — this is the basis of identity in V2.


3. Building block A: the Markdown generator (takenaka)

The generator comes from the takenaka project (ScreamingSandals). It loads the raw mappings plus the server/client JARs (for modifiers, superclasses/interfaces, generics), reconciles them, and writes one compact Markdown file per class.

3.1 Building the CLI

cd takenaka
./gradlew :generator-md-cli:shadowJar

The finished JAR is then located at generator/md-cli/build/libs/generator-md-cli-<version>-all.jar.

3.2 Invocation

java -jar generator-md-cli-<version>-all.jar \
  --client --server \
  -n mojang -n yarn -n fabric -n forge -n obf \
  -v 1.21.4 -v 1.21.11 -v 26.2 \
  -o all-mappings \
  -c cache/mappings
  • -n (namespace): specify, or omit (then all); order matters.
  • -v (version): required; specify multiple times, or omit to generate all versions again.
  • -c cache directory (raw mapping data + JARs).
  • The cache needs cache/mappings/<version>/ with the downloaded mapping data.

3.3 Output layout (all-mappings)

all-mappings/<mapping>/<version>/...
    classes.md                                # class overview (one line `- \`Class\`` per class)
    <package-path>/<SimpleName>.md             # one file per class
    obf/<version>/<SimpleName>.md              # Obf namespace: flat, without package path

Each class .md is a compact table:

# Player (1.21.4)
Class: `net.minecraft.world.entity.player.Player`

## Fields
| Type | Name |
|---|---|
| `Logger` | LOGGER |

## Methods
| Return | Method |
|---|---|
| `boolean` | blockActionRestricted(Level arg0, ...) |

The obf documentation serves as reference only and is skipped by both changelog scripts (all noise).

Staging folders (md-test*, output-*) are intermediate development states and can be ignored.


4. Building block: V1 changelog (generate_changelog.py)

Basis: the .md files produced by the Markdown generator. Type of comparison: a pure file diff — which class names are not present in the previous version.

python3 generate_changelog.py <root> <changelog-dir>
# e.g.:
python3 generate_changelog.py . changelog
  • root = directory with the namespace subdirectories (the all-mappings structure).
  • generates changelog/<mapping>/<version>.md, a file only for this single version (against its predecessor).

Output example

# Changes for 1.21.4

## New classes (250)
- `net/minecraft/client/ClientBootstrap`
...

## `net/minecraft/world/xxx/Foo` — Fields +1, -1, Methods +2
- Field + `SpriteSet` sprites
- Method - `getRenderType` ()Lgcr;

Field identity = field name, method identity = name + parameter prefix. The Obf namespace is omitted.

Limitations of V1

  • Counts every trivial rename as "removed + added" (only "new"/"removed", no rename relationship).
  • At 1.21.2 this produces, for example, thousands of class entries, almost all of them pure obfuscation noise.
  • No access to the real descriptors — method differences are partially invisible.

5. Building block: V2 changelog (generate_changelog_v2.py)

V2 is the current main building block and the most useful tool for coding agents. It reads the resolved .tiny files directly (not the .md) and compares adjacent versions via the stable mapped identity.

python3 generate_changelog_v2.py <mappings-root> <changelog-v2-dir>
# e.g.:
python3 generate_changelog_v2.py cache/mappings changelog-v2
  • mappings-root = directory with cache/mappings/<version>/*.client+server.tiny.
  • generates changelog-v2/<mapping>/<version>.md (separate from the V1 directory, so V1 stays unchanged).
  • Runtime: ~2 minutes for all 16 versions × 4 mapping types.

5.1 The identity concept (core of the logic)

Because the obfuscated names are unstable across version jumps, identity is based on the mapped names (analogous to takariakka's AncestryTree / historyPage). Two (one from prev, one from cur) count as the same logical element if their identity sets intersect:

Element Identity
Class {(namespace, mappedName)}
Field {(namespace, mappedName, normDesc)}
Method {(namespace, mappedName, normDesc)}

The descriptor must be normalized (normDesc): the obfuscated class references inside the descriptor (e.g. Ldmm;) are replaced with their stable mapped name (e.g. Ljm; in the target namespace). Without this normalization, members would produce countless false changes per version jump, because the same method only fails to match because of its changed obfuscated descriptor ("rotate (Ldmm;)F" vs. "rotate (Ljm;)F").

Furthermore, the union of all namespaces present in both versions (intermediary, yarn, searge, mojang) is used as the identity search space (the more namespaces overlap, the more reliable the matching).

An element that matched and whose name differs in the target namespace between the previous and current version is a rename.

5.2 Mapping type → target namespace

MAPPING_NS in the script defines which name is used for the output:

Directory Target namespace (display)
mojang mojang
yarn yarn
fabric intermediary
forge searge
obf source (omitted, noise)

5.3 Output content

# Changes for 1.21.2

## Renamed classes (28)
- **`world/entity/MobSpawnType`**`world/entity/EntitySpawnReason`
- **`world/item/Tier`**`world/item/ToolMaterial`
...

## `ElytraLayer` — Fields ~1
- Field ~ `texture``wingsTexture` `(Lnet/...;)`

## `Foo` — Methods ~2, +1, -1
- Method ~ `createParticle``spawnParticle` `(L...)V`
- Method + `register` `(Llq;)V`
  • Renamed classes: real old → new pairs.
  • New / Removed classes: only the classes that actually appeared / disappeared.
  • Members: renames as ~ (old → new + descriptor), additions +, removals -.
  • Only sections with actual changes appear for each class.

26.x special case: here only mojang exists as a namespace (no second stable namespace). Without a second stable identity, renames cannot be reliably assigned — they therefore appear consistently as removed + added (not assignable, unavoidable).


6. V1 vs. V2 — when to use which

V1 (generate_changelog.py) V2 (generate_changelog_v2.py)
Input generated .md files .tiny mapping files (direct)
Answers only added / removed (no relationship) identifies old → new pairs
Renames ✗ (appear as removed + added) ✓ (real pairs)
Noise tolerance high (obf / many 1:1 renames) low (noise-free)
Output folder changelog/ changelog-v2/
Recommended for coding agent

7. Why is V2 great for a coding agent?

The biggest benefit of V2 is rename resolution. A coding agent that ports mod/plugin code to a new Minecraft version can then directly:

  1. Rewrite class name imports — e.g. MobSpawnTypeEntitySpawnReason, without wading through noise.
  2. See only the real breakages — everything else is a 1:1 rename or a package move.
  3. Search purposefully — instead of a wall of ~5659 "changed" names, only see the handful of 28-58 real renames.

Thanks to the descriptor normalization, member renames now appear as real ~ pairs (old → new + descriptor) rather than being misreported as +/-. Only for 26.x (only mojang namespace, no second stable reference) the assignment is missing — there members still appear as +/-.


8. Quickstart (all in one)

# 1) Build the mapping Markdown reference
cd takenaka && ./gradlew :generator-md-cli:shadowJar
java -jar generator/md-cli/build/libs/generator-md-cli-1.2.1-SNAPSHOT-all.jar \
  --client --server -n mojang -n yarn -n fabric -n forge -n obf \
  -v 1.21 -v 1.21.1 ... -v 26.2 -o all-mappings -c cache/mappings
cd ..

# 2) V1 (file diff) — only if still needed
python3 generate_changelog.py . changelog

# 3) V2 (real renames) — main script
python3 generate_changelog_v2.py cache/mappings changelog-v2

9. Project structure

MC-Mapping-Reference/
├── README.md                     # this file
├── generate_changelog.py         # V1 script
├── generate_changelog_v2.py      # V2 script (core)
├── takenaka/                     # Kotlin project with the md generator (building block 1)
└── .gitignore

# Generated data (lives outside the repo in mappings-test/)
all-mappings/                     # Markdown reference (generated docs)
├── mojang/ yarn/ fabric/ forge/ obf/   # per mapping type
└── mappings.md                   # overview of the mapping types
cache/mappings/<version>/         # raw input for both scripts (.client+server.tiny, JARs, ...)
changelog/                        # V1 output (file diff)
changelog-v2/                     # V2 output (real renames) —— main artifact
md-test*, output-*                # obsolete staging folders (can be ignored)

10. License & credits

Credits partially based on the work of zlataovce (GitHub profile):

  • takenaka — Apache License 2.0; project by ScreamingSandals that provides the Markdown generation. The two changelog scripts build on top of it.

About

Minecraft mapping reference & changelog generator. Tracks renamed classes/methods across versions (1.21-26.2) from .tiny mappings - no obfuscation noise, ideal for mod/plugin porting.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages