Network model - APIAPI's Replicated Rope & Physics-Carry Kit
What the server decides, what clients show, Iris, and the known limits.
Assumes you have read quick-start.md. The per-feature rules are in api.md.
This page explains what the kit sends over the network, which machine decides what, what a player sees while a decision is on its way, and where the kit's guarantees stop.
Concepts
The server decides; clients show. Every state that players could disagree about is decided by the server and replicated:
| Decided by the server | Replicated as | Where |
|---|---|---|
| A rope's anchors, rest length, preset and cut state | the rope's topology | UUKRopeComponent |
| A rope's shape | a short correction stream of a few key particles, plus a snapshot for players who join | UUKRopeComponent |
| Who rides a zipline, in which direction, from where | the rope's rider state | UUKRopeComponent |
| Who holds an object, at what grip, in which phase | the object's carry state | UUKCarryableComponent |
| Whether a player's request is accepted | a reply to that player only | UUKRopeInteractorComponent |
The rope component replicates exactly four state units (topology, snapshot, correction and rider state) and the carryable component three properties; the carry component on the pawn replicates nothing of its own. Players send requests through reliable server calls on their own pawn's interactor, and the server answers the requesting player alone; the kit never multicasts.
Each machine simulates its own rope. A client runs the same rope solver as the server on its own copy and is pulled toward the server's key particles at the correction rate. Anchors and key particles agree closely on every machine; the free shape between key particles can differ slightly (see Rope shape on clients in api.md). Anything a player interacts with at a point along the rope - a grab, an attach point, a hit test - must be resolved on the server.
What is predicted. Only presentation is predicted on the requesting player's machine: the pending request (OnPredictedRequestStarted / OnPredictedRequestEnded) and the carry reach cue (OnReachStarted / OnReachEnded). The state itself - a cut, a grab, a mount - appears when the server's answer arrives. The kit's movement effects - a zipline ride and the carry slowdown - run on the owning player's machine as well as on the server, through the pawn's movement bridge. On a Character the engine's own movement prediction and corrections keep the player's machine and the server together (see Character Movement adapter in api.md).
What is cosmetic. Never replicated and never seen by the server: a client's rope simulation between corrections, the client-side smoothing of moving anchors (Project Settings › UK Rope › Replication, Anchor* fields), and the trailing of a held object on its holder's own screen (CosmeticLagCm).
Same version everywhere. The server and every client must run the same version of the plugin (see api.md).
Players who join a running game
A joining player receives every rope's current topology and a snapshot of its shape, every held object attached to its holder's hand, every cut rope already cut, and every zipline rider on its line - the kit's own state needs no extra message for a join. The measured details are in api.md: Players who join while an object is held and Players who join while someone rides a zipline. A rope that becomes relevant again after a player walked out of its relevancy range arrives as a new rope, starting from a fresh snapshot.
What it costs on the wire
| Situation | Measured cost | Profile |
|---|---|---|
| An object held by a player, per second | 0 bytes (eight players each holding a crate, every connection, default replication and Iris) | dedicated server, no network emulation |
| A grab, per update on the object | about 62 bytes with default replication, about 44 bytes under Iris | dedicated server, eight players |
| A drop | about 32 bytes with default replication, about 45 bytes under Iris | dedicated server, eight players |
| A request and its reply | one reliable call each way, to the requesting player only | - |
A rope whose ends are all lost (both anchors destroyed) sends one more key particle per correction than a bound rope, so a level where many ropes have lost their anchors costs more on the wire than the same ropes bound.
Iris
The kit runs on both of the engine's replication systems: the default (generic) replication and Iris, which the engine leaves opt-in. Every rule in api.md holds under both unless it says otherwise. The differences you can observe:
- A malformed request does not close the sender's connection under Iris. With default replication the engine closes the connection of a client that sends a request the server's validation refuses; with Iris it does not. The kit drops the request either way and reports it as
UK-VAL-151(see Malformed requests in api.md). - Removing a carryable component from a held object. Under Iris a carryable that is part of the actor's class stays on clients after the server removes it; the kit restores the object locally (see Held objects and pawn collision in api.md).
- Byte counts differ. Iris sends names as short tokens and packs some fields differently; the carry costs above give both figures.
Known limits
These are measured or declared limits of this version, each a deliberate boundary rather than a hidden defect. A limit marked not measured is a case our tests do not reach: it is stated so you can plan around it, and a change in it would not be caught by the kit's tests.
- Iris: a joining player whose rider's pawn arrives late. With default replication, a joining player that receives a ridden zipline before the rider's pawn marks the rider as pending and announces the ride when the pawn arrives. Under Iris this order was not observed in our runs (the pawn always arrived first), so the pending path is not measured there: if the pawn did arrive later, that player could keep
IsRiderPending()true and miss theOnZiplineMountedfor that ride. ReadGetRiderState()rather than counting events if you need a joiner's rider list under Iris. - Iris: the arrival order of cut pieces. With default replication, a client that receives a cut rope's pieces in any order - a piece before the other, either before the parent's cut - never shows an incomplete piece. That ordering is not forced in our Iris runs, so under Iris only the natural arrival order is measured; the forced orders are not measured.
- Iris on Unreal Engine 5.6: relevancy re-entry. A rope that leaves and re-enters a client's relevancy range is measured with Iris on 5.7 and 5.8; on 5.6 with Iris that case is not measured.
- Iris on Unreal Engine 5.6 and 5.7: an accepted request racing a possession change. When the server accepts a request and changes the pawn's controller in the same server frame, the requesting player resolves the request once in every case - as accepted with default replication and with Iris on 5.8, but as
OwnerLostwith Iris on 5.6 and 5.7. - A new controller mid-ride on a non-Character pawn. After a possession during a zipline ride, a lost packet can let the new owner's machine run on for a few frames, and a pawn without a
CharacterMovementComponentkeeps that offset (see A new controller mid-ride in api.md). - Root motion and analog walk speed are not slowed by a carry on a
Character(see Carry slowdown and object weight in api.md). - Physics replication modes. Drop and throw smoothness is measured with the default physics replication mode only; the other modes are not measured.
- Other players' copies of a held object are not wall-checked locally, so a fast carrier's object can overlap a wall briefly on their screens (see Held objects near walls in api.md).
Troubleshooting
The kit logs to LogUKRope (and LogUKRopeCMC for the Character Movement adapter). A warning or error the kit can explain carries an id of the form [UK-VAL-nnn], the object it is about, and a hint that starts with fix:. Each one is logged once (at most once a second for a problem that repeats), never every frame.
| Id | Level | Meaning | What to do |
|---|---|---|---|
UK-VAL-102 | Warning | A rope touches a component with no simple collision; the rope passes through it. | Add simple collision, or set the preset's CollisionMode to Sweep. |
UK-VAL-120 | Error | A Character has no movement bridge because the Character Movement adapter module is not loaded. | Enable the module UKRopeCMCAdapter (it is on by default). |
UK-VAL-121 | Warning | A pawn has no usable movement component; ropes mount it but do not move it. | Add a UPawnMovementComponent, or set the interactor's BridgeOverride. |
UK-VAL-122 | Warning | A pawn uses the engine's Mover component, which this version does not bridge. | Use a pawn with a UPawnMovementComponent, or a BridgeOverride. |
UK-VAL-123 | Warning | A Character's movement component has no rope hook; the adapter declines it (no slowdown, no ride movement). | Reparent to UKRope Character, or use UUKRopeCharacterMovement, or implement IUKRopeCMCHook. |
UK-VAL-124 | Warning | The interactor's BridgeOverride cannot drive this pawn and was refused. | Pick a bridge class that matches the pawn's movement component. |
UK-VAL-150 | Warning | A request was called on a pawn this machine does not control. | Call Request* on the locally controlled pawn only. |
UK-VAL-151 | Warning | The server dropped a malformed request from a client. | Investigate that client; a correct client never sends one. |
UK-VAL-160 | Warning | A carryable's actor has Replicate Movement off; a thrown object moves only on the server. | Turn Replicate Movement on for the object's actor. |
UK-VAL-163 | Warning | Code wrote an invalid carry state; nothing was written. | Change carry state only through grab, drop and throw. |
UK-VAL-185 | Error | A preset's mode has no behaviour in this version; a mount answers WrongPreset. | Use Tether, CutRope or Zipline. |
UK-VAL-186 | Error | A preset was saved by a newer version of the kit; the rope stays unbound. | Update the kit. |
UK-VAL-189 | Warning | SetPreset was called after the rope began play and was ignored. | Set the preset before spawning, or on the class. |
| Symptom | Likely cause |
|---|---|
| A rope simulates but nothing is drawn. | This build has no rope visual yet - see api.md. |
A Character carries at full speed. | UK-VAL-123 or UK-VAL-120 in the log: the character does not use the kit's movement component. |
| A pawn mounts a zipline but does not move. | UK-VAL-121: no movement component the kit can drive. |
A request always resolves Throttled. | Too many requests per second from one player; see Project Settings › UK Rope › Interactor. |
A request resolves Timeout. | The server's reply did not arrive within Ack Timeout Seconds; check the connection. |
| Clients lose a long rope while its end is near them. | The rope actor's relevancy is measured from its root; raise NetCullDistance (see AUKRopeActor net settings in api.md). |
| A rope end hangs free on one client. | Its anchor actor is not replicated or not relevant to that client (see api.md). |