RF455-098 RF 4.55: monster special attacks deal no damage, and specials with a cast condition never fire
Game: RF 4.55 (Dragonborn), server v0.3.1, Windows build (stock gameserver.exe, 22,061,568 bytes).
Client: the supported Taiwan build, RF_Online.bin SHA-256 46528aac…2bbc558 (2025-07-16), Language=Taiwan.
Data: the shipped db\gamedata_rf455.db.
Summary
Two gaps in monster specials (monstercharacterai):
- A special with a cast condition never fires.
rollMonsterSpecialskips every AI row whosem_nMotiveConditionisn't 0, instead of checking the condition (e.g. "HP below 60 %"). That is 241 of the 482 AI rows, and 255 monster rows have no special that can ever fire. - A special that fires deals no damage. On the player side GoMMO only installs the special's continuous effect. 82 AI rows that can fire are attack skills/forces with no continuous effect (Frost Nova, Poison Stinking, Aqua Blade…), so they do nothing. 143 monster rows have one.
Also, the 8 AI rows that can fire with m_nDstType 2 return without doing anything. rfdatabase.net lists the same
specials for these monsters (e.g. Sandworm → Poison Stinking), and its force pages give them damage. Read from the
code and data (static); not live-tested.
The server (read, v0.3.1)
- Loading.
gamedata.(*Data).loadMonsterSkills0x14050c320reads 13monstercharacteraicolumns (SELECT at VA0x140bed28b) into a 0x78-byte row:m_nMotiveCondition+0x38 (scanned into a temporary, stored at0x14050c6b0),m_nMotiveValue+0x40,m_nMotiveTime+0x58,m_nDstType+0x60,m_nLimitCount+0x68,m_nProbability+0x70. A monster's rows are them_strSPCodevalues inmonstercharacter__m_strspcode. - Which rows can fire.
(*Server).rollMonsterSpecial0x1408b90c0(its only caller ismonsterMelee, after the melee damage is applied) gets the rows fromMonsterSkillsForand copies each one torsp+0xd0. For each row:m_nMotiveCondition≠ 0 → skipped (0x1408b9393 cmp [rsp+0x108],0; jne).m_nMotiveValueand the exception fields are never read.m_nLimitCount> 0 and the use count has reached it → skipped.- The
m_nMotiveTimecooldown hasn't run out → skipped. m_nProbability≤ 0, orrand.Intn(100)≥m_nProbability→ skipped, and the cooldown restarts (m_nMotiveTimeseconds, 10 s when ≤ 0).- Otherwise the use count goes up, the cooldown starts, and
fireMonsterSpecialruns on that row.
- What it does.
(*Server).fireMonsterSpecial0x1408b9880resolves the code (ResolveSFCode,resolveSFEffectOK; it returns if either fails), then branches onm_nDstType([rsp+0x2d0]):- 1:
fireMonsterSelfSpecial0x1408b8ce0(on the monster itself,applyMonsterAffect); - 2: returns at once (
0x1408b992e→0x1408b9eb9); - otherwise: a range check on
m_fSpecialRange, thenapplyContEffectTo0x1408968e0at levelm_nAttLvclamped to 1..7, thensendMonsterAssist(the broadcast).
- 1:
applyContEffectTois the affect system only (haveEffect,addAffectFrom,refreshEffectState,scheduleAffectExpiry,notifyPartyEffect,checkAlterMaxPoint…). No HP change on any path.(*client).applyDamage0x1407d8700is called bymonsterMelee,animusStrikePlayer,pvpStrike,towerHitPlayer,trapHitPlayer,nuclearHitandactTransDestHP. No special path reaches it, and the server has no damage-over-time code.
The data (read, gamedata_rf455.db)
- 482 AI rows:
m_nMotiveCondition0 on 241 rows, 1 on 223 (a value 5–90, inferred to be an HP %), 2 on 11, 3 on- Of the 241 that can fire, 8 have
m_nDstType2. No row has a probability ≤ 0.
- Of the 241 that can fire, 8 have
- Attack specials (a skill/force with
m_nAttackable/m_bAttackable= 1 andm_nContEffectType−1): 184 rows; 82 can fire (no damage), 102 have a condition (never fire). Monster rows: 347 have one, 143 have one that can fire. - The firing attack specials most used (monster rows): Frost Nova
930925, Poison Stinking940121, Aqua Blade930510, Frost Arrow93049, Gust Of Blast95088, Rock Blade94048, Poison Breath94057. - Examples:
- Sandworm and Anabola (
02B00,02A00, level 31): Poison Stinking, condition 0, probability 100, every 10 s. It fires and does nothing. - DagnuYoungFlam (
0BE03, 12): Electric Bolt9504, condition 0. It fires and does nothing. - Robust Lava (
03A00, 36): Electric Ball9500with condition 1, value 60. It never fires. - Chuty
0590B: Healing7104on itself (condition 1, value 50; and condition 2, value 90,m_nDstType2). Neither ever fires.
- Sandworm and Anabola (
Expected
- A special with a motive condition fires when the condition holds (inferred: condition 1 = the monster's HP below
m_nMotiveValue%; 2 and 3 not known here). - An attackable special deals its force/skill damage to the player (as the same code does when a player casts it), plus its continuous effect if it has one.
- What
m_nDstType2 means isn't known here (inferred: an area or party target); it should do something.
How to see it
Let a Sandworm (level 31) fight you for a minute. Its Poison Stinking should land every 10 s, and your HP drops
only by its melee hits. (fireMonsterSpecial writes a debug-level log line, "monster special landed…", each
time.) A Robust Lava should never cast Electric Ball, even below 60 % HP.
Related
- RF455-094New (zero-value effects): Spin A Web / Entangle
9407(Wheel, Chuty…) has no state reader. - RF455-093New (instant effects) would also stop Healing
7104as a self special, but Chuty's Healing rows never fire in the first place (condition ≠ 0).