Back to the blog

Feature update

Interest management keeps large worlds local

Nebula now limits entity traffic to the part of the world each player needs. The same system narrows what gateways cache and what workers publish, so a larger world does not automatically become a larger network view for every player.

Stop treating a public world as one broadcast room

A gateway routes client input and replicated state. A worker is a headless Unity process that simulates entities in assigned box-shaped containers. These processes, clients, the orchestrator, and its control-plane registry form a mesh.

Before this release, every client in a public instance was told about every entity in that instance. Distance changed how often an entity's transform was sent, but it did not stop the spawn, state, or later messages. Every gateway also connected to every worker and cached every entity it held.

That model made a distant entity part of each client's network state even when the player could not see or interact with it. Adding entities or workers therefore increased work across the whole mesh, not just near the part of the world that changed.

Reduce traffic at three levels

Interest management is the system that decides which entities a client hears about. Nebula now applies that decision throughout the route from worker to player:

  1. A client holds an exact interest set. An entity outside that set is not spawned, and its transforms, variables, synchronization state, and remote procedure calls (RPCs) are not relayed to that client.
  2. A gateway divides absolute world space into regions and subscribes only to the regions covered by its clients' points of interest. It can disconnect from a worker when no client, owned entity, or explicit subscription still needs that worker.
  3. A worker groups its authoritative entities by region and sends each region only to gateways that subscribed to it. Gateways evict records after the last local reason to keep them is gone.

The default point of interest is the player's pawn. The default radius is 120 meters, and the region grid uses 64-meter cells. Enter and exit distances differ, and a short linger period keeps entities from repeatedly spawning and despawning near the edge. Transform update rates still step down with distance inside the set.

Container ownership is scoped too. A client receives incremental ownership rows for nearby containers, its current instance, and containers needed by entities already in its set instead of the mesh's complete lease table.

Follow the interest flow

Start with useful defaults, then describe your game

The default behavior needs no game code or world partition. A player hears about nearby entities, keeps its own pawn at the full update rate, and receives only globally relevant entities while it has no pawn. Interest evaluation is staggered across ticks so all clients do not create one periodic spike.

Three prefab settings handle common exceptions. Use RelevanceRadius for an entity that should be visible from a different distance, AlwaysRelevant for the small set every client must receive, and InterestGroup as an input to game-specific filtering.

For rules such as spectators, party members, strategy cameras, or fog of war, install an IInterestPolicy. A policy can add point or box-shaped foci, subscribe to a limited number of entities by ID, and authorize each client-entity pair. Tightening a rule can revoke existing replicas immediately; revealing new information stays on the bounded evaluation queue.

A standalone gateway can load that game code through a configured gateway extension. Extension failures are isolated and counted, and an authorization error fails closed.

Add game rules to a standalone gateway

Treat camera positions as requests

A client can send a focus hint for a camera that looks away from its pawn. The gateway treats the hint as untrusted input. It rejects malformed coordinates, limits attempts to five per second by default, and applies a server-owned focus mode.

The default mode clamps the hint to 60 meters from the pawn. A server can grant a free focus to a spectator or strategy camera, or disable hints for a client. Instance isolation still applies in every mode, so a wider camera cannot reveal another private instance.

Hints use absolute, double-precision world coordinates so a floating-origin shift does not move the requested point. Clearing a hint is reliable and carries a generation number, which prevents an older in-flight hint from restoring a view the client already closed. The client's content anchor remains separate: the hint asks the server what to send, while the anchor chooses what the client keeps loaded.

Configure client focus hints

Keep carried entities with their carrier

An entity inside a moving container now follows its outermost, or root, carrier for interest. A passenger on a ship enters and leaves a client's set with the ship, even through nested carriers or a cross-worker handover. Spawns arrive carrier-first and removals happen contents-first, so the client always has the frame needed to place a passenger.

Boarding, disembarking, a carrier arriving late, and a carrier being destroyed all reclassify and publish the affected subtree. A surviving passenger is moved into the carrier's former container before the carrier disappears. Carrier cycles are refused, and valid carrier chains have no fixed depth or subtree limit.

Read the carried-entity guarantees

Stream entities and world content together

Every authorized focus now opens a bounded container window, not only the pawn. A strategy camera can therefore receive the empty chunks beneath it as well as nearby entities. Client focus never allocates a chunk; allocation remains a server decision.

You can also configure a runtime chunked world. With NebulaConfig.ChunkedWorld enabled, Nebula allocates and retires chunks around simulated pawns, maintains the client's floating origin, and raises content load and unload hooks. The game supplies the content for each chunk.

Build an infinite runtime world

See what the system is saving

The dashboard and debug overlay now report interest-set sizes, cached entities, subscribed regions, worker-link reasons, spawn and despawn rates, evaluation time, and worker-side filtered entries and bytes. Partition warnings identify a container with too many entities or expensive gateway filtering, and InterestProbe adds machine-readable client checks for load and soak tests.

Interest management bounds replication and network work. It does not divide simulation work: every container still belongs to one authoritative worker. A dense area that exceeds one worker's budget still needs to be partitioned into more containers.

Monitor interest management

Upgrade to alpha.29

Interest management ships in 0.1.0-alpha.29 and changes the wire protocol from version 16 to 17. Rebuild and restart every client, gateway, worker, and orchestrator together; gateways reject clients whose protocol version differs.

Audit any feature that assumed every public entity was always present, including full-map radar and pawn-less spectators. Mark the few global entities as always relevant or express the view through an interest policy. Custom clients must also apply full, upsert, and remove operations from the new incremental container ownership message.