Skip to content

pc: fix intangible_projectile NBT and 26.1 item stack templates - #1267

Merged
rom1504 merged 3 commits into
masterfrom
fix-item-stack-template
Sep 14, 2026
Merged

rom1504 merged 3 commits into
masterfrom
fix-item-stack-template

Conversation

@u9g

@u9g u9g commented Aug 30, 2026

Copy link
Copy Markdown
Member

Two protocol fixes found by PrismarineJS/prismarine-item#184's live vanilla tests.

intangible_projectile is NBT, not void (1.21.5–26.1)

The component has no dedicated network codec, so vanilla syncs it through its NBT codec — an empty compound (0a 00) on the wire. 1.20.5–1.21.4 correctly had anonymousNbt and 1.21.5 onward regressed to void, leaving two bytes unread in any slot carrying the component (protodef PartialReadError on set_slot). unbreakable and glider stay void: they have real unit stream codecs and decode cleanly today.

26.1 sends non-empty stacks as item stack templates (item id first)

26.1 changed the non-optional stack codec to item id, count, components; the optional count-first Slot form (set_slot, window_items, cursor, equipment, merchant offers, entity metadata) is unchanged. Before this fix, nested stacks decode with itemId/itemCount swapped — giving bundle[bundle_contents=[{id:stone,count:3},{id:dirt}]] parsed as item 3 ×1 and item 1 ×28.

