Spawning & Pooling

GONet provides network-aware instantiation with zero-latency spawning, adaptive object pooling, and clean despawn handling across all connected clients.

Network Spawning

Use GONetMain.Instantiate() as a drop-in replacement for UnityEngine.Object.Instantiate(). It automatically assigns a GONetId and replicates the object to all clients.

// Spawn a networked object
var projectile = GONetMain.Instantiate(
    projectilePrefab,
    firePoint.position,
    firePoint.rotation
);

// Despawn a networked object
GONetMain.DespawnGONetParticipant(projectile.GetComponent<GONetParticipant>());
  • --The prefab must have a GONetParticipant component attached.
  • --The prefab must be in a Resources folder (or loaded via Addressables).

Zero-Latency Spawning

Normally, a client must request a GONetId from the server before it can spawn an object. This round-trip adds 50-150ms of delay before the object appears. GONet solves this with the GONetId Batch System.

How it works

  1. Client connects to the server.
  2. Server sends a batch of 200 GONetIds (configurable).
  3. Client can spawn objects instantly using pre-allocated IDs.
  4. At 50% consumption, the next batch is requested in the background.
  5. If the batch runs out, "limbo mode" handles it gracefully.

Configuring Batches

These settings are available in the GONetGlobal inspector.

SettingDescription
client_GONetIdBatchSizeIDs per batch (100-1000, default 200)
client_GONetIdBatchLimboModeBehavior when batch is exhausted (see below)

Limbo Mode Options

ReturnFailure

Spawn returns null. The safe default -- your code is responsible for handling the null case.

InstantiateInLimborecommended

Creates a "ghost" object that becomes real when the next batch arrives. Provides the most seamless player experience.

BlockUntilBatchArrives

Waits synchronously for the server to send a new batch. Not recommended -- causes frame stutter.

QueueRequestWithCallback

Queues the spawn request and invokes a callback when the next batch arrives. Non-blocking and avoids frame stutter. Good for fire-and-forget spawns where a small delay is acceptable.

Object PoolingGONet Legendary

Object pooling is a GONet Legendary feature (v1.6+). The API below shows the intended design. Until then, you can use standard Unity object pooling patterns alongside GONet spawning.

GONet will include a built-in adaptive pooling system. Implement IGONetPoolResettable on your networked components to opt in.

public class Projectile : GONetParticipantCompanionBehaviour, IGONetPoolResettable
{
    private Rigidbody rb;

    void IGONetPoolResettable.ResetForPoolBorrow()
    {
        // Called when object is borrowed from pool
        rb = GetComponent<Rigidbody>();
        rb.velocity = Vector3.zero;
        gameObject.SetActive(true);
    }

    void IGONetPoolResettable.ResetForPoolReturn()
    {
        // Called when object is returned to pool
        gameObject.SetActive(false);
    }
}

Adaptive Pool ScalingGONet Legendary

GONet will automatically grow pools based on demand. GONetAdaptivePoolScaler will monitor utilization and adjust pool sizes to prevent allocation spikes during gameplay.

Monitor pool utilization at runtime with GONetMain.GetMonitor().

Destroying Networked Objects

// Network-safe destroy
GONetMain.DespawnGONetParticipant(participant);

// Or using the convenience method
GONetMain.DestroyImmediate(gameObject);
  • --Both methods handle cleanup on all clients.
  • --If using pooling, objects are returned to the pool instead of destroyed.

Best Practices

  • --Use InstantiateInLimbo for the smoothest player experience.
  • --Pool frequently spawned and despawned objects (projectiles, effects, pickups) to avoid GC pressure.
  • --Keep prefabs in Resources or use Addressables for on-demand loading.
  • --Monitor pool utilization in development builds to tune pool sizes before shipping.

Next Steps

Spawning & Pooling | GONet Docs