Entry 67
piney-battle: the rules of combat, the enemies' and party's decisions and items, checked against the game
Documented in Game data tables.
Filescrates/piney-battletools/test_battle_rs.pytools/test_battle_flow_rs.pytools/test_battle_drain_rs.pytools/test_battle_items_rs.pytools/test_battle_enemy_ai_rs.pytools/test_battle_party_ai_rs.pydocs/engine/battle.md
The goal needs the opening's fights. 22 and 25 had worked out
Infection's battle formulas in Python (tools/battle.py). A battle agent
and three helpers have now ported the rules half of combat to Rust as a
pure-logic crate, piney-battle (about 14,000 lines). It has no drawing,
animation or movement: those are the runtime's.
What it holds
- The formulas.
CalcReal;CalcBattleDamagewith the protect gauge and Exdefense;ccSkillDamage's four forms andccSkillDamageValue;- recovery, cures, hold and condition changes;
- experience, levels and erosion;
EntryAffectwith each kind of character'saffectFunc.
- A skill's life.
_ccSkillRequestthroughccSkill::Main(ccThSkill) with its systems,NoteEventAffect, and the player's and fellows' attack notes. - Data Drain.
DataDrainMenu's steps: the drain, the side effect and level down, and evolution. - Items. All of
useitem.cppand the save's item lists. - The enemies' decisions.
enemy.cpp's think, attack, skill and target choices, andgenrand(the enemies' own MT19937). - The party's decisions.
ccAI:Brains,Reconnoiter,ActInField,ActInDungeon, healing, attack choice, chat commands, and its message bus. - The shape. Each rule returns events in the game's call order. A
Scenestands for the three command lists;Randis newlib'srand()andGenrandthe enemies' generator.
Bugs found while merging
_ccSkillCheckTypehad 1 and -2 swapped: 1 is an attack spell, -2 a debuff.ccSkillDamageValuetakes both characters' list checks.- A cure cast on oneself lost its SP change.
ConditionAdjustmentdoes not run every frame.
Checked
-
Against the game. Six harnesses run the game's functions natively in eemu beside the port. Each compares the return value, every character and AI field, both generators' states, and the calls in order. There are 125 checks, each over at least 1,000 random cases, with 0 mismatches. The core, flow and drain checks also passed 10,000 cases each.
harness covers test_battle_rs.pydamage, skills' effects, stats, levels, conditions, experience, erosion, EntryAffecttest_battle_flow_rs.pyccSkill::Main, notes,ccSkillCheck,ConditionAdjustment, level ups,AreaItemtest_battle_drain_rs.pyDataDrainMenusteps 0-1, 10, 20test_battle_items_rs.pyuseitem.cppand the item liststest_battle_enemy_ai_rs.pyenemy.cpp's decisions,genrandtest_battle_party_ai_rs.pyccAIand its message bus -
Re-run in a clean worktree. I re-ran all six there, with the older
test_battle.py: all pass. The workspace's tests pass, and clippy, fmt and the docs check are clean.
- Not in the runtime yet. The crate supplies the rules; nothing in the field calls it. The runtime must still supply: - the characters' animation and notes; - enemy spawning and portals (
ccThEntryCtrl,entryEnemy,entryMagicCircle); - enemy movement and each race'saction(); - party movement (FollowPlayer,FollowTarget,FollowBeacon,ActInTown) andccFellow::Action/Main; - the spells' element systems; - the Data Drain movie and transformation; - damage numbers, hit marks and sounds.