NametagsMixin hooked EntityRenderer.renderLabelIfPresent(state, text, MatrixStack, VertexConsumerProvider, light) to draw a replacement label. 1.21.9 moved label rendering to the render command queue, so that method no longer exists. The mixin was empty there, and NametagsMod did nothing on 1.21.9–1.21.11.
Fix
One hook for every version.LivingEntityRendererMixin already captures health and entity type at the end of LivingEntityRenderer.updateRenderState. It now also applies NametagsMod.getNametagString(...) to state.displayName, which is the label the renderer draws later on every version.
Old mixin removed. No version condition is needed, so NametagsMixin and its features.mixins.json entry are gone.
Same rules as before: only entities that already show a label get a replacement, and the mod's filters (players, hostile, passive, health format) are unchanged.
Docs:VERSION_GUIDE.md now suggests looking for a hook like this before splitting a class by version. MatrixStackMixin is the remaining example of a version-only mixin.
One visible difference
Role icon placement: for players, the Saturn role icon is added after this (PlayerEntityRendererMixin). So it now comes before the replaced name and keeps its colour. Before, the replacement text swallowed the icon as a plain character.
Checks
Builds:compileJava passes for all 8 versions.
In game: 1.21.4, 1.21.8 (which used the old hook) and 1.21.11 start.
Needs an in-game check, on a newer and an older version (e.g. 1.21.11 and 1.21.8): turn Nametags on with "Display health", then look at a named mob, another player and yourself in F5.
Part of #30: custom nametags on 1.21.9+.
## Why they didn't work
`NametagsMixin` hooked `EntityRenderer.renderLabelIfPresent(state, text, MatrixStack, VertexConsumerProvider, light)` to draw a replacement label. 1.21.9 moved label rendering to the render command queue, so that method no longer exists. The mixin was empty there, and `NametagsMod` did nothing on 1.21.9–1.21.11.
## Fix
- **One hook for every version.** `LivingEntityRendererMixin` already captures health and entity type at the end of `LivingEntityRenderer.updateRenderState`. It now also applies `NametagsMod.getNametagString(...)` to `state.displayName`, which is the label the renderer draws later on every version.
- **Old mixin removed.** No version condition is needed, so `NametagsMixin` and its `features.mixins.json` entry are gone.
- **Same rules as before:** only entities that already show a label get a replacement, and the mod's filters (players, hostile, passive, health format) are unchanged.
- **Docs:** `VERSION_GUIDE.md` now suggests looking for a hook like this before splitting a class by version. `MatrixStackMixin` is the remaining example of a version-only mixin.
## One visible difference
**Role icon placement:** for players, the Saturn role icon is added after this (`PlayerEntityRendererMixin`). So it now comes before the replaced name and keeps its colour. Before, the replacement text swallowed the icon as a plain character.
## Checks
- **Builds:** `compileJava` passes for all 8 versions.
- **In game:** 1.21.4, 1.21.8 (which used the old hook) and 1.21.11 start.
**Needs an in-game check, on a newer and an older version (e.g. 1.21.11 and 1.21.8):** turn Nametags on with "Display health", then look at a named mob, another player and yourself in F5.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
NametagsMixin hooked EntityRenderer.renderLabelIfPresent with a
VertexConsumerProvider, which 1.21.9 moved to the render command queue, so
custom nametags only worked before 1.21.9 (#30).
LivingEntityRendererMixin already captures health and entity type at the
end of LivingEntityRenderer.updateRenderState. It now also applies
NametagsMod's replacement to state.displayName there, the label the
renderer draws later. This works the same on every version, so
NametagsMixin and its features.mixins.json entry are gone.
As before, only entities that already show a label get a replacement. For
players, the role icon is added after this (PlayerEntityRendererMixin), so
it now comes before the replaced name and keeps its colour, instead of
being folded into the replacement text.
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.
Part of #30: custom nametags on 1.21.9+.
Why they didn't work
NametagsMixinhookedEntityRenderer.renderLabelIfPresent(state, text, MatrixStack, VertexConsumerProvider, light)to draw a replacement label. 1.21.9 moved label rendering to the render command queue, so that method no longer exists. The mixin was empty there, andNametagsModdid nothing on 1.21.9–1.21.11.Fix
LivingEntityRendererMixinalready captures health and entity type at the end ofLivingEntityRenderer.updateRenderState. It now also appliesNametagsMod.getNametagString(...)tostate.displayName, which is the label the renderer draws later on every version.NametagsMixinand itsfeatures.mixins.jsonentry are gone.VERSION_GUIDE.mdnow suggests looking for a hook like this before splitting a class by version.MatrixStackMixinis the remaining example of a version-only mixin.One visible difference
Role icon placement: for players, the Saturn role icon is added after this (
PlayerEntityRendererMixin). So it now comes before the replaced name and keeps its colour. Before, the replacement text swallowed the icon as a plain character.Checks
compileJavapasses for all 8 versions.Needs an in-game check, on a newer and an older version (e.g. 1.21.11 and 1.21.8): turn Nametags on with "Display health", then look at a named mob, another player and yourself in F5.
🤖 Generated with Claude Code