RF455-102 RF 4.55: eight siege kits (Beelzebub and the four late "Siege Kit" rows) have level 30 in gamedata; the client says 75, 80 or 100
New
Game: RF 4.55 (Dragonborn), server v0.4.0, Windows build (stock gameserver.exe, SHA-256 0b9c9099…), its
gamedata_rf455.db.
Client: the supported Taiwan build, RF_Online.bin SHA-256 46528aac…2bbc558 (2025-07-16), Language=Taiwan,
its DataTable\Item.edf.
Expected: a siege kit needs the level the client's item data gives it, which the tooltip shows as Required
Level (for sklu029: 80).
Summary
- In
gamedata_rf455.db,siegekititem.m_nLevelLimis 30 for every row from 18 on. The client's own item data gives rows 22–29 levels 75, 80 or 100:
| Row | Code | DB name | DB m_nLevelLim | Client level |
|---|---|---|---|---|
| 22 | sklu023 | Attack Beelzebub Siege Kit | 30 | 75 |
| 23 | sklu024 | Defence Beelzebub Siege Kit | 30 | 75 |
| 24 | sklu025 | Siege Kit | 30 | 100 |
| 25 | sklu026 | Attack Beelzebub Flame Siege Kit | 30 | 75 |
| 26 | sklu027 | Defence Beelzebub Flame Siege Kit | 30 | 75 |
| 27 | sklu028 | Siege Kit | 30 | 100 |
| 28 | sklu029 | Siege Kit | 30 | 80 |
| 29 | sklu030 | Siege Kit | 30 | 80 |
- In play the client enforces its own level, so a normal player can't use these kits early. Our level-46 Accretia holding
sklu029(tooltip: Required Level 80, in red) tried to go into siege mode with it and couldn't. The server'shistory.logshows no 1C/01 at all during that try (the last one is 21:31:20, with kit index 1), so the client refused locally and never asked the server (read from the log; the client code that refuses wasn't traced). - The server's own check is looser (read): it uses the DB value, so it would accept 1C/01 for these kits from level 30. Only a client that skips its local check reaches that. Crafting and upgrades also read this column on the server (below).
- So this is a data inconsistency with low impact today, not a way to use the kits early.
- These are the same rows your client sync already corrected for other columns (
_client_synced_cells, source "RFOnline Taiwan Updated DataTable item.dat#27":m_nDurUnit,m_nSubType,m_nIconIDX, the four effects,m_nStdPrice…), butm_nLevelLimwasn't among them for this table. - Every other item table agrees with the client on the level limit (below), so this looks limited to these rows.
Server side (v0.4.0)
- The check.
(*Server).checkSiegeTransform0x1409473e0(1C/01) callssiegeKitLevelAllows0x14094b640(call at0x1409477e1). It loads the kit withsiegeKitField0x14094b1c0and compares the struct's+0x28withprogressLevel+equipLevelBonus: allowed whenLevelLim <= level + bonus(cmp [rsp+0xf8], rcx,setle alat0x14094b77f). +0x28isLevelLim: theSiegeKitFieldtype descriptor0x140b8e7c0(size 0xB8) listsUsableType+0,SubType+8,Civil+0x10,DurUnit+0x20,LevelLim+0x28,UpLevelLim+0x30, …- It comes from the DB:
gamedata.(*Data).SiegeKitByIndex0x140538a80runsSELECTm_nUsableTyoe,m_nSubType,m_strCivil,m_nDurUnit,m_nLevelLim,m_nUpLevelLim, … FROMsiegekititemWHEREm_dwIndex= ?(string at0x140c2a43a). - Crafting and upgrades read the same column through
ItemEquipLevel/equipLevelOf(SELECT m_nLevelLim FROM <table> WHERE m_dwIndex = ?; callersplanUpgrade,craftSuccessPercent,informCraftMastery). - These four functions are identical in our patched build and the stock one (
gosyms.py diff).
Client side
- The decrypted
Item.edfis a chain of sections, one per item table (siege kit = section 27: 31 records of 240 bytes, each starting with itsm_dwIndex). The level limit is the byte at record+0xAC. For rows 0–21 it equals the DB on every row; for rows 22–29 it holds 75, 75, 100, 75, 75, 100, 80, 80. - The tooltip agrees:
sklu029(row 28) shows "Required Level 80". - The same comparison over every item table (about 87,000 rows: armour, weapons, accessories, ammo, potions, boxes, traps, towers, unit parts…) finds only one other difference:
radaritemrow 6rdetw00, DB 40, client 30. The radar query (RadarItemRecord,SELECTm_dwIndex,m_strCode,m_fActDelay, … FROMradaritem) doesn't read the level, so that one has no effect on the server today.
Tried in game (2026-10-14, after 21:35): a level-46 Accretia couldn't go into siege mode with sklu029 (client
level 80, DB 30). history.log has no 1C/01 from that try, so the client stopped it before sending; the server's
check was never reached.
Suggested fix
- Set
siegekititem.m_nLevelLimfor rows 22–29 to the client's values (75, 75, 100, 75, 75, 100, 80, 80), for instance by adding the column to the client sync for these rows. Then the server's check matches the client's instead of relying on it, and crafting and upgrades use the right level. - Optionally
radaritemrow 6m_nLevelLim40 → 30, for consistency.
Local workaround
None