June 10, 2026

Why Multiplayer Physics Breaks at Scale

Networking a multiplayer game is really two separate problems, and they have almost nothing in common.

The first is moving ten players around a map, and it is effectively solved: position and rotation, a little interpolation, and server authority over who is where. Every engine and framework ships something that handles it well enough to get you a playable prototype in an afternoon.

The second is moving thousands of active physics objects: rigid bodies, destructible props, dense crowds, persistent world state, all colliding and reacting every tick. This is the one that feels fine in a prototype and falls apart in production. Online multiplayer is now the most-adopted feature in Unity games, named by 83% of developers in the 2026 Unity Game Development Report, and as more of those games reach for physics depth and persistent worlds, more teams meet this second problem for the first time. When it falls apart, it is almost always for the same reason.

It is a bandwidth problem before it is anything else

A physics object on the wire is its transform plus its motion: position, rotation, and velocity. After the compression every serious engine already applies, a transform update lands somewhere around 12 to 20 bytes. Physics adds the velocity state on top of that.

Then multiply it out. With 1,000 active physics objects at 30 Hz, a client that needs to see all of them receives roughly 1,000 * 18 bytes = 18,000 bytes per tick, which at 30 Hz works out to about 540 KB per second, per client, for movement alone. Push the scene to 10,000 objects and the same client is trying to receive 5.4 MB per second, which is no longer a number you can tune your way out of; it is a hard ceiling on what the scene can hold.

This is why the jump from “it works” to “it ships” is so steep for physics-heavy games. Player count, tick rate, and object count all multiply each other, and physics is the term that grows fastest, which is how a prototype with 50 objects turns into a shipping game with 5,000.

The limits of interest management

The first thing studios reach for is relevancy, which means not sending what the player cannot perceive. Objects that are not moving get flagged as static and dropped from the stream, distant objects update less often, and anything outside the player’s area of interest is culled.

This works, and you should do it, but it reduces the object count rather than the cost per object. For genuinely dense scenes the count you are left with is still large, because the objects that stay relevant are the expensive ones: a crowd is relevant precisely because it is near the player, and a destruction event is relevant precisely when dozens of pieces are moving at once. Interest management thins the easy cases and leaves you holding the hard ones, which are the cases that made the game worth building in the first place.

The durable lever is bytes per object

Once you have culled what you can, the only variable left is how many bytes each remaining object costs. That is the number that decides your ceiling, and it is the one most projects never touch, because touching it means writing custom serialization.

Going below the 12 to 20 byte baseline means building data models tuned to your exact game state, testing them against edge cases, and maintaining them as the game changes. It is some of the least glamorous engineering there is. The bugs show up in production as desync, jitter, or visual corruption, and the root cause is bytes that do not mean what the deserializer expected. Studios that go down this road spend real months on it. (We have written about why the baseline is what it is.)

A note on the other approach

There is a way to avoid sending state at all: deterministic lockstep, where every client runs the same simulation from the same inputs. It is elegant, and for dense physics it is treacherous. Floating-point arithmetic diverges across CPU architectures, and one rounding difference cascades into a full desync. It punishes late joiners, who have to be brought up to the current state before they can play. And cross-play makes it worse, because the platforms you want to share a match are exactly the ones whose float behavior differs. That is not a shrinking concern: the same report has 72% of studios prioritizing cross-play. Most large-scale physics games end up on server-authoritative state sync instead, which puts you right back at the bandwidth problem above.

What Reactor does about it

Reactor attacks the byte count directly, and without making it your job. Instead of asking you to write serialization, it builds the data model from your game’s state and optimizes it automatically, observing what is in the scene, what is changing, and the range of each value, then generating the tightest representation it can. That process is ongoing, so the wire format keeps adapting as the game does. The result is the kind of thing that sounds unlikely until you measure it:

  • Kazap.io: about 0.5 bytes per transform.
  • Braains2: under 1 byte per transform, running 100 players and 150 physics objects at 30 Hz, with each player streaming roughly 35 KB/s at full load. (Full case study.)
  • Ruins demo: frequently under 1 byte per transform through continuous physics destruction.

In a controlled comparison against Photon Fusion 2 and Netcode for GameObjects on identical scenes, Reactor moved 9.5 times less transform data. (The benchmark is public if you want to run it yourself.) Put the 540 KB/s scene from earlier on that footing and it stops being a wall.

The authority side is built in rather than assembled. Reactor runs PhysX on the server: raycasts, sweeps, overlap queries, and rigid-body simulation all happen server-side, with the server holding authority over entity state. Client updates are treated as inputs to validate, not state to trust. Prediction and reconciliation are included, so interactions stay responsive without giving up that authority. Doing this for dense physics, not just character movement, is the part that is genuinely hard to build yourself, and it is the part Reactor exists to handle.

Decide this before you write gameplay

If your game has meaningful physics complexity, the decisions you make in the first months set your ceiling. The studios that ship in this space tend to share a few habits:

  • They treat maximum networked object count as a hard spec, not a “we will optimize later.”
  • They put a bandwidth budget in the design doc, next to the polygon budget and the memory budget.
  • They choose state sync or lockstep based on game type before writing a line of gameplay code.
  • They build on tooling made for dense physics sync rather than stretching a general-purpose networking layer to a job it was not designed for.

The tooling for getting to a prototype has never been better, so the gap is no longer time-to-first-playable; it is whether the architecture under that prototype can carry the object count you eventually have to design around.

Reactor is built for the second problem: thousands of networked physics objects, server-authoritative, with the wire format optimized for you. It is free to develop locally and free to self-host up to 32 CCU. Get started here.