Narrate the battle in the event log, synced to the replay step.

This commit is contained in:
Greyson Parrelli
2026-07-23 08:07:17 -04:00
parent 506c6e5b55
commit 63b64bc1d8
5 changed files with 151 additions and 26 deletions
+5 -2
View File
@@ -1,4 +1,5 @@
import { useEffect, useMemo, useState } from 'react'
import type { Dispatch, SetStateAction } from 'react'
import { createPortal } from 'react-dom'
import type { BattleEvent, Card, ClientMessage, GameView } from '../types'
import { CardView } from './CardView'
@@ -8,6 +9,9 @@ import { artFor } from '../petArt'
interface Props {
view: GameView
send: (msg: ClientMessage) => void
// Step is owned by Table so the event log can stay in sync with the replay.
step: number
setStep: Dispatch<SetStateAction<number>>
}
interface UnitVis {
@@ -171,10 +175,9 @@ function unitPop(ev: BattleEvent | null, seat: number, events: BattleEvent[], st
// BattlePhase plays back the battle log: cards flip off each deck, rocks
// fly, pets clash, the fallen fade out, then the round result lands.
export function BattlePhase({ view, send }: Props) {
export function BattlePhase({ view, send, step, setStep }: Props) {
const battle = view.battle!
const events = battle.events ?? []
const [step, setStep] = useState(0)
const [acked, setAcked] = useState(false)
// The deck-peek popover lives inside .battlefield, which sets overflow-x
// (and thus overflow-y) to auto — so an absolutely-positioned popover gets