Fix LpVec3 entity velocity decoding (big-endian word + notch units)#1494
Fix LpVec3 entity velocity decoding (big-endian word + notch units)#1494atiweb wants to merge 2 commits into
Conversation
The 32-bit word was read/written little-endian, but Minecraft's LpVec3 uses FriendlyByteBuf.readUnsignedInt/writeInt (big-endian), so every entity velocity decoded to a wrong but same-length (hence silent) value. Also scale the decoded vector to 1/8000-block-per-tick units to match vec3i16, so fromNotchVelocity() consumers work uniformly across versions. Fixes broken entity velocity / knockback on 1.21.9-1.21.11 (mineflayer#3887). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
157649e to
64c8cee
Compare
|
the big endian fix here seems correct but offsetting the generated value by 8000 is redundant and should be handled as a supportFeature in mineflayer. |
|
Thanks — agreed on both. The big-endian read is the core fix (FriendlyByteBuf writes that word with On the ×8000: you're right that it's units-normalization, not wire format, so it doesn't belong here. I added it so mineflayer's existing Updating shortly. |
The 1/8000 notch-unit normalization is a version-specific consumer concern, not wire format, so it does not belong in nmp. LpVec3 now decodes and encodes in blocks per tick (the codec's natural units); mineflayer will gate the /8000 for pre-1.21.9 velocity behind a supportFeature. Keeps the big-endian word fix; round-trip unchanged.
Problem
src/datatypes/lpVec3.js(added in #1453 for the 1.21.9+ entity-velocity encoding) decodes every entity velocity incorrectly. Two separate issues:1. Wrong endianness. The 32-bit word is read with
readUInt32LEand written with a little-endianwriteUInt32LE/writeUInt16LElayout, but Minecraft'snet.minecraft.network.LpVec3reads/writes it withFriendlyByteBuf.readUnsignedInt/writeInt, which are big-endian. The decoded packet is still the correct length, so no parse error is raised — the velocity is just silently wrong. The existing test only covers the zero vector, which is a single0byte and therefore endian-agnostic, so this was never caught.2. Wrong units.
entity_velocity/spawn_entityuselpVec3on >= 1.21.9 andvec3i16on older versions, and consumers applyfromNotchVelocity(÷ 8000) topacket.velocityuniformly (e.g. mineflayerlib/plugins/entities.js, PrismarineJS/mineflayer#3839).vec3i16yields raw 1/8000-block-per-tick units, butlpVec3yielded raw blocks-per-tick — i.e. 8000× too small.Together these break entity velocity / knockback on 1.21.9–1.21.11. See PrismarineJS/mineflayer#3887 ("Bot freezes in mid-air after taking knockback on 1.21.11").
Fix
packed = c << 16 | b << 8 | a(byte,byte,int32big-endian).vec3i16, so the existingfromNotchVelocityconsumers work unchanged across all versions.Validation
test/lpVec3Test.jsdecodes and round-trips velocity payloads captured from a real vanilla 1.21.11 server (e.g.f9ff7ffeebed→ ≈(0, -0.078, 0)blocks/tick) plus the zero-vector single-byte case.(0.087, 0.177, -0.258)blocks/tick and the bot takes knockback normally instead of freezing in mid-air.Reference:
net.minecraft.network.LpVec3.read=readUnsignedByte,readUnsignedByte,readUnsignedInt; the resultingVec3is the entity's blocks-per-tick movement.