Field banter playback timing: lines fire on the resolved action, not the cast moment; authoring sim flags where banter would run dry
2026-06-06
Lines fire on the resolved action, not the cast. Previously every line in a turn fired at the cast moment, which read as a wall of chatter and didn't line up with what was happening on screen. Now: a caster's line plays on the damage their cast deals, a hit line on the damage landing on the hero, a heal line when the heal lands. The damage and heal steps carry the caster id so the renderer knows who's speaking.
Skip-fallback gets its own beat. A hero who did nothing and wasn't hit gets an ACTOR_SKIPPED beat, but only when a line is actually baked for them — otherwise playback runs unchanged. No empty pause for heroes with nothing to say.
Camera-aware bubble. When a line fires, step auto-advance freezes for one second so the bubble is readable on the stationary hero, then the bubble keeps tracking the cell as the camera moves away and dismisses about half a second later. Pause and bubble lifetime are decoupled — the bubble can outlive the pause as the camera repositions.
Authoring sim for banter gaps. The selection logic is server-authoritative and has a six-fight dedup window per pool, so it's not obvious by reading the data where banter would go quiet. The new sim drives the real selector — same window, same caps, same gating — over a worst-case fight run and reports two things: static gaps (party-reachable pool keys with zero authored exchanges) and window-exhaustion gaps (the first fight a pool runs out of fresh options, plus how many silent fights follow). On the current data set, no static gaps; pools with fewer than six exchanges drain under worst case — a pool needs at least six exchanges to never go dry inside the window.