pub struct RollbackSession<State: Clone + Debug, Input: Clone + Debug + PartialEq> { /* private fields */ }Expand description
The whole rollback loop for one peer, wired.
It owns a StateHistory, an InputTimeline per player, and the current
frame, and drives the predict / detect / rollback / re-simulate cycle against
a deterministic step you supply. The primitives stay public for anyone who
wants to wire the loop differently; this is the ready-made path, the rollback
counterpart to crate::PredictedPlayer.
Each peer runs its own session and calls its local player index the “local” one; the two are otherwise identical: both re-simulate to the same state from the same inputs.
// Two players; the deterministic step advances the shared world one frame.
let mut session = RollbackSession::new(initial_world, vec![NEUTRAL, NEUTRAL],
RollbackConfig::default(), step);
// Each frame: feed the local input, fold in any remote inputs that arrived,
// then advance (which rolls back first if a remote input disproved a guess).
session.queue_local_input(LOCAL, my_input);
for (frame, input) in inbox.drain() { session.confirm_remote_input(REMOTE, frame, input); }
session.advance_frame();
draw(session.state());Implementations§
Source§impl<State: Clone + Debug, Input: Clone + Debug + PartialEq> RollbackSession<State, Input>
impl<State: Clone + Debug, Input: Clone + Debug + PartialEq> RollbackSession<State, Input>
Sourcepub fn new(
initial_state: State,
neutral_inputs: Vec<Input>,
config: RollbackConfig,
advance: fn(&State, &[Input]) -> State,
) -> Self
pub fn new( initial_state: State, neutral_inputs: Vec<Input>, config: RollbackConfig, advance: fn(&State, &[Input]) -> State, ) -> Self
Creates a session over neutral_inputs.len() players, starting from
initial_state. neutral_inputs[p] is the input assumed for player p
before any of its inputs are known (typically “no input”). advance is the
deterministic step: same state and inputs in, same state out, every time and
on every peer, which is what rollback rests on.
Sourcepub fn with_predictor(self, predictor: fn(&Input, Frame) -> Input) -> Self
pub fn with_predictor(self, predictor: fn(&Input, Frame) -> Input) -> Self
Replaces the input predictor (default: repeat_last_input). A predictor
takes the last confirmed input and the frame being predicted and returns the
guess for that frame.
pub fn num_players(&self) -> usize
Sourcepub fn current_frame(&self) -> Frame
pub fn current_frame(&self) -> Frame
The next frame to be simulated. state is the world at the
start of this frame, i.e. after every frame before it.
Sourcepub fn state(&self) -> &State
pub fn state(&self) -> &State
The world as it stands now: the present the peer renders. Includes the effect of every predicted input still awaiting confirmation.
Sourcepub fn state_at(&self, frame: Frame) -> Option<State>
pub fn state_at(&self, frame: Frame) -> Option<State>
The world at the start of frame, if still retained. This is the saved
state, so for a fully-confirmed frame it is identical on every peer.
Comparing two peers here shows whether they are in sync. Returns the
present for the current frame.
Sourcepub fn set_rollback_enabled(&mut self, enabled: bool)
pub fn set_rollback_enabled(&mut self, enabled: bool)
Turns rollback on or off (on by default). With it off the session still predicts and advances, but never restores or re-simulates: it trusts every guess permanently. Do not ship with it off, because predictions that are never corrected drift a peer out of sync. It is useful for measuring what rollback contributes. A delay-based front end also turns rollback off with it when it waits for inputs instead of predicting them.
Sourcepub fn queue_local_input(&mut self, player: usize, input: Input)
pub fn queue_local_input(&mut self, player: usize, input: Input)
Supplies the local player’s input for the current frame. Local inputs are
known before their frame runs, so they are never mispredicted. Call once per
frame before advance_frame.
Sourcepub fn confirm_remote_input(
&mut self,
player: usize,
frame: Frame,
input: Input,
)
pub fn confirm_remote_input( &mut self, player: usize, frame: Frame, input: Input, )
Folds in a remote input that has arrived for a past or current frame. If it
contradicts the guess already used for an already-simulated frame, the
session marks that frame for rollback on the next
advance_frame.
Sourcepub fn advance_frame(&mut self)
pub fn advance_frame(&mut self)
Advances the simulation by one frame: first rolls back and re-simulates if a confirmation disproved a guess, then simulates the current frame, predicting any input not yet known.
Sourcepub fn is_frame_confirmed(&self, frame: Frame) -> bool
pub fn is_frame_confirmed(&self, frame: Frame) -> bool
Whether every player’s input for frame is confirmed (none predicted). A
delay-based peer waits for this before advancing; a rollback peer ignores it
and predicts. Which to do is the app’s policy, so this only reports.
Sourcepub fn confirmed_frame(&self, player: usize) -> Option<Frame>
pub fn confirmed_frame(&self, player: usize) -> Option<Frame>
The newest frame this player’s input is confirmed through, or None.
Sourcepub fn prediction_horizon(&self) -> usize
pub fn prediction_horizon(&self) -> usize
How many frames the present is running ahead of the least-confirmed player: the depth of prediction currently exposed to a rollback. Zero when every input is known up to the last simulated frame.
Sourcepub fn last_rollback_frames(&self) -> usize
pub fn last_rollback_frames(&self) -> usize
Frames re-simulated by the most recent advance_frame
(0 if it did not roll back).
Sourcepub fn max_rollback_frames(&self) -> usize
pub fn max_rollback_frames(&self) -> usize
The deepest rollback seen so far, in frames.
Sourcepub fn rollback_count(&self) -> u64
pub fn rollback_count(&self) -> u64
How many times the session has rolled back.