replayFrameAt function
The GameFrame for a single replay frame index.
Memoized per (gameId, index): GameRules.parseObservation runs once per
frame no matter how often the user steps back and forth across it. Timing is
always empty, since a replay has no live clocks. Returns null until the frames
and the version unit have both loaded, or for an out-of-range index.
Implementation
@riverpod
GameFrame? replayFrameAt(
Ref ref, {
required String gameId,
required int index,
}) {
final rules = ref.watch(gameRulesProvider(gameId: gameId)).value;
final frames = ref.watch(replayFramesProvider(gameId: gameId)).value;
if (rules == null || frames == null || index < 0 || index >= frames.length) {
return null;
}
final frame = frames[index];
return GameFrame(
observation: rules.parseObservation(frame.data as Map<String, dynamic>),
pendingPlayers: frame.pendingPlayers,
version: frame.version,
// A replay has no live clocks: the deadlines these frames carried have
// long passed, and re-rendering them as countdowns would be nonsense.
timing: TimingContext(clock: ref.watch(serverClockProvider)),
);
}