Skip to content

five-on-it / packages/net-client/src/mirror

packages/net-client/src/mirror ​

The client's copy of the server world. Every entity in a snapshot gets a physics twin in the local simulation: the one the player controls is predicted and reconciled by the Predictor; every other twin is set to its snapshot pose, so the predicted car collides with other cars and characters where the server will make it collide, instead of driving through them until the correction arrives. Twins of entities that leave the snapshot are removed. The level's light pieces lie where the server has them: loose at the snapshot's pose, planted again once it lists them no more. The level's doors stand open or shut, locked (by a key or a keypad) or not, and its security cameras on, off or destroyed, as the snapshot says; items on the ground, containers, terminals and the nail strips laid on the roads get twins of their own (so the predicted car's tyres pop where the server's do; a container's or a terminal's box blocks the predicted character as the server's does); a character's role comes with it (a contact the prompt says Talk at), its body too (a dog's twin is a dog's low capsule, so the predicted car meets it, and a shot passes over it, as on the server), and why it lies down (a body the prompt offers to search), and so does a player's ghost after respawning (the twin passes through cars as the server's does); the player's inventory and the container they have open are the server's word too (Mirror.applyInventory), so the local interaction rule sees the keys the player holds and the panel they have open. Every car's owner, lock and paint are the server's too, so the prompt knows a locked car from the player's own; how far the player has picked a lock is the server's word (Mirror.picking), never predicted.

Which entity the player controls follows the snapshot: their character on foot, the car their character drives, nothing while riding as a passenger. Getting in and out of a car and a carjack are never predicted: the snapshot's act (board, enter, exit) and jacking flag hold the twin still through them, and the snapshots move and seat it.

The server recycles entity ids, so one snapshot's person can be the next one's car under the same id (a level reset, a mission started again, the traffic and the crowd coming and going): a twin is of its entity's kind, and is made anew when the id comes back as another (a car's twin left a person's capsule would walk where the keys point and turn to the mouse). The entity the player controls is followed by its twin, not only by its id.

The local world simulates only what it predicts. The controlled entity (with its trailer) and the player's own character are simulated in full, and so is every twin that could touch the controlled entity before the next snapshot (within NEAR_MARGIN plus the distance both cover at their snapshot speeds over the replay and the next snapshot's wait), so a car the player rams is pushed and a person it brushes is shoved as the server will. Everything else is a proxy (@foi/sim's setProxy): a kinematic body that stays where its snapshot put it, solid to the simulated ones and found by rays, but never integrated, so a crowd and the traffic cost a step almost nothing, and so does the replay of every reconciliation. Which twins are proxies is decided on each snapshot, before the replay, from the poses it carries.

A remote car simulated in full stands at the local time, where the predicted car meets it; the renderer draws it there (PredictedRemotes, from Mirror.predicts and Mirror.presentPose) instead of interpolated in the past, and its driver's twin holds the steering and the handbrake the car's snapshot shows, so it keeps turning as it was. Which remotes are drawn at the local time is a wider set than the simulated one, decided on the same snapshot: the blend from the interpolated pose to the predicted one is bounded to a share of the remote's pace (blendSeconds, predicted.ts), so it must begin before the remote could touch the controlled entity within the blend's length, the replay and the next snapshot's wait, and a remote stays on the predicted timeline for a blend's length after it is out of that reach, so one hovering at the edge never flips back and forth. A proxy drawn at the local time stands at its measurement carried on by its velocity and its spin for the ticks the prediction runs ahead; when it comes into the simulated set its twin takes over at the same place.

Classes ​

Interfaces ​

Variables ​

Functions ​