Step 4 of #8, into stonecutter. The first version before the 1.21.9 render queue: 1.21.8 now builds from src/ as :1.21.8, and versions/1.21.8/src is gone.
API differences behind version comments (<1.21.9 / >=1.21.9)
Player cosmetics: before 1.21.9, FeatureRenderer.render takes a VertexConsumerProvider instead of the render queue.
The cloak, hat and OBJ renderers now name the render target output in both versions, so only its type and the final draw call differ: output.submitCustom(layer, …) vs output.getBuffer(layer).
The OBJ face loop moved into a drawGroup helper that both paths call.
Smaller renames and API changes:
the entity type in PlayerEntityRenderer.updateRenderState (PlayerLikeEntity generics vs AbstractClientPlayerEntity)
the cape texture accessor (cape() vs capeTexture())
GameProfilename()/id() vs getName()/getId() (MinecraftClientMixin, TabListMixin)
fonts in TextMixin
EntityRenderManager vs EntityRenderDispatcher
Screen input events (Click/KeyInput vs raw values)
KeyBinding categories and InputUtil.isKeyPressed
Features 1.21.9+ lacks, kept on 1.21.8
Each has a TODO on the 1.21.9+ side:
Custom nametags.NametagsMixin only existed on 1.21.8, because it hooks renderLabelIfPresent(…, VertexConsumerProvider, …), which 1.21.9 changed. It's now in src/ with its body only on <1.21.9, and an empty class on 1.21.9+. It stays registered for every version, so features.mixins.json needs no version comments.
The splash screen's loading-bar border (commented out on 1.21.9+).
Real drag deltas in SaturnScreenFabric.mouseDragged (1.21.9+ passes 0.0, 0.0).
Status effect icons keep 1.21.8's GUI atlas sprite. 1.21.9+ draws the effect's texture instead (getIconId), which it already did.
Behaviour changes on 1.21.8
Player lookup: the cloak and hat read the Saturn player from the render state instead of looking it up by name. PlayerEntityRendererMixin already stores it there on 1.21.8, keyed by UUID, so this is the same as 1.21.9+.
Null check: the display-name null check from 1.21.11 applies.
Checks
1.21.8 jar vs old :mc-1.21.8: same entries, identical fabric.mod.json and mixin configs. Bytecode differs (ignoring line numbers) only in:
CloakFeatureRenderer and HatFeatureRenderer: player lookup
PlayerEntityRendererMixin: null check
ObjRenderer: drawGroup
ShaderUtils: entityAlpha helper
StatusEffectMixin: gains 1.21.9's getIconId, unused while 1.21.8 returns a sprite
1.21.9–1.21.11 jars: only ObjRenderer (drawGroup), the new empty NametagsMixin and its features.mixins.json entry.
Switching versions:Set active project to 1.21.8 compiles, and a reset leaves src/ unchanged.
Builds: a cold buildAll --no-build-cache builds all 8 jars in 96 s, and compileJava passes.
In game::1.21.8:runClient and :1.21.11:runClient start, with both NametagsMixin variants applied.
VERSION_GUIDE.md now also covers version-only classes (empty bodies keep the mixin configs shared) and why inactive code can't contain /* */ comments.
Needs an in-game check on 1.21.8: cloak, hat, nametags and the status effect HUD.
Step 4 of #8, into `stonecutter`. The first version before the 1.21.9 render queue: 1.21.8 now builds from `src/` as `:1.21.8`, and `versions/1.21.8/src` is gone.
## API differences behind version comments (`<1.21.9` / `>=1.21.9`)
- **Player cosmetics:** before 1.21.9, `FeatureRenderer.render` takes a `VertexConsumerProvider` instead of the render queue.
- The cloak, hat and OBJ renderers now name the render target `output` in both versions, so only its type and the final draw call differ: `output.submitCustom(layer, …)` vs `output.getBuffer(layer)`.
- The OBJ face loop moved into a `drawGroup` helper that both paths call.
- **Smaller renames and API changes:**
- the entity type in `PlayerEntityRenderer.updateRenderState` (`PlayerLikeEntity` generics vs `AbstractClientPlayerEntity`)
- the cape texture accessor (`cape()` vs `capeTexture()`)
- `GameProfile` `name()`/`id()` vs `getName()`/`getId()` (`MinecraftClientMixin`, `TabListMixin`)
- fonts in `TextMixin`
- `EntityRenderManager` vs `EntityRenderDispatcher`
- Screen input events (`Click`/`KeyInput` vs raw values)
- `KeyBinding` categories and `InputUtil.isKeyPressed`
## Features 1.21.9+ lacks, kept on 1.21.8
Each has a `TODO` on the 1.21.9+ side:
- **Custom nametags.** `NametagsMixin` only existed on 1.21.8, because it hooks `renderLabelIfPresent(…, VertexConsumerProvider, …)`, which 1.21.9 changed. It's now in `src/` with its body only on `<1.21.9`, and an empty class on 1.21.9+. It stays registered for every version, so `features.mixins.json` needs no version comments.
- **The splash screen's loading-bar border** (commented out on 1.21.9+).
- **Real drag deltas** in `SaturnScreenFabric.mouseDragged` (1.21.9+ passes `0.0, 0.0`).
Status effect icons keep 1.21.8's GUI atlas sprite. 1.21.9+ draws the effect's texture instead (`getIconId`), which it already did.
## Behaviour changes on 1.21.8
- **Player lookup:** the cloak and hat read the Saturn player from the render state instead of looking it up by name. `PlayerEntityRendererMixin` already stores it there on 1.21.8, keyed by UUID, so this is the same as 1.21.9+.
- **Null check:** the display-name null check from 1.21.11 applies.
## Checks
- **1.21.8 jar vs old `:mc-1.21.8`:** same entries, identical `fabric.mod.json` and mixin configs. Bytecode differs (ignoring line numbers) only in:
- `CloakFeatureRenderer` and `HatFeatureRenderer`: player lookup
- `PlayerEntityRendererMixin`: null check
- `ObjRenderer`: `drawGroup`
- `ShaderUtils`: `entityAlpha` helper
- `StatusEffectMixin`: gains 1.21.9's `getIconId`, unused while 1.21.8 returns a sprite
- **1.21.9–1.21.11 jars:** only `ObjRenderer` (`drawGroup`), the new empty `NametagsMixin` and its `features.mixins.json` entry.
- **Switching versions:** `Set active project to 1.21.8` compiles, and a reset leaves `src/` unchanged.
- **Builds:** a cold `buildAll --no-build-cache` builds all 8 jars in 96 s, and `compileJava` passes.
- **In game:** `:1.21.8:runClient` and `:1.21.11:runClient` start, with both `NametagsMixin` variants applied.
`VERSION_GUIDE.md` now also covers version-only classes (empty bodies keep the mixin configs shared) and why inactive code can't contain `/* */` comments.
**Needs an in-game check on 1.21.8:** cloak, hat, nametags and the status effect HUD.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Step 4 of #8, the first version before the 1.21.9 render queue.
versions/1.21.8/src is gone; 1.21.8 builds from src/ as :1.21.8.
API differences behind version comments (<1.21.9 / >=1.21.9):
- Player cosmetics: FeatureRenderer.render takes a VertexConsumerProvider
instead of the render queue. The cloak, hat and OBJ renderers name the
render target "output" in both, so only the parameter type and the final
draw call differ; the OBJ face loop moved into drawGroup.
- PlayerEntityRenderer.updateRenderState's entity type, the cape texture
accessor, GameProfile getName()/getId() vs name()/id(), fonts in
TextMixin, EntityRenderDispatcher vs EntityRenderManager, Screen input
events (Click/KeyInput), and KeyBinding categories and isKeyPressed.
Features 1.21.9+ lacks stay on 1.21.8, with a TODO for 1.21.9+:
- NametagsMixin moves into src/. It hooks renderLabelIfPresent with a
VertexConsumerProvider, which 1.21.9 changed, so on 1.21.9+ its body is
empty; it stays registered, so features.mixins.json is the same for
every version.
- The splash screen's loading-bar border, and the real drag deltas in
SaturnScreenFabric.mouseDragged.
- Status effect icons keep 1.21.8's GUI atlas sprite; 1.21.9+ draws the
texture instead (getIconId), as before.
Behaviour changes on 1.21.8: the cloak and hat read the Saturn player from
the render state (set by PlayerEntityRendererMixin, by UUID) instead of
looking it up by name, and the display-name null check applies.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Step 4 of #8, into
stonecutter. The first version before the 1.21.9 render queue: 1.21.8 now builds fromsrc/as:1.21.8, andversions/1.21.8/srcis gone.API differences behind version comments (
<1.21.9/>=1.21.9)FeatureRenderer.rendertakes aVertexConsumerProviderinstead of the render queue.outputin both versions, so only its type and the final draw call differ:output.submitCustom(layer, …)vsoutput.getBuffer(layer).drawGrouphelper that both paths call.PlayerEntityRenderer.updateRenderState(PlayerLikeEntitygenerics vsAbstractClientPlayerEntity)cape()vscapeTexture())GameProfilename()/id()vsgetName()/getId()(MinecraftClientMixin,TabListMixin)TextMixinEntityRenderManagervsEntityRenderDispatcherClick/KeyInputvs raw values)KeyBindingcategories andInputUtil.isKeyPressedFeatures 1.21.9+ lacks, kept on 1.21.8
Each has a
TODOon the 1.21.9+ side:NametagsMixinonly existed on 1.21.8, because it hooksrenderLabelIfPresent(…, VertexConsumerProvider, …), which 1.21.9 changed. It's now insrc/with its body only on<1.21.9, and an empty class on 1.21.9+. It stays registered for every version, sofeatures.mixins.jsonneeds no version comments.SaturnScreenFabric.mouseDragged(1.21.9+ passes0.0, 0.0).Status effect icons keep 1.21.8's GUI atlas sprite. 1.21.9+ draws the effect's texture instead (
getIconId), which it already did.Behaviour changes on 1.21.8
PlayerEntityRendererMixinalready stores it there on 1.21.8, keyed by UUID, so this is the same as 1.21.9+.Checks
:mc-1.21.8: same entries, identicalfabric.mod.jsonand mixin configs. Bytecode differs (ignoring line numbers) only in:CloakFeatureRendererandHatFeatureRenderer: player lookupPlayerEntityRendererMixin: null checkObjRenderer:drawGroupShaderUtils:entityAlphahelperStatusEffectMixin: gains 1.21.9'sgetIconId, unused while 1.21.8 returns a spriteObjRenderer(drawGroup), the new emptyNametagsMixinand itsfeatures.mixins.jsonentry.Set active project to 1.21.8compiles, and a reset leavessrc/unchanged.buildAll --no-build-cachebuilds all 8 jars in 96 s, andcompileJavapasses.:1.21.8:runClientand:1.21.11:runClientstart, with bothNametagsMixinvariants applied.VERSION_GUIDE.mdnow also covers version-only classes (empty bodies keep the mixin configs shared) and why inactive code can't contain/* */comments.Needs an in-game check on 1.21.8: cloak, hat, nametags and the status effect HUD.
🤖 Generated with Claude Code
Tested and hats, cloaks, nametags, and the status effect all work