Performance & Optimizations
Interest Management
The BR200 uses the Eventual Consistency replication mode that allows clients to receive data only about network objects they are interested in. This improves performance and reduces network traffic. Learn more in Interest Management Manual.
Every player defines a cone-shaped area based on camera direction to receive information about objects in front and close to them. The Interest Management addon is used to define player's interest.
The player only receives state for objects within the area, other objects are not synchronized.
The BR200 also contains special components to further reduce performance cost and network traffic:
StaticNetworkTransform
One-time position/rotation synchronization of static objects upon spawn. StaticNetworkTransform
is used for item boxes. There could be hundreds of boxes in the level and usage of StaticNetworkTransform
is more optimal than NetworkTransform
.
NetworkAreaOfInterestProxy
NetworkAreaOfInterestProxy
is used for objects that don't need to synchronize position or rotation but still need to be filtered by the interest management system. For example, weapons that are parented under an owning Agent
don't need to synchronize transforms, but their networked data should be received based on whether the weapon is in the player's area of interest or not. The position for AoI calculations is taken from a specified object. In the case of the weapon, it is based on the owning agent position. This feature has zero network traffic overhead.
Although the features above have a major impact on network traffic, there is still some space for further improvements:
- 💡 Better area of interest cone limits based on level design
- 💡 Precalculated visibility zones
Additional info about the interest management can be found in the Interest Management Manual and Interest Management Addon.
Benchmarks
The recommended maximum player count for stable 60Hz simulation on headless dedicated server instance:
Configuration (Hardware + Build type) | Player Count |
---|---|
Mac Mini M1 2020, Mac server (Silicon) | 200 |
Core i9-10900K, Windows server | 200 |
Unity Game Server Hosting Bare Metal (Intel® Xeon® E-2288G @ 3.70GHz), Linux server | 200 |
Unity Game Server Hosting Virtual Machine (GCP N2 - Intel® Xeon® @ 2.80GHz), Linux server | 60 - 80 |
The actual performance and the player count highly depend on the gameplay mode. Deathmatch, where all players are active all the time, is always more demanding than Battle Royale where eliminated players have low overhead. It is also affected by level design (map size, player density) and gameplay design (forcing players to constantly move/look/shoot has a different impact than 200 campers). Numbers above represent the worst case scenario - first minute after the spawn - all players actively moving, looking and shooting.
Note on Unity Game Server Hosting virtual machines:
Another factor which affects the performance is the specification of currently allocated hardware. While one match (game server instance) can barely handle 60 players, another runs 100 players without any problems. This is caused by different hardware specifications. Running on a bare metal server is recommended for higher player counts and better stability.
Profiling
In addition to common profiling tools, this sample provides tools for offline analysis of the game in release mode. When the game is launched with the -recordSession
parameter, engine delta time and player count are recorded every frame and stored in a file in CSV format. Then this file can be processed by provided Python scripts (available in Assets/Extras.zip
) which will generate HTML files with graphs.
The file is created at the Application.persistentDataPath
path or at the path specified in the -dataPath XXX
command.
The image above shows an increasing player count (up to 200) represented by the blue line and engine delta time (being stable most of the time with few peaks above 16ms). Aside from DeltaTime
and PlayerCount
, you can create your own set of tracked properties with a custom StatsRecorder
instance.
Pooling
In shooter projects, a large amount of object spawning is expected (projectiles, muzzle effect, impacts, hit effects,...). Since instantiation of a new object is expensive, everything in BR200 is pooled.
There are two types of pools:
NetworkObjectPool
is used to pool theNetworkObjects
. TheNetworkObjectPool
implements theINetworkObjectProvider
interface and is passed into theNetworkRunner.StartGame
function in theNetworking
script. For more information, check out the Network Object Provider section in the Fusion Manual.ObjectCache
is a genericGameObject
pool that's used for non-networked objects such as impact effects. It comes with a feature to return objects after a specified delay.ObjectCache
is accessible in other parts of the code through the SceneContext.