RF455-046 RF 4.55: a shield block shows as a 65534 damage number, because the attack result packs the block marker as a u16
New
Game: RF 4.55 (Dragonborn), server v0.2.0, Windows build (stock gameserver.exe, SHA-256 96452fbd…).
Client: the supported Taiwan build, RF_Online.bin SHA-256 46528aac…2bbc558 (2025-07-16), Language=Taiwan.
Summary
- With a shield equipped, about one monster hit in five shows 65534 floating over the character.
- HP doesn't change on those hits: they are blocks, and no damage was taken.
- The server marks a block with damage 0xFFFE, packed as a u16.
- The client reads each target's damage as a u32, and knows a block only as −2 (0xFFFFFFFE). It reads
FE FF 00 00as 65534 and draws it.
Server side
(*Server).monsterMelee0x140886280, afterrollBlock:
140886a75: movzx edx, byte ptr [rsp + 0x377] ; blocked 140886a83: mov edx, 0xfffffffe 140886a88: cmovne cx, dx ; damage u16 = 0xFFFE 140886a8c: mov word ptr [rsp + 0x3a8], cx ... 140886ac0: call protocol.AttackGenResult
protocol.AttackGenResult0x140643020writes 11 + 10·n bytes: each target isu8 kind, u32 serial, u16 damage, u8 flag, u16.
Client side (RF_Online.bin)
attack_gen_result_zoclis at0x5a4a10, with 05/08 at0x5a4c50and 05/09 at0x5a4eb0.- The target list is read by
0x5a42d0with a 14-byte stride:u8 kind, u32 serial, u32 damage (+5), u8 (+9), u32 (+0xA). 0x5a3cff:cmp dword [entry + 0x3c], -2. If it's equal, the damage becomes 0 and0x5a3f30(1)plays the block. Otherwise the value is drawn.0x5a359c: −1 is a miss in the same way.
Captured (05/07, a Crawler Bunch hitting a level 30 Accretia with a shield)
01 F5 56 0F 00 | 00 FF FF 00 00 | 01 | 00 5A 0C 00 00 FE FF 00 00 00
The damage reads as u32 0x0000FFFE = 65534. The 11/0D that follows every real hit is missing after this one.
Expected
The block shows as the client's block, not a number. For example, send the damage as a u32 −2. The 14-byte entry layout the client reads would also fix multi-target results: with 10-byte entries, every target after the first is misread.
Workaround
A client-side shim sets the two bytes after the u16 to FF FF when it reads FE FF 00 00. The client then
reads −2 and shows a block.
History
-
cybercyber