This document is about: FUSION 2
SWITCH TO

What's New

Fusion 1 set the bar high as an industry-leading state sync SDK, combining the best of Bolt’s tick-based netcode with PUN’s cloud-based convenience. This unique architecture allows Fusion to cover a wide variety of game genres and, combined with its amazing CPU and Bandwidth usage, makes it a truly next-gen networking SDK.

Fusion 2 builds upon this foundation by bringing new features and quality-of-life updates to the existing APIs. Additionally, large parts of Fusion's inner core have been rewritten in an effort to improve and streamline it. We made sweeping changes to a variety of systems, including data transfer, time synchronization, memory management and overall CPU performance.

This page gives an overview of the changes that we made for Fusion 2.

Reworked Interest Management System

The new system is much more performant and now provides reliable Enter/Exit callbacks whenever an object enters/exits the interest set of a client.

These are fired when a Network Object enters/exits a given Player's AOI regions, as well as when a player explicitly has interest in an Object added or removed (using Runner.SetPlayerAlwaysInterested()). The callbacks are reliably computed on the server in Server, Host and Shared Mode.

We also have the NetworkObject/NetworkBehaviour.ReplicateTo API which allows for fine-grained dynamic control over which behaviours are replicated to which clients.

FixedUpdateNetwork On Proxies

FixedUpdateNetwork no longer executes on proxies by default. (Proxies are NetworkObjects on clients over which the client does not hold InputAuthority.)

This change reduces overall CPU usage as most applications do not need to simulate proxies. For cases where this is needed (such as when using predicted physics), proxies can be set to simulate and invoke FixedUpdateNetwork callbacks by using:

C#

networkRunner.SetIsSimulated(networkObject, true);

New Time Synchronization

Fusion 2 has improved its system that controls how far ahead clients predict and for how long they buffer server snapshots before rendering. This new system still adapts to changing network conditions smoothly, but does so much more quickly and reliably than in Fusion 1.1.

The settings are also simpler and more meaningful. Both the client's lead for prediction and the time it spends buffering snapshots come from two settings (each)—a target packet loss and an additional, static offset. The client will sample recent network conditions and dynamically adjust how far ahead of the server it is so that network jitter only induces the specified packet loss. If jitter increases, the client will predict further ahead. If jitter decreases again, the client will fall back to a smaller lead. The static offset essentially just provides more “delivery attempts.”

For example, if it was acceptable for ~1% of the client's inputs to reach the server late but also desirable for each input to have a second chance to arrive on time (in case the first packet is lost), you would set both TimeSyncConfiguration.MaxLateInputs and TimeSyncConfiguration.ExtraSimulationOffset to 1.

Shared Mode

Shared Mode now also relies on accurate tick-aligned data between clients.

This allows for using Runner.Tick to refer to a specific tick across clients, meaning that TickTimer is now supported in Shared Mode.

The tick-based Shared Mode now also uses the same accurate snapshot interpolation as Server Mode, improving both visual accuracy and perceived latency.

Change Detection

Fusion 2 introduces a new change detection API which allows you to not only detect changes in Render, but also in FixedUpdateNetwork to trigger gameplay logic.

Create a ChangeDetector like this:

C#

 _changes = GetChangeDetector(ChangeDetector.Source.SimulationState);

Then call ChangeDetector.DetectChanges at any time (such as in FixedUpdateNetwork or Render) to detect any changes that occurred since its previous invocation.

New Networked Data Access System

New APIs allow for direct access of underlying network data buffers. Use TryGetSnapshotsBuffers to access snapshot buffers. There are functions available to read the data and helper functions to interpolate them for custom interpolation.

Interpolation Targets

Working with interpolation targets was difficult to get right with Fusion 1, especially when parenting Network Objects. Fusion 2 simplifies interpolation so that interpolation targets are not needed anymore when using NetworkTransform. Instead, the Unity Transform with the NetworkTransform component is interpolated directly.

NetworkTransform Improvements

NetworkTransform now stores its TRS data (Position/Rotation/Scale) in local space. This means:

  • Child and nested NetworkTransforms are MUCH more data efficient.
  • However, Area Of Interest position is no longer valid for nested NetworkObjects. AreaOfInterestOverride has been introduced to account for this and allows a NetworkObject to specify another NetworkObject position to be used to determine Player Interest.

Syncing a Transform's LocalScale is now optional.

Syncing a NetworkObject's parent is now optional. A valid NetworkBehaviour must be present on the parent transform, and the NetworkTransform must be on the root of the Network Object.

Network Physics

NetworkRigidBody and NetworkPhysicsSimulation have been removed from the Fusion DLL and have been replaced with the Unity Physics Addon, which comes included in the main Fusion SDK download. The full feature set of server-only and full-prediction physics is available.

Providing the physics addon via source code allows you to modify & extend it to fit your project's needs. This provides more flexibility when working with physics in complex use cases such as VR games. While NetworkTransform has removed its InterpolationTarget requirement in Fusion 2, NetworkRigidbody still has an InterpolationTarget property. However, an Interpolation Target is only needed for very specific use cases, and can typically be left as null (indicating that the rigidbody transform will be moved for interpolation).

VR Input Mode

A new input transfer mode designed for VR games. By default, Fusion sends input from the client to the server using unreliable transfer. To mitigate packet loss a small history of past inputs is included in each input packet. This allows the server to operate with a complete stream of inputs even if a few individual packets are lost, but it increases the size of input packets.

