Skip to content

fix: decode 32 bit qangle_precise fields as three raw floats - #67

Merged
osztenkurden merged 1 commit into
osztenkurden:masterfrom
LukasW1337:fix/qangle-precise-32bit
Sep 23, 2026
Merged

osztenkurden merged 1 commit into
osztenkurden:masterfrom
LukasW1337:fix/qangle-precise-32bit

Conversation

@LukasW1337

Copy link
Copy Markdown
Contributor

Demos from CS2's new rush map (rush_001, build 2000913) fail during entity creation with MALFORMED U64.

The conveyor belts (CFuncConveyor) use CBodyComponentBaseModelEntity, whose m_angRotation is declared with the qangle_precise encoder and a bit count of 32. The server writes it as three full 32-bit floats, but findDecoder returned QanglePresDecoder for every qangle_precise field, reading a presence bit per component (3 bits for a zero angle) instead of 96. Everything after the field was then decoded at the wrong offset.

With this change, a qangle_precise field with 32 bits falls through to findQAngleDecoder, which already picks Qangle3Decoder (same as the 32-bit aim punch angles).

2.7.0 without this change (658fe93):

  • entities: EntityMode.ALL -> MALFORMED U64
  • entities: EntityMode.ALL, entityClasses: 'all' -> MALFORMED U64

entityClasses doesn't avoid it since every class is still decoded; the problem is the bit count.

With this change, both modes complete, and the 3 conveyors decode sanely: m_angRotation [0,0,0], m_flScale 1, m_flTargetSpeed 4096, cells (30,16,32) / (24,16,32) / (14,16,32), stable m_hModel per conveyor. Another build 2000913 demo (de_anubis) is unaffected. New unit tests check decoder selection and that exactly 96 bits are consumed; all 1024 unit tests pass.

Demo for testing

CS2 declares CBodyComponentBaseModelEntity.m_angRotation with the
qangle_precise encoder and a bit count of 32, and the server writes it
as three full 32 bit floats. findDecoder returned QanglePresDecoder for
every qangle_precise field, which reads a presence bit per component
(3 bits for a zero angle) instead of 96 bits, so everything after the
field was decoded at the wrong offset.

This showed up on demos from CS2's new rush map (rush_001, build
2000913), whose conveyor belts (CFuncConveyor) use that body component,
failing entity creation with "MALFORMED U64". The field layout itself
is not new, it only needs a map that spawns such an entity.

Only take the precise path when the bit count is not 32, so the field
falls through to findQAngleDecoder, which already picks Qangle3Decoder
for it (the same decoder used by the 32 bit aim punch angles).
@osztenkurden
osztenkurden merged commit 1cfd219 into osztenkurden:master Sep 23, 2026
3 checks 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.

2 participants