This adds an ItemStackTemplate type and uses it where vanilla uses the template codec (cross-checked against MCProtocolLib's readItemStackTemplate call sites):

  • use_remainder, charged_projectiles, bundle_contents components
  • container component — now a prefixed-optional template per entry, preserving empty slots
  • the item particle
  • the item_stack slot display
  • the advancement display icon

Verification

Each site was checked against real vanilla servers (1.21.5, 1.21.6, 1.21.8, 1.21.9, 1.21.11, 26.1) by giving items carrying each component, granting an advancement and spawning item particles, then confirming the decoded ids and counts match what was given, with zero parse errors. On 26.1: stone(1)×3 + dirt(28)×1 bundle, shulker container decoding [null, diamond(899)×5], advancement icons and minecraft:item particle all correct. prismarine-item#184's 78 live window_click hash tests still pass against 1.21.5/1.21.11 with these files, now with no PartialReadErrors.

protocol.json files are regenerated from the edited proto.ymls via npm run build; tools/js tests pass (the only local failure is the 40s suite-duration gate, from running Minecraft servers concurrently on the same machine).

intangible_projectile has no dedicated network codec, so vanilla syncs
it as NBT (an empty compound); 1.20.5-1.21.4 had it right and 1.21.5
onward regressed to void, leaving two bytes unread in any slot carrying
it.

26.1 sends non-empty stacks (item stack templates) with the item id
before the count, while the optional count-first Slot form is
unchanged. Add an ItemStackTemplate type and use it at the sites
vanilla serializes with the template codec: the use_remainder,
charged_projectiles, bundle_contents and container components (the
latter as a prefixed optional now, preserving empty slots), the item
particle, the item_stack slot display and the advancement icon.

Verified against vanilla 1.21.5-26.1 servers by giving items carrying
each component, granting an advancement and spawning item particles,
and checking the decoded ids, counts and hashes against what was
given (PrismarineJS/prismarine-item#184's live tests).
@rom1504

rom1504 commented Aug 30, 2026

Copy link
Copy Markdown
Member

Did you check against the decompiled code ?

EntityDataSerializers.ITEM_STACK still uses ItemStack.OPTIONAL_STREAM_CODEC
(count-first optional) in 26.1; only the template call sites changed.
@u9g

u9g commented Aug 30, 2026

Copy link
Copy Markdown
Member Author

Did you check against the decompiled code ?

I just checked, yes.

@u9g

u9g commented Sep 11, 2026

Copy link
Copy Markdown
Member Author

Decompiled sources behind each change, for the record:

  • 1.21.5 DataComponents: INTANGIBLE_PROJECTILE = register("intangible_projectile", b -> b.persistent(Unit.CODEC)) with no networkSynchronized; DataComponentType.Builder.build then uses ByteBufCodecs.fromCodecWithRegistries(codec), i.e. the NBT form (empty compound). UNBREAKABLE and GLIDER are .networkSynchronized(Unit.STREAM_CODEC) and stay void. Same registrations through 26.1.
  • 26.1 ItemStackTemplate.STREAM_CODEC = composite(Item.STREAM_CODEC, VAR_INT count, DataComponentPatch.STREAM_CODEC), item id first. Sites using it: UseRemainder.STREAM_CODEC, ChargedProjectiles.STREAM_CODEC (list), BundleContents.STREAM_CODEC (list), ItemContainerContents.STREAM_CODEC (.apply(ByteBufCodecs::optional).apply(list(256)), hence the prefixed optional per entry), ItemParticleOption.streamCodec, SlotDisplay.ItemStackSlotDisplay.STREAM_CODEC, DisplayInfo.serializeToNetwork (advancement icon).
  • 26.1 ItemStack.STREAM_CODEC still delegates to OPTIONAL_STREAM_CODEC (count first), so MerchantOffer, set_slot, window_items, cursor, equipment and entity metadata are unchanged.

@rom1504
rom1504 merged commit fb64396 into master Sep 14, 2026
4 checks passed
@rom1504
rom1504 deleted the fix-item-stack-template branch September 14, 2026 07:04
DallasCarraher added a commit to DallasCarraher/minecraft-data that referenced this pull request Sep 14, 2026
Addresses review feedback on this PR:

- sulfur_cube_content duplicated ItemStackTemplate's shape inline
  instead of referencing it. Verified against the real 26.2 server jar:
  net.minecraft.world.item.component.SulfurCubeContent is a record with
  a single field of type net.minecraft.world.item.ItemStackTemplate (no
  array wrapper) — Mojang's own internal type has the same name and
  shape minecraft-data already used. Now just `if sulfur_cube_content:
  ItemStackTemplate`.

- packet_spectator_action: verified this is a genuine rename, not a
  new packet alongside the old one. Decompiled the real 26.2 server
  jar: net/minecraft/network/protocol/game/ServerboundSpectatorActionPacket
  exists (a Record with one field, `OptionalInt spectateEntityId`,
  handled via `handleSpectatorAction`); no ServerboundSpectateEntityPacket
  class exists anywhere in the jar. Matches this PR's existing encoding
  (`entityId?: varint`) exactly — no data change needed for this one.

- Separately: rebasing this branch onto pc_26_2 silently regressed
  PrismarineJS#1267's ItemStackTemplate fix throughout data/pc/latest/proto.yml —
  git's merge applied both sides' overlapping edits to this file in a
  way that dropped PrismarineJS#1267's hunks without flagging a conflict. Restored
  all of it (intangible_projectile NBT, and ItemStackTemplate at
  use_remainder/charged_projectiles/bundle_contents/container/particle
  item/SlotDisplay item_stack/advancement icon) and regenerated
  data/pc/26.2/protocol.json from the corrected proto.yml.

Full test suite still green: 1887 passing, 1 pending, 0 failing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
DallasCarraher added a commit to DallasCarraher/minecraft-data that referenced this pull request Sep 14, 2026
…ng, cubemob metadata, bee size, knockback_resistance min

All five verified by decompiling the real 26.2 server jar
(versions/26.2/server-26.2.jar) with CFR, cross-referenced against
extremeheat/extracted_minecraft_data where cited in review.

- packet_entity_teleport: the pc_26_2 rebase also silently dropped
  PrismarineJS#1273's 1.21.2+ layout fix (dx/dy/dz, f32 yaw/pitch,
  PositionUpdateRelatives flags) the same way it dropped PrismarineJS#1267's
  ItemStackTemplate fix. Restored — ClientboundTeleportEntityPacket
  still uses PositionMoveRotation in 26.2, confirmed against the real
  class.

- packet_spectator_action: entityId?: varint (protodef presence-byte
  optional) doesn't match vanilla's wire format. Decompiled
  ByteBufCodecs.OPTIONAL_VAR_INT: it maps a single raw VarInt directly
  (no separate presence byte) — 0 = absent, n = entity id (n - 1).
  Changed to `entityId: optvarint`, the same sentinel-varint alias
  already used for entity metadata's optional_block_state/
  optional_unsigned_int.

- data/pc/26.2/entities.json: slime/magma_cube/sulfur_cube were
  missing the `baby`/`age_locked` metadata keys AgeableMob defines
  (confirmed via SynchedEntityData.defineId call order in
  AgeableMob/AbstractCubeMob/SulfurCube bytecode), and sulfur_cube had
  max_fuse/from_bucket swapped. Fixed all three to
  mob_flags, baby, age_locked, size, max_fuse, from_bucket.

- bee width/height: EntityTypes.BEE registers .sized(0.55f, 0.5f) in
  26.2; entities.json still had 26.1's 0.7/0.6. Fixed.

- data/pc/26.2/attributes.json: knockbackResistance's min was 0.0;
  Attributes.KNOCKBACK_RESISTANCE registers RangedAttribute(default
  0.0, min -2.0, max 1.0). Fixed.

Full test suite still green: 1887 passing, 1 pending, 0 failing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
extremeheat pushed a commit that referenced this pull request Sep 19, 2026
* Add Minecraft PC 26.2 data

Registers protocol 776 (26.2) with real generated data: blocks, items,
entities, recipes, language, commands, protocol.json (regenerated from
proto.yml), loot tables, and the rest of the per-version files. Also
adds a 1.20.3 windows.json with the crafter menu (missing since 1.20.3)
so 26.2's windows entry is accurate.

Extracted from the 26.2 portion of #1287,
which additionally carries unrelated fixes for 1.13.1, 1.14.2, 1.9.1
and a broader commands.json refresh across older versions. This commit
isolates just the 26.2 data so it can be reviewed and merged
independently of that larger changeset.

effects/enchantments/instruments are borrowed from 26.1 since those
registries are unchanged in 26.2.

Full mocha suite passes (1887 passing, 1 pending, 0 failing).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Fix sulfur_cube_content type reuse; restore ItemStackTemplate regression

Addresses review feedback on this PR:

- sulfur_cube_content duplicated ItemStackTemplate's shape inline
  instead of referencing it. Verified against the real 26.2 server jar:
  net.minecraft.world.item.component.SulfurCubeContent is a record with
  a single field of type net.minecraft.world.item.ItemStackTemplate (no
  array wrapper) — Mojang's own internal type has the same name and
  shape minecraft-data already used. Now just `if sulfur_cube_content:
  ItemStackTemplate`.

- packet_spectator_action: verified this is a genuine rename, not a
  new packet alongside the old one. Decompiled the real 26.2 server
  jar: net/minecraft/network/protocol/game/ServerboundSpectatorActionPacket
  exists (a Record with one field, `OptionalInt spectateEntityId`,
  handled via `handleSpectatorAction`); no ServerboundSpectateEntityPacket
  class exists anywhere in the jar. Matches this PR's existing encoding
  (`entityId?: varint`) exactly — no data change needed for this one.

- Separately: rebasing this branch onto pc_26_2 silently regressed
  #1267's ItemStackTemplate fix throughout data/pc/latest/proto.yml —
  git's merge applied both sides' overlapping edits to this file in a
  way that dropped #1267's hunks without flagging a conflict. Restored
  all of it (intangible_projectile NBT, and ItemStackTemplate at
  use_remainder/charged_projectiles/bundle_contents/container/particle
  item/SlotDisplay item_stack/advancement icon) and regenerated
  data/pc/26.2/protocol.json from the corrected proto.yml.

Full test suite still green: 1887 passing, 1 pending, 0 failing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Address review findings: teleport regression, spectator_action encoding, cubemob metadata, bee size, knockback_resistance min

All five verified by decompiling the real 26.2 server jar
(versions/26.2/server-26.2.jar) with CFR, cross-referenced against
extremeheat/extracted_minecraft_data where cited in review.

- packet_entity_teleport: the pc_26_2 rebase also silently dropped
  #1273's 1.21.2+ layout fix (dx/dy/dz, f32 yaw/pitch,
  PositionUpdateRelatives flags) the same way it dropped #1267's
  ItemStackTemplate fix. Restored — ClientboundTeleportEntityPacket
  still uses PositionMoveRotation in 26.2, confirmed against the real
  class.

