Spatial

Network Culling (LOD)

Per-pair broadcast-rate rings so distant entities cost less bandwidth. Off by default.

Server
services.AddCrossplayCulling();
Unity package
com.crossplay.culling
Depends on
movement

Configuration 1

Every tunable lives in an options object — there are no magic numbers to hunt for.

CullingOptions

Configurable culling parameters (defaults here; never inlined in logic).

  • bool Enabled { get; set; }

    Master switch — off by default so composing the piece changes nothing until it is explicitly turned on (Crossplay:Culling:Enabled / env Crossplay__Culling__Enabled=true, or AddCrossplayCulling(o => o.Enabled = true)). Off = full rate for every pair.

  • int FarTickDivisor { get; set; }

    Send divisor for pairs beyond FullRateRadius: an observer receives every Nth broadcast tick of a far subject (at the default 20 Hz tick, 4 → 5 Hz far updates). 1 disables the reduction; the client's interpolation buffer absorbs the sparser timeline automatically. Default 4; raise it for more far-pair savings (coarser far updates), lower it toward 1 for smoother distant motion.

  • float FullRateRadius { get; set; }

    Observers within this distance (world units) of a subject receive every broadcast tick. Beyond it — but still inside the interest radius — they receive every FarTickDivisorth tick. Size it to where per-tick fidelity stops being visible in your game (typically well inside the interest radius). Default 40 units; raise it for fast/precise action, lower it to save more bandwidth.

Unity seams you implement 1

The client half's sockets. Bind your implementation in the client context and Crossplay's client calls it — this is where your models, animators, UI and controls plug in.

ICullingClient unity SPI

The client culling layer: assigns every world entity view a distance tier from the local player and (by default) applies the built-in actions — full detail near, animator pose-write culling in the mid ring, deactivation beyond. It never knows what a view IS; whatever the game spawns gets culled. Remove the package (or disable it in options) and every view stays full detail.

  • event Action<WorldEntityView, int> TierChanged

    A view moved to another tier (see CullingTier). Games hook their own LOD reactions here.

  • int CountFull

    Views currently at full detail.

  • int CountReduced

    Views currently in the reduced ring.

  • int CountCulled

    Views currently culled (deactivated).