The VR Input Mode only sends the latest input state to drastically reduce bandwidth for VR games with large input structs containing position data for head/hands.

To enable this, set the Input Transfer Mode to Latest State in the NetworkProjectConfig.

Encryption

Currently not yet present in the release candidate but will be in the release version.

Fusion 2 introduces seamless end-to-end encryption, ensuring the security of gameplay traffic. The encryption system covers communication between Clients and Photon Cloud, built on top of the existing Realtime SDK. The main addition of Fusion 2 is its automatic encryption of data exchanged between clients and servers, making the process hassle-free—all it takes is enabling the feature. Whether in Shared or Client-Server mode, Fusion 2 encrypts the entire data packet transmitted between peers, offering a robust encryption solution for enhanced security.

Simple KCC

With the Simple KCC we’ve added a user-friendly and intuitive 3D character controller addon to Fusion. It is designed to simplify setting up character movement in your games using Fusion.

Compared to the Unity CharacterController it provides more features and fully supports all multiplayer use cases, so you can use it in Shared, Host and Server Mode.

simple kcc

New Heap System

Fusion 2 comes with a new internal heap which dynamically pre-allocates memory. The new heap allows for leak detection and garbage collection of internal unmanaged memory used by Fusion.

Unified Data Transfer Model

Fusion 1 provided two data transfer models: Delta Snapshots and Eventual Consistency. Both had their use cases, however we discovered that by focusing on a single model we can provide data transfer that is more CPU and bandwidth efficient in almost all use cases.

The new eventual consistency mode in Fusion not only has a lot of performance improvements over the prior version, but also ensures by default that all Networked Property updates on a single NetworkObject arrive on clients in the same tick, providing consistent tick-accurate data on a per-object basis. For a classic per-property eventual consistency transfer you can set the SimulationConfig.ObjectDataConsistency to Eventual.

Scene Management

To support more cases out-of-the-box, Scene Management has been completely rewritten. It now serves as a drop-in replacement for Unity’s SceneManager, enabling you to build more elaborate scene transitions on top of it.

It's no longer necessary to write custom support for addressable scenes. Simply add the FusionScenes Addressables label to your addressable scene asset and Fusion will automatically recognize it.

Additive scene loading is ready to go! The new NetworkSceneInfo supports up to 8 scenes simultaneously. Works both in single and multiple peer mode.

Using versioning, it's possible to let clients reload a scene by simply removing the desired scene from the SceneAuthority and adding it again or loading it in Single mode.

On top of that, objects can now be spawned as DontDestroyOnLoad, even in multiple peer mode with additive scenes.

Fusion 2 App IDs

Fusion 2 applications require explicitly creating a Fusion 2 App ID on the Photon Dashboard.

Read the Fusion Shared Mode Basics - Create An App ID tutorial for more information.

New Demo Menu

The new demo menu allows you to kick start your Fusion development by providing a template menu for prototyping.

It shows many commonly used features such as random matchmaking and party based matchmaking by sharing a party code.

It was designed to be extendable and handle the complexity of dealing with connection logic. Unfortunately these design goals compete with each other, but this solution tries to balance them reasonably.

fusion 2 demo menu
fusion 2 demo menu
fusion 2 demo menu
fusion 2 demo menu
fusion 2 demo menu
fusion 2 demo menu

Lag Compensation

Positioning animated hitboxes ahead of Render is no longer necessary to have them in the correct position for lag compensation. The lag compensation system now automatically uses the correct interpolated animation position from Render which matches what the player saw on their screen.

Lag compensation now also supports 2D use cases and allows querying against the 2D physics scene.

In addition, 3D capsule hitboxes are also supported now.

NetworkObjectProvider

INetworkObjectPool has been replaced with INetworkObjectProvider, providing a more consistent and complete API. The default implementation is now able to load & spawn objects asynchronously.

To accommodate these new features, NetworkRunner.TrySpawn and an awaitable NetworkRunner.SpawnAsync method have been added. Addressables no longer have to be preloaded or waited for with WaitForCompletion!

Unused Addressable prefabs can now be unloaded immediately after their instance count has reached zero or at user’s discretion with NetworkRunner.Prefabs.UnloadUnreferenced.

All of the above can now be verified in NetworkPrefabsInspector window - which allows inspecting which network prefabs have been loaded, spawned and what their instance count is.

SendReliableData

The reliable data streaming API was reworked, bringing many new quality-of-life improvements. It automatically splits data into fragments which are streamed to the target client and reassembled. Once the full data is received a callback with the data is invoked. Another callback is provided to track the status of the data transfer.

Example code:

C#

byte[] largeData = new byte [10000];

// Provide 4 numbers as a unique key for the data
var key = ReliableKey.FromInts(42, 0, 0, 0);

// Use in shared mode or as the server/host to send data to players
runner.SendReliableDataToPlayer(playerRef, key, largeData);

// Use as a client to send data to the server/host
runner.SendReliableDataToServer(key, largeData);

Callbacks for receiving the data (INetworkRunnerCallbacks):

C#

public void OnReliableDataReceived(NetworkRunner runner, PlayerRef player, ReliableKey key, ArraySegment<byte> data){}

public void OnReliableDataProgress(NetworkRunner runner, PlayerRef player, ReliableKey key, float progress){}    
Back to top