Skip to content

fix: stabilize item display metadata packing - #408

Merged
toxicity188 merged 1 commit into
toxicity188:v3-devfrom
mvanhorn:fix/405-item-display-metadata-packing
Aug 18, 2026
Merged

fix: stabilize item display metadata packing#408
toxicity188 merged 1 commit into
toxicity188:v3-devfrom
mvanhorn:fix/405-item-display-metadata-packing

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Aug 8, 2026

Copy link
Copy Markdown

Order each Bukkit NMS adapter's reflected EntityDataAccessor collection by accessor id before any existing positional selection, keeping the current field mapping and packet-building behavior otherwise unchanged. Apply the same minimal change across all maintained Bukkit NMS versions because these duplicated adapters are required to remain behaviorally equivalent; the Fabric implementation already uses named mixin accessors and is out of scope. Add a focused v26_R2 regression test that checks accessor ordering and the complete TransformationData.pack() output, including unique expected ids and the correct serializer/value category for interpolation delay, integer duration, translation, scale, and rotation. BetterModel 3.3.0 can send an ItemDisplay metadata entry whose field id is the integer interpolation-duration field while its serializer and payload are for a float, causing vanilla 26.2 clients to disconnect with a network protocol error. The reported failure is intermittent under rapid model spawn/despawn load, but the field/type pair and the v26_R2 transformation packing path are concrete. Bukkit NMS adapters currently collect EntityDataAccessor fields in raw Class.getDeclaredFields() order and then use positional indexes to select duration, translation, scale, and rotation accessors. That JVM field order is not a supported contract, while the accessors' numeric metadata ids provide the stable ordering the packet format requires.

Testing: With reflected Display accessors returned from accessors(), assert their ids are strictly ordered so positional selection cannot bind a later float accessor to the interpolation-duration slot; Pack a transformation with duration 20 and non-default translation, scale, and rotation; assert the duration entry uses the interpolation-duration id and integer serializer/value rather than a float serializer/value.

Fixes #405

@RaidenTechnology

Copy link
Copy Markdown

Reporter of #405 here. Your diagnosis matches what I saw — the field/type
pair is exactly the one that kicks the client.

I have the reproduction environment (Paper 26.2, BetterModel 3.3.0, models
spawning and despawning under load). Happy to build this branch and test it
against the case that originally kicked my clients — I'll report back with
results.

@toxicity188
toxicity188 changed the base branch from v3 to v3-dev August 18, 2026 01:29
@toxicity188
toxicity188 merged commit f105a86 into toxicity188:v3-dev Aug 18, 2026
1 check passed
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.

Client kicked with Network Protocol Error: Float written to ItemDisplay field 9 (interpolation duration, Int)

3 participants