Skip to content

fix: preserve custom head items in player emotes - #411

Draft
OmarZiadeh wants to merge 1 commit into
toxicity188:v3-devfrom
OmarZiadeh:fix/410-player-emote-item-model
Draft

fix: preserve custom head items in player emotes#411
OmarZiadeh wants to merge 1 commit into
toxicity188:v3-devfrom
OmarZiadeh:fix/410-player-emote-item-model

Conversation

@OmarZiadeh

@OmarZiadeh OmarZiadeh commented Aug 13, 2026

Copy link
Copy Markdown

Type

Bug fix / small additive API update

Summary

  • preserve helmet stacks whose minecraft:item_model or minecraft:custom_model_data differs from the base item
  • synthesize a private HEAD-transformed renderer child beneath every existing ph_ player-head bone at model-load time
  • suppress BetterModel's generated vanilla helmet layer only while that custom head item is active
  • keep unmodified vanilla armor on the existing generated armor path

No public bone tag or global model-name prefix is added, and steve.bbmodel is unchanged. Existing installations and custom player rigs gain the behavior on reload without replacing copied model files.

Root cause

Player emotes converted the equipped helmet exclusively to ArmorItem texture metadata. That conversion discarded the original item stack's custom model components, and the player skin renderer consequently rebuilt only a vanilla armor layer.

Implementation

PlayerArmor#helmetItem() is the additive transport seam between version-coupled platform adapters and the renderer. The private player-renderer implementation constructs a deterministic zero-offset child under each PLAYER_HEAD; its directly constructed, unregistered BoneTag supplies the custom-item mapper and never enters BoneTagRegistry.

Verification

  • reproduced on the Paper 1.21.11 (v1_21_R7) conversion boundary before the fix: custom and plain helmets collapsed to identical armor metadata
  • :nms:v1_21_R7:test --tests 'kr.toxicity.model.bukkit.nms.v1_21_R7.PlayerArmorImplTest'
  • :bettermodel-core:test --tests 'kr.toxicity.model.manager.PlayerModelRendererTest'
  • full normal build across all Paper mappings, Fabric, tests, license checks, Javadocs, and packaging

Renderer coverage starts from an arbitrary existing ph_head blueprint and verifies player-only synthesis, authored-child preservation, internal-name collision handling, deterministic identity, zero relative offset, visibility, private parsing, helmet/air mapping, and the HEAD transform.

An initial uncached run of the three legacy Paperweight setup tasks required its CodeBook Java launcher to use JDK 21 because CodeBook 1.0.14 cannot inspect JDK 25 class files. That workaround is not in this branch; after setup, the normal full build passed.

Remaining draft check

In-game resource-pack visual confirmation is still pending; automated coverage verifies component preservation and the complete renderer-construction path.

Fixes #410

Preserve custom helmet components and synthesize a private HEAD-transformed child beneath existing ph_ player heads without changing public bone tags or bundled player models.
@OmarZiadeh
OmarZiadeh force-pushed the fix/410-player-emote-item-model branch from 78218f7 to 3649eb7 Compare August 13, 2026 22:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant