Skip to content

feat: support Minecraft 26.3 - #27

Open
twme-ai wants to merge 1 commit into
mainfrom
feat/minecraft-26.3
Open

twme-ai wants to merge 1 commit into
mainfrom
feat/minecraft-26.3

Conversation

@twme-ai

@twme-ai twme-ai commented Sep 25, 2026

Copy link
Copy Markdown
Owner

Summary

Upgrade VirtualEntities to Minecraft 26.3.

  • PacketEvents 2.13.0 → 2.14.0 (first release with ClientVersion.V_26_3, protocol 777)
  • Bundle a reviewed 26.3 entity-data snapshot, so the library no longer throws
    Entity-data version '26.3' is newer than the latest bundled snapshot '26.2.0' on a 26.3 server
  • Map the new DyeColor metadata serializer in both the runtime type table and the key generator
  • Teach tools/sync-entity-data.sh to preserve locally reviewed snapshots that upstream has not published
  • Fix the test harness for PacketEvents 2.14.0, and route the 26.x attack packet in the Mineflayer fixture

The library still targets Java 17 bytecode; only the snapshot data, the serializer table, and the tests change.

Why the 26.2 snapshot is not enough

EntityMetadataRegistry.resolveVersion throws for a release newer than the newest bundled snapshot, and VirtualEntity resolves that version from the server release name. On Minecraft 26.3 every metadata-backed entity therefore failed before this change — 323 tests failed with that exact error, which is why a 26.3 snapshot is required rather than optional.

The 26.2 and 26.3 layouts are not identical, so 26.3.json was derived from the official artifact instead of copied. The full derivation, artifacts, hashes, and the validated method are documented in data/entity-data/README.md. Summary:

  • The derivation replays Minecraft's own accessor-id assignment (SynchedEntityData.defineId → ClassTreeIdRegistry.define) over the Mojang-mapped server classes, reading each accessor's generic signature for its dataType and the define(accessor, value) argument for its defaultValue.
  • It was validated by reproducing the already-reviewed 26.2.json byte for byte from the official 26.2 artifact, so the same tooling produced 26.3.json.
  • Compared with 26.2.json, 26.3.json differs in exactly two places: the EnderMan → Enderman class rename (layout unchanged; normalize() resolves both spellings), and the new Cushion entity with one DyeColor COLOR field at index 8 whose DyeColor.WHITE default was recovered from the bytecode.
  • All 185 other classes in the EntityType registry closure have identical layouts and superclass links. minecraft:poplar_boat and minecraft:poplar_chest_boat retarget the existing Boat/ChestBoat classes, so they need no new entry.

Cushion is reachable, not theoretical: PacketEvents 2.14.0 registers EntityTypes.CUSHION, and AllEntityMetadataSchemaTest resolves every registered PacketEvents entity type for every supported server version through 26.3.

Keeping the snapshot under the daily sync

tools/sync-entity-data.sh reinstalls src/main/resources/entity-data from upstream on every run, and upstream still has no 26.3 document (https://kennytv.eu/entity-data/26.3.json → 404). Without a change, the next scheduled run would have deleted the new snapshot and reverted 26.3 support. The sync now backs up the current snapshots, reinstalls upstream data, restores any snapshot that upstream does not publish, and reports what it preserved:

Synced and merged 34 entity-data versions.
Preserved locally reviewed snapshots that upstream does not publish yet: 26.3

Upstream's own document replaces the local copy as soon as it is published.

PacketEvents 2.14.0 harness fix

With 2.14.0 the whole suite died with ExceptionInInitializerError → NullPointerException, because WrappedBlockState.loadMappings0 now dereferences PacketEvents.getAPI().getLogManager() while parsing built-in item component data. PacketEventsTestSupport supplies a mocked LogManager. All 323 pre-existing failures were this plus the missing 26.3 snapshot.

Verification

  • node tools/verify-entity-data.mjs src/main/resources/entity-data data/metadata-flags/semantic-flags.json → Verified 34 snapshots, 5065 entity-data classes, and 5846 declared fields. / Verified 11 reviewed semantic metadata flags across every applicable snapshot.
  • ./gradlew verifyGeneratedMetadataKeys → passes (regenerated GeneratedEntityMetadataKeys contains Cushion.COLOR typed MetadataKey<DyeColor> via EntityDataTypes.DYE_COLOR).
  • ./gradlew cleanTest test → 19171 tests, 0 failures, 0 errors, 0 skipped (was 19170; +1 Cushion test). The two exhaustive matrices are the real cross-validation against PacketEvents 2.14.0 for 26.3:
All-entity spawn wire matrix: serverVersions=60 cases=7017
All-entity runtime schema matrix: serverVersions=60 cases=7017
All-entity schema matrix: snapshots=34 entities=5065 declaredFields=5846
  • ./gradlew build → BUILD SUCCESSFUL (verifyEntityData + verifyGeneratedMetadataKeys + check).
  • ./tools/sync-entity-data.sh → succeeds, reports the preserved snapshot, leaves 26.3.json byte-identical (sha256 verified), and the verifier still passes.
  • Paper + Mineflayer E2E on Paper 1.21.11 with PacketEvents 2.14.0 → passes.
  • Paper 26.3 runtime E2E: the fixture on a real Paper 26.3 build 41 server with PacketEvents 2.14.0, driven by a 26.1 Mineflayer client bridged with ViaVersion/ViaBackwards (Mineflayer cannot speak 26.x yet). This exercises real 26.3 schema resolution (server release name -> bundled 26.3 snapshot), spawn, metadata, relative movement, inbound interaction, Text Display metadata, root-anchor relocation and the atomic packet bundle:
{"entityId":2147483647,"type":"pig","customName":"VE_TEST_PIG","boostTime":10,"relativeMove":true,
 "attack":true,"textDisplay":"VE_TEST_TEXT","rootAnchorRelocation":true,"bundle":true}

Bridged clients are disconnected by the 26.3 server's movement validation, so that harness suppresses client-side movement; no VirtualEntities scenario depends on it.

The Mineflayer fixture on 26.x

Running the fixture against 26.3 exposed a real coverage hole: Minecraft 26.1 moved entity attacks out of ServerboundInteractPacket into a dedicated ServerboundAttackPacket(int entityId), which PacketEvents exposes as PacketType.Play.Client.ATTACK / WrapperPlayClientAttack (INTERACT_ENTITY is -1 for 1.21.11 and 26 for 26.1+; ATTACK is -1 for 1.21.11 and 1 for 26.1+). The library already handles it through VirtualEntityManager.handleInteraction(User, WrapperPlayClientAttack), but the fixture only listened for INTERACT_ENTITY, so attacks were never routed on 26.x. The fixture now handles both packet types, which makes the black-box attack assertion pass on 1.21.11 and 26.3 alike.

Test changes

EntityMetadataRegistryTest: the "latest bundled snapshot" fixture moves to 26.3, 26.2 and 26.3 must agree on the TEXT/TRANSLATION indexes, and a new test asserts registry.schema("26.3", EntityTypes.CUSHION) resolves COLOR as MetadataField(8, "DyeColor", "COLOR", "DyeColor.WHITE").

Notes

  • The Mineflayer integration fixture (and its paper-api/Java targets) intentionally stays on Paper 1.21.11, the newest version the pinned Mineflayer can log in to. It is test scaffolding, not part of the published artifact.
  • New data/entity-data/README.md records the provenance of every locally reviewed snapshot: artifacts, hashes, the validated derivation method, the resulting 26.3 delta, and the remaining uncertainty.
  • Related: the TextDisplayShapes and WorldEditDisplay 26.3 upgrades, which consume this library.

Companion changes

Upgrades the same Minecraft version in the downstream consumers: TWME-TW/TextDisplayShapes and TWME-TW/WorldEditDisplay. Both keep their current v0.9.0 pin in this round and will pick up the explicit 26.3 snapshot once this library is released.

Bundle a reviewed 26.3 entity-data snapshot so the registry no longer
rejects a 26.3 server as newer than the latest bundled snapshot. The
snapshot is derived from the official Mojang-mapped Paper 26.3 artifact
with the same tooling that reproduces the reviewed 26.2 snapshot byte for
byte; it differs from 26.2 only by the EnderMan to Enderman rename and the
new Cushion entity, whose DyeColor COLOR field is at index 8.

- Bump PacketEvents to 2.14.0, the first release with the 26.3 protocol.
- Map the new DyeColor serializer in the runtime type table and the key
  generator so generated keys cover GeneratedEntityMetadataKeys.Cushion.
- Preserve locally reviewed snapshots in the daily entity-data sync
  instead of deleting snapshots that upstream has not published yet.
- Route the 26.1+ attack packet in the Mineflayer integration fixture;
  entity attacks moved out of the interact packet into ServerboundAttackPacket.
- Supply a log manager in the test harness, which PacketEvents 2.14.0
  dereferences while parsing built-in item component data.
- Document the provenance, artifacts and remaining uncertainty of locally
  reviewed snapshots in data/entity-data/README.md.
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