- packet_spectator_action: entityId?: varint (protodef presence-byte
  optional) doesn't match vanilla's wire format. Decompiled
  ByteBufCodecs.OPTIONAL_VAR_INT: it maps a single raw VarInt directly
  (no separate presence byte) — 0 = absent, n = entity id (n - 1).
  Changed to `entityId: optvarint`, the same sentinel-varint alias
  already used for entity metadata's optional_block_state/
  optional_unsigned_int.

- data/pc/26.2/entities.json: slime/magma_cube/sulfur_cube were
  missing the `baby`/`age_locked` metadata keys AgeableMob defines
  (confirmed via SynchedEntityData.defineId call order in
  AgeableMob/AbstractCubeMob/SulfurCube bytecode), and sulfur_cube had
  max_fuse/from_bucket swapped. Fixed all three to
  mob_flags, baby, age_locked, size, max_fuse, from_bucket.

- bee width/height: EntityTypes.BEE registers .sized(0.55f, 0.5f) in
  26.2; entities.json still had 26.1's 0.7/0.6. Fixed.

- data/pc/26.2/attributes.json: knockbackResistance's min was 0.0;
  Attributes.KNOCKBACK_RESISTANCE registers RangedAttribute(default
  0.0, min -2.0, max 1.0). Fixed.

Full test suite still green: 1887 passing, 1 pending, 0 failing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Address review: preserve trial_spawner particle naming, fix pickaxe material for 26.2

- Revert latest/proto.yml particle enum rename (trial_spawner_detection ->
  trial_spawner_detected_player) to match the naming still used by all
  other proto.yml versions, avoiding an inconsistent one-off rename scoped
  to this PR; regenerate 26.2/protocol.json to match.
- Fix 26.2/blocks.json: 108 ore/obsidian/metal blocks carried
  material: incorrect_for_wooden_tool instead of mineable/pickaxe, which
  made prismarine-block digTime() ~8x too slow for them. Apply the same
  mapping used by #1307 for 1.20.5-26.1 so 26.2 doesn't regress.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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.

2 participants