- replay the shooter's combat update a second time when it launches a
projectile, matching the client's own component-pass re-entry
- carry the shooter's damage effect on every projectile and null a
shot's target/source when either leaves the board
- derive pending physical damage from the shots actually in flight
instead of an incremental total, so it can never go negative
- split the spawn ring's two angle registers so three- and five-unit
cards land where the client puts them
- attribute a combat target left at NONE to the exact site that did it,
gated to report each object once
- number and annotate every checksum field so a client-reported
mismatch resolves straight to a name
the decks were the visible half: LogicBattle carries one LogicSpellDeck
per player and we wrote both as absent, so the client cleared them and
the card bar came up empty. both sides get a real deck now - the player
from their profile, the bot from the fullest row of predefined_decks.
matchmaking no longer picks a row out of npcs.csv. it takes the location
from the arena's PvpLocation column and builds an opponent avatar with
its own name, arena and trophies, so the battle reads as a player match
rather than a trainer one. StartMissionMessage still goes through the
npc path unchanged.
the battle type stays 1 on purpose. LogicGameMode::isImmediateMessageExecution
is (type - 1) < 3, so 1, 2 and 3 let the client simulate locally while 0
makes it wait for the server to drive the sector - which needs the real
tick loop we do not have yet.