Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
coherence uses the concept of ownership to determine who is responsible for simulating each Entity. By default, each Client that connects to the Replication Server owns and simulates the Entities they create. There are a lot of situations where this setup is not adequate. For example:
The number of Entities could be too large to be simulated by the players on their own, especially if there are few players and the World is very large.
The game might have an advanced AI that requires a lot of coordination, which makes it hard to split up the work between Clients.
It is often desirable to have an authoritative object that ensures a single source of truth for certain data. State replication and "eventual correctness" doesn't give us these guarantees.
Perhaps the game should run a persistent simulation, even while no one is playing.
With coherence, all of these situations can be solved using dedicated Simulators. They behave very much like normal Clients, except they run on their own with no player involved. Usually, they also have special code that only they run (and not the clients). It is up to the game developer to create and run these programs somewhere in the cloud, based on the demands of their particular game.
Simulators can also be independent from the game code. A Simulator could be a standalone application written in any language, including C#, Go or C++, for instance. We will post more information about how to achieve this here in the future. For now, if you would like to create a Simulator outside of Unity, please contact our developer relations team.
To use Simulators, you need to enter your credit card details. You can do it by logging into our Dashboard, selecting the Billing tab, finding the Payment Methods section and clicking the Manage button.
If you're on the Free plan, you won't be charged anything - our payment provider will temporarily reserve a small amount to verify that the credit card is in working order.
Only Paid and Enterprise plans offer Simulators external network connectivity. When switching from Free plan to a Paid or Enterprise plan, it may take up to 10 minutes for the Simulators to have their external connectivity enabled.
If you have determined that you need one or more Simulator for your game, there are multiple ways you can go about implementing these. You could create a separate Unity project and write the specific code for the Simulator there (while making sure you use the same schema as your original project).
An easier way is to use your existing Unity project and modify it in a way so that it can be started either as a normal Client, or as a Simulator. This will ensure that you maximize code sharing between Clients and Servers - they both do simulation of Entities in the same Game World after all.
To force a build to start as a Simulator, you can use the following command line argument:
The Simulator is started with the following parameters in coherence Cloud:
Important: if you want to deploy Simulators on the coherence Cloud, they have to be built for Linux 64-bit.
The SDK provides a static helper class to access all the above parameters in the C# code called SimulatorUtility
.
To build Simulators, it's best to use the Linux Dedicated Server Build Target.
This is great for Simulators since we're not interested in rendering any graphics on these outside of local development. You will also get a leaner executable that is smaller and faster to be published in coherence Cloud.
When a room has only Simulators (no Clients) it shuts down automatically after a short period of time.
Refer to the Simulator: Build and deploy section.
coherence allows us to use multiple Simulators to split up a large game world with many entities between them. This is called spatial load balancing.
You can see load balancing in action in this video:
While load balancing is supported for standalone projects, our cloud services currently only support associating one Simulator to a Room or World. This will be extended in the near future. Enterprise customers can still run multiple Simulators in their own cloud environment.
World Simulators are started and shut down with the World. They can be enabled and assigned in the Worlds section of the Developer Portal.
When scripting Simulators, we need mechanisms to tell them apart.
Ask Coherence.SimulatorUtility.IsSimulator
.
There are two ways you can tell coherence if the game build should behave as a Simulator:
COHERENCE_SIMULATOR
preprocessor define.
--coherence-simulation-server
command-line argument.
Connect
and ConnectionType
The Connect
method on Coherence.Network
accepts a ConnectionType
parameter.
Whenever the project compiles with the COHERENCE_SIMULATOR
preprocessor define, coherence understands that the game will act as a Simulator.
Launching the game with --coherence-simulation-server
will let coherence know that the loaded instance must act as a Simulator.
You can supply additional parameters to a Simulator that define its area of responsibility, e.g. a sector/quadrant to simulate Entities in and take authority over Entities wandering into it.
You can also build a special Simulator for AI, physics, etc.
You can define who simulates the object in the CoherenceSync inspector.
coherence includes an auto-connect MonoBehaviour out of the box for Room- and World-based Simulators. The Component its called AutoSimulatorConnection.
Multi-Room Simulators have their own per-scene reconnect logic. The AutoSimulatorConnection components should not be enabled when working with Multi-Room Simulators.
If the Simulator is invoked with the --coherence-play-region
parameter, AutoSimulatorConnection will try to reconnect to the Server located in that region.
Before deploying a Simulation Server, testing and debugging locally can significantly improve development and iteration times. There are a few ways of accomplishing this.
Using the Unity Editor as a Simulator allows us to easily debug the Simulator. This way we can see logs, examine the state of scenes and GameObjects and test fixes very rapidly.
To run the Editor as a Simulator, run the Editor from the command line with the proper parameters:
--coherence-simulation-server
: used to specify that the program should run as a coherence Simulator.
--coherence-simulator-type
: tells the Simulator what kind of connection to make with the Replication Server, can be Rooms or World.
--coherence-region
: tells the Simulator which region the Replication Server is running in: EU, US or local.
--coherence-ip
: tells the Simulator which IP it should connect to. Using 127.0.0.1 will connect the Simulator to a local server, if one is running.
--coherence-port
: specifies the port the Simulator will use.
--coherence-world-id
: specifies the World ID to connect to, used only when set to Worlds.
--coherence-room-id
: specifies the Room ID to connect to, used only when set to Rooms.
--coherence-unique-room-id
: specifies the unique Room ID to connect to, used only when set to Rooms.
For example:
If you're not sure which values should be used, adding a COHERENCE_LOG_DEBUG
define symbol will let you see detailed logs. Among them are logs that describe which IP, port and such the Client is connecting to. This can be done in the Player settings: Project Settings > Player > Other Settings > Script Compilation > Scripting Define Symbols.
Another option is making a Simulator build and running it locally. This option emulates more closely what will happen when the Simulator is running after being uploaded.
You can run a Simulator executable build in the same way you run the Editor.
This allows you to test a Simulator build before it is uploaded or if you are having trouble debugging it.
You can also run existing Simulator build from coherence Hub > Simulators > Run local simulator build.
Use the Fetch Last Endpoint button to autofill the required fields.
When using a Rooms-based setup, you first have to create a Room in the local Replication Server (e.g. by using the connect dialog in the Client).
The local Replication Server will print out the Room ID and unique Room ID that you can use when connecting the Simulator.
World simulation servers are started with the command line parameters described in the section.
When you add the Component, it will parse the connection data passed with to connect to the given Replication Server automatically. This will also work for Simulators you upload to the coherence Cloud.
Keep in mind that all regular Unity arguments are supported. You can see the full list here: .
To learn more about Simulators, see .
To learn more about creating a Simulator build, see .
Simulators per room can be enabled in the dashboard for the project. The Simulator used is matched according to the Simulator slug in the RuntimeSettings scriptable object file. This is set automatically when you upload a Simulator.
For each new Room, a Simulator will be created with the command line parameters described in the Simulators section. The Simulator is shutdown automatically when the Room is closed.
Simulate multiple Rooms at the same time, within one Unity instance
Multi-Room Simulators are Room Simulators which are able to simulate multiple game rooms at the same time - one sim to rule them all!
In order to achieve this, the game code should be defensive on which room it is affecting. Game state should be kept per Room, meaning game managers, singletons (static data), etc. need to account for this.
Each Room is held in a different scene. So for every Room created, the Multi-Room Simulator should open a connection to it, hence loading additively a scene and stablishing a Simulator connection (via Bridge).
By using Multi-Room Simulators, the coherence Developer Portal is able to instruct your Simulator which room to join and start simulating.
This communication happens via HTTP. An HTTP server is started by your game build when the MultiRoomSimulator
component is active. This component listens to HTTP requests made by the coherence __ Developer Portal.
For offline local development, you can use a MultiRoomSimulatorLocalForwarder
component on your clients, which will create HTTP requests against your local simulator upon client connection, like joining a room.
For local development, enable the Local Development Mode
flag in the project settings.
Once the MultiRoomSimulator
receives a request to join a room, it spawns a CoherenceSceneLoader
that will be in charge of loading additively the scene specified.
By default, scenes will have their physics scene. coherence ticks the physics scene on the CoherenceScene
component, which the target scene to be loaded should include.
The quickest way to get Multi-Room Simulators set up is by using the provided wizard.
It will take you through the GameObjects and Components needed to make it happen.
Here's a quick overview video of the setup:
These are the pieces needed for Multi-Room Simulators to work:
Simulators
In the initialization scene (splash, init, menu, ...)
MultiRoomSimulator — listens to join room requests and delegates scene loading (by instantiating CoherenceSceneLoaders)
Clients
(Only for local development) In the scene where you connect to a Room (where you have the Sample UI or your custom connection logic)
MultiRoomSimulatorLocalForwarder — requests the local MultiRoomSimulator to join rooms when the Client connects.
Independently
In the scene where the networked game logic is (game, Room, main, ...)
Bridge — handles the connection
LiveQuery — filters Entities by distance
CoherenceScene — when the scene is loaded via CoherenceSceneLoader, it will try to connect using the data given by it. It attaches to the Bridge, creates a connection, and handles auto reconnection. If a scene loaded through CoherenceSceneLoader doesn't have a CoherenceScene on it, one will be created on the fly.
There are two components that can help you fork Client and Simulator logic, for example, by enabling or disabling the MultiRoomSimulator component depending on whether it's a Simulator or a Client build. These are optional but can come in handy.
SimulatorEventHandler — events on the build type (Client/Simulator).
ConnectionEventHandler — events on the connection stablished by the Bridge associated with that Scene.
It is possible to visualize each individual Room the Multi-Room Simulator is working on. By default, Simulator connections to Rooms are hidden, as shown in the image above. You can toggle the visibility per scene by clicking the Eye icon. You can also change the default visibility of the loaded scene (defaults to hidden) on the CoherenceScene component:
Working with Multi-Room Simulators needs your logic to be constrained to the scene. Methods like FindObjectsOfType will return objects in all scenes — you could affect other game sessions!
Check out Coherence.Toolkit.SceneUtils
for alternative APIs to FindObjectsOfType
that work per scene.
Also, Coherence.Toolkit.ActiveSceneScope
can help make sure instantiation happens where you want it to be.
This is also true for static members, e.g. singletons. When using Multi-Room Simulators, there need to be as many isolated instances of your managers as there are open simulated rooms.
For example, if you were to access your Game Manager through GameManager.instance
, now you'll need a per-scene API like GameManager.GetInstance(scene)
.
There may be third-party or Unity-provided features that can't be accessed per scene, and that affect the whole game.
Loading operations, garbage collections, frame-rate spikes... all these will affect performance on other sessions, since everything is running within the same game instance.
Multi-Room Simulators are still Room Simulators. You need to enable Simulators for Rooms and enable Multi-Room Simulators in the coherence Developer Portal, as shown here:
When using the Simulators tab in the coherence Hub, you can specify a Simulator slug. This is simply a unique identifier for a Simulator. This value is automatically saved in RuntimeSettings
when an upload is complete, and Room creation requests will use this value to identify which Simulator should be started alongside your room.
The Simulator slug can be any string value, but we recommend using something descriptive. If the same slug is used between two uploads, the later upload will overwrite the previous Simulator.
A list of uploaded Simulators and their corresponding slugs can be found in the Developer Portal:
A Simulator build is a built Unity Player for the Linux 64-bit platform that you can upload to coherence straight from the Unity Editor.
Open Coherence Hub and select the Simulators tab.
From here you can build and upload Simulators.
Click the little info icon in the top right corner to learn more about Simulators and how to build them properly.
You can change your Simulator build options by editing the SimulatorBuildOptions object, or in the coherence Hub Simulators tab.
There are several settings you might want to change.
Specify the scenes you want to get in the build via the Scenes To Build field.
For a local build, you can choose to enable/disable the Headless Mode by ticking the checkbox. For a cloud build, Headless Mode is always enabled by default.
For more information about the options listed under Build Size Optimizations, see this section below.
Make sure you have completed the steps required in Create an account.
Make sure you meet the requirements:
You have to have Linux modules (Linux Build Support (IL2CPP)
, Linux Build Support (Mono)
, and Linux Dedicated Server Build Support
) installed in Unity Editor. See Unity - Manual: Adding modules to the Unity Editor.
You have to be logged into the coherence Developer Portal, through the Unity Editor. See Login through Unity for more information.
Press the coherence Hub > Simulators > Build And Upload Headless Linux Client button.
When the build is finished, it will be uploaded to your currently selected organization and project in the Developer Portal.
You'll see in the developer dashboard when your Simulator is ready to be associated with a Room or World.
Target frame rate on Simulator builds is forced at 30.
This feature is experimental, please make sure you make a backup of your project beforehand.
You can set the values for the Build Size Optimizations in the drop-down list of the build configuration inspector. It looks like this:
Select the desired optimizations depending on your needs.
Once your Simulator is built and uploaded, you'll be prompted with the option to revert the settings to the ones you had applied before building. This is to avoid these settings from affecting other builds you make.
Optimization | What it does |
---|---|
Flag | Description |
---|---|
Replace Textures And Sounds With Dummies
Project's textures and sound files are replaced with tiny and lightweight alternatives (dummies). Original assets are copied over to <project>/Library/coherence/AssetsBackup. They are restored once the build process has finished.
Keep Original Assets Backup
The Assets Backup (found at <project>/Library/coherence/AssetsBackup) is kept after the build process is completed, instead of deleted. This will take extra disk space depending on the size of the project, but is a safety convenience.
Compress Meshes
Sets Mesh Compression on all your models to High.
Disable Static Batching
Static Batching tries to combine meshes at compile-time, potentially increasing build size. Depending on your project, static batching can affect build size drastically. Read more about static batching.
--coherence-play-region
eu
, us
(or local
).
--coherence-ip
Specific IP to point to.
--coherence-port
Specific port to point to.
--coherence-room-id
Specific Room to point to.
--coherence-room-tags
Room tags (space-separated).
--coherence-room-kv
Key-value pairs (space-separated). Example:
key1 value1 key2 value2
--coherence-world-id
Specific World ID to point to.
--coherence-simulation-server
Connect and behave as a Simulator.
--coherence-simulator
Same as --coherence-simulation-server
.