Options
All
  • Public
  • Public/Protected
  • All
Menu

This holds multiple frames of the simulation at one time along with the necessary information to rewind and replay the simulation so that we can feed "old" state packets in to the simulation, and re-simulate the new state based on that revision of history. A packet can be "old" either because it was sincerely delayed OR because we're intentionally trying to render a simulation time that is greater than servertime - one-way-latency (i.e we're doing client side prediction to get ahead of what the server has had time to confirm and send). Either way this simulation approach allows us to take server data that was for a few moments ago and reasonably validly work it in to our simulation..

TODO Investigate using a WebWorker so that simulation can run in parallel to the render thread. Note that WebRTC is not available to WebWorkers currently so the render thread would still need to marshall updates from the network to the webworker.

Another TODO, if the client cannot keep up with the server its simulation will fall behind until it explodes, need to figure out how we can detect it / relieve pressure etc. I'm not sure how to deal with it yet so we'll just let it explode for now. It may well require a negotiated state flush of some sort from the game server similar to reconnect.

Hierarchy

  • ClientSimulation

Index

Constructors

constructor

Properties

Private Optional firstEverFrameIndex

firstEverFrameIndex: number

Private frames

Private Optional largestInitializedFrameIndex

largestInitializedFrameIndex: number

An integer that represents the largest frame we have initialised so far.

Private Optional oldestDirtySimulationFrameIndex

oldestDirtySimulationFrameIndex: number

An integer that represents the oldest simulation frame for which we have received modifications that have not yet been propagated. Any time a historical frame is modified we drop this number to match it so that we re-simulate from that frame back to the desired frame.

Private Optional playerId

playerId: PlayerId = ...

Methods

Private applyAuthoritativeStateToResolvedState

Private applyPredictedOrAuthoritativeInputsToResolvedInputs

doSimulationWork

  • doSimulationWork(simulationTimeS: number): void
  • This is not meant to be called by users of library. TODO create external interface for this class.

    Performs any outstanding simulation work between the "dirty" checkpoint and the requested simulationTimeS Simulation will be done for the next frame to occurr after simulationTimeS on the assumption that there may be interpolation between the preceeding and subsequent frame. Uninitialised frames will be added as we go.

    Parameters

    • simulationTimeS: number

    Returns void

getCurrentSimulationTimeS

  • getCurrentSimulationTimeS(): undefined | number
  • This is the estimate of the current simulation time on the server. undefined is returned when we are not synchronised with the server.

    Returns undefined | number

getInputTravelTimeS

  • getInputTravelTimeS(): undefined | number

Private getOldestInitializedFrameIndex

  • getOldestInitializedFrameIndex(): undefined | number
  • The oldest frame that we still have data for. This starts equal to largestInitializedFrameIndex, and ramps up to however many frames we store behind largestInitializedFrameIndex

    Returns undefined | number

Private getOrInsertFrameWithoutSimulation

  • Gets the frame data for frameIndex, initializes any new frames up to that index, does NOT perform any simulation on any new frames that are added Returns undefined if frameIndex is so far in the past that it is no longer available.

    Parameters

    • frameIndex: number

    Returns undefined | ClientSimulationFrameData

getOwnPlayerId

  • getOwnPlayerId(): undefined | PlayerId

getSimulationFrames

Private getSuccessorFrameForSimTime

  • getSuccessorFrameForSimTime(simulationTimeS: number): undefined | number
  • Does a binary search of the frames in order to find the smallest frame index with a simulation time greater than the given param. Note this can return dirty / unsimulated frames. Returns undefined if there is no simulation frame less than the given simTime

    Parameters

    • simulationTimeS: number

    Returns undefined | number

Private insertNewFrame

Private markFrameAsDirty

  • markFrameAsDirty(frameIndex: number): void

notifyInputBeingSent

  • notifyInputBeingSent(inputFrame: InputFrame, targetSimulationTimeS: number): void

onFrameDeletionsMessage

onFrameInputsUsedMessage

onFramecomponentStateMessage

onPlayerIdAssigned

  • onPlayerIdAssigned(playerId: PlayerId): void

Private simulateOneFrame

Generated using TypeDoc