# Photon Fusion Integration Guide

The Runtime Spawner package (from version 1.5.0 and higher) includes optional integrations for Photon Fusion 2.x, enabling fully networked spawning, pooling, and synchronization.

This guide explains how to set up your project, assemblies, and bootstrap flow to use the spawner with Fusion’s `NetworkRunner`.

{% hint style="info" %}
[Existing Fusion Project? Read this first](https://megacrush.gitbook.io/megacrush-unity-assets/runtime-spawner/runtime-spawner-user-manual/getting-started/networking-integrations/photon-fusion-integration-guide/existing-fusion-project-read-this-first)
{% endhint %}

***

### Overview

Runtime Spawner can operate seamlessly inside a Fusion session:

* The **host or server instance** performs all spawn logic.
* Clients automatically observe replicated objects through Fusion’s built-in network synchronization.

Key benefits:

* Authoritative spawning managed by the host.
* Full pooling support via:
  * `FusionPoolProvider` (core `INetworkObjectProvider` passed into `StartGameArgs.ObjectProvider`), or
  * `FusionPoolObjectProviderBehaviour` (MonoBehaviour attached to the `NetworkRunner` GameObject).
* Lifecycle synchronization for AI, players, and encounter systems.
* Drop-in integration using `FusionFactoryAsset` and `FusionObjectFactory`.

### Using the Runtime Spawner Fusion Pool Provider

The Runtime Spawner provides an Pooling system that directly integrates with Fusion, providing automatic pooling and object lifecycle management for your Fusion-based games.

Please refer to this page in the manual for more information:

> [Using the Runtime Spawner Fusion Pool Provider](https://megacrush.gitbook.io/megacrush-unity-assets/runtime-spawner/runtime-spawner-user-manual/technical-details/object-pooling/using-the-runtime-spawner-fusion-pool-provider)

***

### 1. Assembly Definition Requirements

Any assembly definition (`asmdef`) that contains Fusion-related scripts (such as `FusionBootstrap`, `CharacterController_Fusion`, or your own `NetworkBehaviour` components) must be processed by Fusion’s CodeGen (Weaver) system.

#### Required Configuration

| Setting                   | Required Value                         |
| ------------------------- | -------------------------------------- |
| **Assembly references**   | `Fusion.Unity`, `Unity.Fusion.CodeGen` |
| **Define constraint**     | `FUSION_WEAVER`                        |
| **Recommended reference** | `RuntimeSpawner.Integrations.Fusion`   |

> **Tip:** The `FUSION_WEAVER` define ensures your scripts are compiled with Fusion’s code generation pipeline.

***

### 2. Add Assemblies to the CodeGen List

1. Go to **Tools → Fusion → Network Project Config**
2. Add all assemblies that contain networked behaviours to **Assemblies to Process**, including:
   * `RuntimeSpawner.Integrations.Fusion`
   * `RuntimeSpawner.Fusion.Samples`
   * Your own gameplay assemblies containing `NetworkBehaviour` classes

<figure><img src="https://627544832-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAjayiCOvbs0xN74JSxBK%2Fuploads%2FXhwoAZzSYZAtf0wKrYc0%2F2025-11-09%2016_19_29-D__projects_RuntimeSpawner-Fusion%20-%20FusionSample%20-%20Windows%2C%20Mac%2C%20Linux%20-%20Unity%202.png?alt=media&#x26;token=8cc81677-08a6-4462-987c-23ba428c2870" alt=""><figcaption></figcaption></figure>

> If you skip this step, Fusion will log:\
> `NetworkObjectSpawnException: Failed to spawn: behaviour not weaved`

***

### 3. Run the Fusion Code Generator

After updating assemblies or define constraints:

1. In the Unity menu bar, select **Fusion → CodeGen → Run CodeGen**
2. Wait for a console message like:\
   `Fusion CodeGen: processed N behaviours in <AssemblyName>`

Once complete, all networked prefabs (players, AI, etc.) will be valid for runtime spawning via the **FusionObjectFactory** and **FusionPoolObjectProvider**.

***

### 4. Bootstrap Flow Overview

The **Fusion Bootstrap Sample** (included in the packages Fusion sample) demonstrates a complete setup:

1. Player clicks Start in the UI.
2. A `NetworkRunner` is created (or re-used) and configured with a **pooling `INetworkObjectProvider`**:
   * In the sample, this is `new FusionPoolProvider(new PoolAdapter())` passed into `StartGameArgs.ObjectProvider`.
3. The host (or peer 0 in Shared mode) spawns player prefabs for each joining client.
4. When the local player spawns, the bootstrap binds the camera.
5. Once the host player exists, the bootstrap triggers:

   ```csharp
   spawner.Init();
   spawner.StartSpawners();
   ```

   to begin population and encounters.

#### Key Rules

* **Only the Host/Server runs the `RuntimeSpawner`.**
  * Clients observe replicated results automatically.
* Player prefabs must include a `NetworkObject` component and be registered in\
  **Project Settings → Fusion → Network Prefabs**.
* In **Shared Mode**, both players and AI synchronize automatically without a dedicated server.

***

### 5. Quick Setup Checklist

| Setting / Asset            | Required Value                                                |
| -------------------------- | ------------------------------------------------------------- |
| **Assembly references**    | `Fusion.Unity`, `Unity.Fusion.CodeGen`                        |
| **Define constraints**     | `FUSION_WEAVER`                                               |
| **CodeGen assemblies**     | Include all with `NetworkBehaviour` scripts                   |
| **Network Prefab Table**   | Register all player, AI, and pooled prefabs                   |
| **Runner Object Provider** | `FusionPoolObjectProvider`                                    |
| **Spawner Factory**        | `FusionFactoryAsset`                                          |
| **Host Init Flow**         | `spawner.Init() → spawner.StartSpawners()` after player spawn |

***

### 6. Common Errors and Fixes

| Error                                     | Likely Cause                                  | Fix                                                                                        |
| ----------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `FailedToCreateInstance (prefab: [Name])` | Prefab missing from Network Prefab Table      | Add prefab under Project Settings → Fusion → Network Prefabs                               |
| `NetworkObject not weaved`                | Assembly not processed by CodeGen             | Add the asmdef to Fusion CodeGen and re-run                                                |
| `INetworkObjectProvider` returned null    | Provider not assigned or pool not initialized | Ensure provider is set in `StartGameArgs.ObjectProvider` and prefabs have `NetworkObject`  |
| Nothing spawns in multiplayer             | `RuntimeSpawner` never started on host        | Confirm bootstrap calls `spawner.Init()` and `StartSpawners()` **after** host player spawn |
| Prefabs spawn locally but not on remote   | Prefab not in Network Prefab list             | Register prefab in Project Settings                                                        |
| Errors mentioning “behaviour not weaved”  | Assembly not processed by CodeGen             | Add asmdef to CodeGen list and re-run                                                      |

***

### 7. Tips for Custom Projects

* For small projects or tests, put all Fusion scripts in a single asmdef (e.g. `RuntimeSpawner.Fusion.Samples`) and include it in CodeGen - simplest setup.
* Use Fusion’s **Simulation Info HUD** to confirm authority and observe replication during play.
* When testing locally:
  * Run one instance as **Host**.
  * Run a second instance as **Client**.&#x20;
  * Verify that both players spawn and the host begins spawner-driven population.

{% hint style="info" %}
You can use the [Parrel Sync Package](https://megacrush.gitbook.io/megacrush-unity-assets/runtime-spawner/runtime-spawner-user-manual/getting-started/networking-integrations/tips-for-network-development-with-the-unity-editor) to load and test multiple Untiy Editor instances easily
{% endhint %}

***

### 8. Advanced Integration Notes

#### Lifecycle Coordination

`SpawnDirector` and `SpecialEncounterManager` support:

* `Pause()` – temporarily halts spawning during match transitions or network pauses.
* `Resume()` – continues spawn flow without reinitialization.
* `End()` – clean teardown for disconnects or scene transitions.

These lifecycle calls work cleanly alongside Fusion’s object pool and replication logic.

#### Pooling Bridge

The Fusion pool providers connect the Runtime Spawner’s pool system directly to Fusion’s runner:

* `FusionPoolProvider` – a core `INetworkObjectProvider` you construct in your bootstrap and pass to `StartGameArgs.ObjectProvider`.
* `FusionPoolObjectProviderBehaviour` – a MonoBehaviour `INetworkObjectProvider` that you attach to the same GameObject as your `NetworkRunner`.

When a pooled object is spawned by the host, it’s automatically replicated to all connected peers.\
Despawns and returns to the pool are mirrored network-wide.

`FusionObjectFactory.Prewarm` recognizes both providers and forwards `Prewarm(GameObject, int)` calls accordingly.

***

### 9. Example: Integrating with Your Own Custom Bootstrap

If you already have **custom Fusion startup logic** (your own `Bootstrap`, `GameManager`, etc.), you don’t need to use the sample bootstrap. You only need to:

1. Ensure your `NetworkRunner` is started with an appropriate **object provider**:
   * `FusionPoolProvider` **or**
   * `FusionPoolObjectProviderBehaviour`
2. Use a `FusionFactoryAsset` (or `FusionObjectFactory` constructed in code) to plug the spawner into your runner.
3. Call `spawner.Init()` and `spawner.StartSpawners()` on the **authoritative side** once the host/local player is ready.

#### Option A – Core Provider (`FusionPoolProvider`)

This is closest to the sample:

```csharp
using Fusion;
using UnityEngine;
using MegaCrush.Spawner;
using MegaCrush.Spawner.FusionAdapter;

public class MyFusionBootstrap : MonoBehaviour
{
    [SerializeField] private NetworkRunner runnerPrefab;
    [SerializeField] private RuntimeSpawner spawner;

    private NetworkRunner _runner;

    private async void Start()
    {
        _runner = Instantiate(runnerPrefab);

        // Bridge Fusion to your Runtime Spawner pool via PoolAdapter.
        var provider = new FusionPoolProvider(new PoolAdapter())
        {
            DelayIfSceneManagerIsBusy = true
        };

        var args = new StartGameArgs
        {
            GameMode       = GameMode.Host,
            SessionName    = "MySession",
            ObjectProvider = provider,
            // SceneManager = your INetworkSceneManager, if any
        };

        var result = await _runner.StartGame(args);
        if (!result.Ok)
        {
            Debug.LogError($"Fusion start failed: {result.ShutdownReason}");
            return;
        }

        if (_runner.IsServer)
        {
            spawner.Init();
            spawner.StartSpawners();
        }
    }
}
```

#### Option B – Behaviour-based Provider (`FusionPoolObjectProviderBehaviour`)

If your project already expects **providers as components on the runner** (e.g. your own `NetworkObjectProviderDefault` subclass):

```csharp
using Fusion;
using UnityEngine;
using MegaCrush.Spawner;
using MegaCrush.Spawner.FusionAdapter;

public class MyFusionBootstrap : MonoBehaviour
{
    [SerializeField] private NetworkRunner runnerPrefab;
    [SerializeField] private RuntimeSpawner spawner;

    private NetworkRunner _runner;

    private async void Start()
    {
        _runner = Instantiate(runnerPrefab);

        // Attach the behaviour-based provider to the runner GameObject.
        var provider = _runner.GetComponent<FusionPoolObjectProviderBehaviour>();
        if (provider == null)
            provider = _runner.gameObject.AddComponent<FusionPoolObjectProviderBehaviour>();

        var args = new StartGameArgs
        {
            GameMode       = GameMode.Host,
            SessionName    = "MySession",
            ObjectProvider = provider,
            // SceneManager = your INetworkSceneManager, if any
        };

        var result = await _runner.StartGame(args);
        if (!result.Ok)
        {
            Debug.LogError($"Fusion start failed: {result.ShutdownReason}");
            return;
        }

        if (_runner.IsServer)
        {
            spawner.Init();
            spawner.StartSpawners();
        }
    }
}
```

In both cases, `FusionFactoryAsset` (if you’re using it) will:

* Find the active `NetworkRunner`.
* Use its `ObjectProvider` (either `FusionPoolProvider` or `FusionPoolObjectProviderBehaviour`).
* Provide a `FusionObjectFactory` that the `RuntimeSpawner` will use for networked spawning.

***

### 10. Troubleshooting Summary

| Symptom                                  | Check                                           | Resolution                                                                                           |
| ---------------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| Host works, clients see nothing          | Spawner running on host only                    | Guard spawn logic with `if (runner.IsServer)` and ensure `spawner.StartSpawners()` is called on host |
| Pool not returning objects               | Object provider setup                           | Verify `FusionPoolProvider` / `FusionPoolObjectProviderBehaviour` is assigned to `ObjectProvider`    |
| Prefabs spawn locally but not on remote  | Network Prefab registration                     | Register prefabs in Project Settings → Fusion → Network Prefabs                                      |
| Errors mentioning “behaviour not weaved” | CodeGen configuration                           | Add assemblies to Fusion CodeGen list and re-run                                                     |
| `INetworkObjectProvider` never hit       | Wrong provider or not passed to `StartGameArgs` | Ensure `ObjectProvider` is set on `StartGameArgs` before calling `StartGame`                         |

***

### ✅ You’re Ready to Go

Once your assemblies are weaved, prefabs registered, and your `NetworkRunner` started with either `FusionPoolProvider` **or** `FusionPoolObjectProviderBehaviour` (plus a `FusionFactoryAsset` or `FusionObjectFactory` in play), the Runtime Spawner will automatically handle networked spawning, despawning, and pooling across host and clients.

Use the provided **Fusion Bootstrap Sample** scene as a reference template, then adapt the integration snippets above to match your own custom Fusion startup logic.

### Also see:

* [Installing Samples](https://megacrush.gitbook.io/megacrush-unity-assets/runtime-spawner/runtime-spawner-user-manual/getting-started/samples-overview/installing-samples)
