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
NetworkObjectProviderDefaultOr 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 instanceCalls
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
ISpawnHandleassociated with the instanceCall
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)
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
ISpawnHandleIf networked → calls
handle.Despawn()→ Fusion replicates despawnIf 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)
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.onObjectSpawnedRuntimeSpawner.onObjectCulledRuntimeSpawner.onUpdateCurrentPopulationetc.
Last updated