Modules / Networking

rewindaddon

A late press put back on the step it was made on.

Putting it in a scene

A scene is run by rewind, and its pages run it ahead (see predict), when its world.predict holds exactly the five numbers shown here. A scene with no world.predict keeps nothing: the server answers every message on the first step after it arrives, and its pages draw the server's packets.

"world": {
  "predict": { "epsilon": 0.01, "cutoff": 12, "halflife": 100, "snap": 2, "below": 0.001 }
}

The server never waits for a page. A page stamps each press with the step its own copy answered it on, and the press reaches the server after the server has run that step. The server then loads its truth as it stood before that step, takes the press there, and plays on one step for each step of its clock, taking again every message it took on the steps it passes. Its truth therefore stands as many steps behind its clock as the press was late, and the server is never sped up to catch up. The page that pressed sees its press where it made it, so lag is never punished.

Properties

Read from world.predict. A block of any other shape is refused.

.cutoff : number

A whole number of steps, 1 or more. It is the furthest the server goes back for a press, and so the furthest its truth ever stands behind its clock. The server keeps its truth as it stood before each of its last cutoff steps. A page's press reaches the server a round trip after its step, so cutoff must cover the round trip in steps.

A message stampedIs answered
At the server's current step or later, up to cutoff steps aheadOn its stamped step.
More than cutoff steps ahead of the server's clockOn the next step the server runs.
Before the server's current step, within cutoff stepsOn its stamped step, which the server goes back to.
Before the server's current step, further back than the server keepsOn the next step the server runs. The page that sent it is told and moves it there in its copy.

.epsilon, .halflife, .snap, .below

The page's numbers: how far its copy may differ from the server and how a jump is smoothed. They are described on predict.

What the server keeps

Before each step the server saves its truth, with the memory each row's kind holds beside the rows (see Memory). Every message that reaches the truth between two steps is kept with the step it reached it before, whether it came from a page, the playtester, a scene's entry act or an arrival. So is every change made through change, such as a seat joining or leaving.

A truth changed between two steps in any other way, such as a rule run from outside a step or a persist load landing, cannot have the steps before that change passed again without it. The saves before it are let go, and a late press never reaches back past it.

The journal

Every message, as the truth answers it and stamped with the step it is answered on, and every change, stamped with the step it was made before, is written down in order and kept for twice cutoff steps. The server sends it to every page of the scene. Each page puts every entry into its own copy, going back to the entry's step as the server did.

Memory

Members of a kind's sim, for a kind that keeps state beside its rows which a saved truth does not carry, such as a physics library's world, its contacts and its sleeping bodies.

hold( row ) : unknown

Hands out the memory of the row without changing it, as JSON and Uint8Arrays. A physics world's image is the library's own bytes, kept as they are; socket carries them as bytes. It is asked when the server saves the truth for a page that asks for it, and before each step on a server that rewinds.

take( row, held, was? )

Handed the memory hold gave, on a truth loaded from that save, before the truth's next step, so the truth steps on exactly as the one it was saved from did. was is the row of the same id the truth held before the load, when it had one, whose memory the kind may reuse.

Methods

rewind( truth, cutoff, options? ) : Rewind

Makes a truth rewind. Called by the scenemanager for each rewinding scene on the server, and by a page that runs ahead for its own copy.

OptionMeaning
capDefault true. A message stamped more than cutoff steps past the truth's clock is answered on the step about to run, as a server must treat a page. A page's copy, handed the server's own stamps, sets this false and takes every stamp as it is.
fastDefault false. After going back, run every step again up to where the truth stood, within the step it is given, so it never stands behind where it was. A page's copy, which the player watches, does this. A server, which must spend no more than a step's time on a step, does not.
steppedCalled after every step the truth runs.
horizonReturns the oldest step a late message or change may still be put back on. Every save before it is let go. Left out, cutoff steps before the truth's clock.

The Rewind it returns has these members:

MemberMeaning
step(dt)One step of the truth, every late message and change put back first.
take(seat, msg)A message as it arrived: held for its step, or put back on it.
change(op, f)Makes a change now, between two steps, and returns what f hands back. The steps passed again make it again on the step it was made before.
schedule(at, op, f)A change made before step at: made when the truth reaches that step, or put back there if the truth has passed it.
move(seat, from, msg)Moves a message of the seat's that the truth took on step from to the step msg.n the server answered it on. Returns false and does nothing when the truth no longer keeps step from.
journal(from), end, baseThe journal's entries from place from on, the place the next entry will take, and the first place it still holds.
back, missedHow many steps the truth went back in all, and how many late messages and changes were later than the truth keeps steps and were taken on the next step instead.
waiting, drop()How many late messages and changes wait for the next step to put them back, and a call that lets every one of them go, for a truth loaded from a save that some of them may already be in.
clockReal time, in steps. A page's copy sets it back after running a snapshot up to where it stands.
earliest()The truth as it stood before the oldest step kept, with what each kind held then. A page that runs ahead starts from it, so every late message the server may yet put back lands on a step the page's copy holds too.

rewinding( truth ) : boolean

True from the moment the truth goes back until it stands again where it stood. Whatever runs on a truth's steps from outside, such as the playtester thinking, persist writing, or heard writing down what the steps answered, calls this and does nothing it already did.

onRewind( truth, f )

Calls f each time the truth has gone back. The rows are new objects then, so anything that holds rows takes them again.

onRestore( truth, f )

Calls f with the save each time the truth is put back to one, before it runs a step from it. The player addon uses it to take back which slot each seat holds.

restore( truth, snapshot, memory )

Puts a truth back to a save. Each row's kind is handed what it held beside that row, with the row of the same id it had before the load, and whatever keeps state of the truth's seats is told.

held( truth ) : Record<number, unknown>

What each row's kind holds beside the rows, by row id.

reach( truth ) : number

The oldest step a rewind of the truth may still run again. When nothing rewinds the truth, the step it is about to run.

predicts( world ) : Predict | undefined

Reads world.predict of a scene file: its five numbers, or undefined when the scene is not run ahead.

Used by

  • scenemanager
    Runs each scene that has a world.predict by rewind.
  • predict
    Runs a page's copy of the scene by a rewind of its own.
  • heard
    Writes down a message once, not again when the steps are run again.
  • player
    Takes back which slot each seat holds when the truth is put back to a save.
  • persist
    Writes nothing it already wrote while the truth is rewinding.
  • box3d
    Hands its physics world through Memory.
  • box2d, hitscan3d, loader
    Also use it.

In the guide