Using the Runtime Spawner Fusion Pool Provider

Integrating with the Fusion Pooling system provided by Runtime Spawner

Runtime Spawner – Fusion Pool Provider Integration

How Fusion + Runtime Spawner Pooling Works

Runtime Spawner ships with a FusionPoolObjectProvider, a component that plugs directly into Fusion’s INetworkObjectProvider API.

This component must be the runner’s provider when using Runtime Spawner in Fusion mode.

Because Fusion only supports one provider per runner:

  • If you previously used Fusion’s NetworkObjectProviderDefault

  • Or your own custom provider → Runtime Spawner’s provider replaces it on that runner.

Runtime Spawner now owns pooling, Fusion still owns networking and authority replication.


What Runtime Spawner’s Fusion Pool Provider Does

With FusionPoolObjectProvider added to your NetworkRunner:

Fusion

  • Calls AcquirePrefabInstance() when it needs a new instance

  • Calls ReleaseInstance() when despawning a network object

Runtime Spawner

  • Provides the instance from its internal pool

  • Prewarms pools from SpawnEntries

  • Tracks per-entry + global population caps

  • Ensures proper enable/disable lifecycle for pooled instances

  • Ensures networked despawn goes through Fusion first but still returns to Runtime Spawner's pool

Fusion owns the network lifecycle. Runtime Spawner owns the object pooling.


How to Spawn and Despawn Objects

This is the #1 point users get stuck on, so here is the definitive guidance.


How Spawning Works

Automatic spawning

If you’re using:

  • Global spawners

  • Region spawners

  • Wave spawners

… then spawning is fully automatic. You do not manually call Runner.Spawn().

Runtime Spawner internally drives spawning through its factory abstraction, and the Fusion pool provider ensures that:

  • Fusion sees the spawned object

  • The pooled instance is reused

  • Networking replication happens correctly

Users do not need to write any spawn code unless doing custom spawns.


Manual spawning (advanced / optional)

If your game needs to manually spawn something (e.g., player abilities, projectiles), you must go through Runtime Spawner’s factory, not Fusion directly.

Use:

var instance = RuntimeSpawner.Instance.Executor.Spawn(entry, context);

But since this is advanced, typical users do not need this.


How to Despawn Objects

This is the most important part for Fusion users.

There are three correct ways to despawn something:


1. Automatic Despawn (waves, culling, region exit)

Runtime Spawner will:

  • Detect the despawn condition

  • Look up the ISpawnHandle associated with the instance

  • Call Runner.Despawn() (if networked)

  • Return the object to the pool

  • Update internal population bookkeeping

You don’t need to do anything.


2. Call RuntimeSpawner.Despawn(GameObject)

This is the recommended API for gameplay scripts.

RuntimeSpawner.Despawn(gameObject);

This method:

  • Looks up the owning RuntimeSpawner

  • Checks if the object has a Fusion ISpawnHandle

  • If networked → calls handle.Despawn() → Fusion replicates despawn

  • If not → returns the object to the pool

  • Updates all internal population and SpawnEntry counts

This is the safest despawn method for Fusion + pooling.


3. Call ISpawnHandle.Despawn() yourself (advanced)

If you cached the handle from the factory you may call that directly.

Gamers rarely need to do this unless writing custom spawn flows.


Should I Call Runner.Despawn Myself?

Short answer: NO — not when using Runtime Spawner.

Fusion’s Runner.Despawn(obj) will only:

  • Replicate destruction across network clients

  • Release the instance back to the Fusion pooling system (which Runtime Spawner has replaced)

But it will not update:

  • SpawnEntry population

  • Global population

  • Internal bookkeeping

  • Owner maps

  • SpawnedObject list

  • Region/wave counts

This breaks spawn balancing.

Correct Pattern

Instead of:

Runner.Despawn(gameObject);

Use:

RuntimeSpawner.Despawn(gameObject);

This ensures:

✔ Fusion replication ✔ Returned to Runtime Spawner's pool ✔ Correct population tracking ✔ Wave/region/global systems stay consistent


Prefab-Level Lifecycle: OnEnable / OnDisable

If your old pooling system used OnSpawned/OnDespawned, convert it to:

void OnEnable() { /* init */ }
void OnDisable() { /* cleanup */ }

Runtime Spawner guarantees:

  • Pooled objects are disabled when returned

  • Enabled when spawned

  • Re-enable calls happen for reused objects

  • Works safely in Fusion scenes

Recommended uses:

  • Reset health

  • Reset behavior state

  • Play VFX/SFX

  • Re-register with AI managers

  • Start movement/pathfinding logic


Global Hooks for Analytics / Manager Systems

You can listen to spawn/despawn events:

RuntimeSpawner.onObjectSpawned += obj => { ... };
RuntimeSpawner.onObjectCulled += obj => { ... };
RuntimeSpawner.onUpdateCurrentPopulation += count => { ... };

This replaces custom provider logic you may have had before.


Advanced: Wrapping the Fusion Provider

If your project used custom routing in your old provider, you can wrap the Runtime Spawner provider:

public class MyWrappedFusionProvider : MonoBehaviour, INetworkObjectProvider
{
    public FusionPoolObjectProvider rspProvider;

    public NetworkObjectAcquireResult AcquirePrefabInstance(...) {
        // pre logic
        return rspProvider.AcquirePrefabInstance(...);
    }

    public bool ReleaseInstance(...) {
        // post logic
        return rspProvider.ReleaseInstance(...);
    }
}

This is rarely needed but fully supported.


Migration Checklist (Updated)

When migrating from Fusion’s default pooling to Runtime Spawner:

Required

✔ Remove existing INetworkObjectProvider from the runner ✔ Add FusionPoolObjectProvider (or your wrapper) ✔ Ensure Runtime Spawner uses the Fusion factory mode

Prefab updates

✔ Move OnSpawned/OnDespawned logic → OnEnable/OnDisable ✔ Ensure your NPCs/AI reset correctly when reused

Gameplay scripts

Replace:

Runner.Despawn(gameObject);

With:

RuntimeSpawner.Despawn(gameObject);

Global systems

✔ If you track active enemies/objects → subscribe to Runtime Spawner events

Optional

✔ For manual spawns → use Runtime Spawner’s executor, not Fusion directly


Final Summary

How do I despawn an object?

RuntimeSpawner.Despawn(gameObject);

Should I use Runner.Despawn?

No. Runtime Spawner must route the despawn so it can:

  • Update SpawnEntry population

  • Update global population

  • Remove bookkeeping

  • Return to the internal pool

  • Trigger Fusion’s network replication (if networked)

How do I spawn new enemies manually?

Typically you don’t. Spawning is handled by global, region, or wave systems. If you must, use RuntimeSpawner’s executor.

What events can I listen to?

  • RuntimeSpawner.onObjectSpawned

  • RuntimeSpawner.onObjectCulled

  • RuntimeSpawner.onUpdateCurrentPopulation

  • etc.

Last updated