Input queues enable a simulator to take control of the simulation of another client's objects based on the client's inputs.
In situations where you want a centralized simulation of all inputs. Many game genres use input queues and centralized simulation to guarantee the fairness of actions or the stability of physics simulations.
In situations where clients have low processing power. If the clients don't have sufficient processing power to simulate the world it makes sense to use input queue and just display the replicated results on the clients.
In situations where determinism is important. RTS and fighting games will use input queues and rollback to process input events in a shared (not centralized), and deterministic, way so that all clients simulate the same conditions and produce the same results.
coherence currently only supports using input queues in a centralized way where a single simulator is setup to process all inputs and replicate the results to all clients.
Setting up an object to simulate via input queues using CoherenceSync is done in three steps:
The Simulation Type of the CoherenceSync component is set to Simulation Server With Client Input
Setting the simulation type to this mode instructs the client to automatically give authority over this object to the simulator in charge of simulating all inputs on all objects.
Each simulated CoherenceSync component is able to define its own, unique set of inputs for simulating that object. An input can be one of:
Button. A button input is tracked with just a binary on/off state.
Button Range. A button range input is tracked with a float value from 0 to 1.
Axis. An axis input is tracked as two floats from -1 to 1 in both the X and Y axis.
String. A string value representing custom input state. (max length of 63 characters)
To declare the inputs used by the CoherenceSync component, the CoherenceInput component is added to the object. The input is named and the fields are defined.
In this example, the input block is named "Player Movement" and the inputs are WASD and "mouse" for the XY mouse position.
In order for the inputs to be simulated on CoherenceSync objects, they must be optimized through baking.
If the CoherenceInput fields or name is changed, then the CoherenceSync object must be re-baked to reflect the new fields/values.
When a simulator is running it will find objects that are set up using CoherenceInput components and will automatically assume authority and perform simulations. Both the client and simulator need to access the inputs of the CoherenceInput of the replicated object. The client uses the Set* methods and the simulator uses the Get* methods to access the state of the inputs of the object. In all of these methods, the name parameter is the same as the Name field in the CoherenceInput component.
public void SetButtonState(string name, bool value)
public void SetButtonRangeState(string name, float value)
public void SetAxisState(string name, Vector2 value)
public void SetStringState(string name, string value)
Simulator-Side Get* Methods
public bool GetButtonState(string name)
public float GetButtonRangeState(string name)
public Vector2 GetAxisState(string name)
public string GetStringState(string name)
For example, the mouse click position can be passed from the client to the simulator via the "mouse" field in the setup example.
The simulator can access the state of the input to perform simulations on the object which are then reflected back to the client as any replicated object is.
Each object only accepts inputs from one specific client, called the object's Input Owner.
When a client spawns an object it automatically becomes the Input Owner for that object. This way, the object's creator will retain control over the object even after authority has been transferred to the simulator.
If an object is spawned directly by the simulator, you will need to assign the Input Owner manually. Use the SetInputOwner method on the CoherenceInput component to assign or re-assign a client that will take control of the object:
The ClientId used to specify input owner can currently only be accessed from the ClientConnection class. For detailed information about setting up the ClientConnection prefab, see the Client connections page.
Use the OnInputOwnerAssigned event on the CoherenceSync component to be notified whenever an object changes input owner.
Generally, using server-side simulation with simulators makes the time from the client providing input to the time the object is updated with that input significantly longer than just client-side simulation because of the time required for the input to be sent to the simulator, processed, and then the updates to the object returned across the network. This can cause visual lag. Using input queues allows the client to perform prediction of the simulation to provide a smooth playing experience.
If the client simulates the inputs on the object as well as applying them to the CoherenceInput component and then blends the authoritative results from the simulator with the locally simulated results, then smoother and more responsive simulation is achieved.
Rollback is not currently available but is in the roadmap. Each client will be aware of the current global simulation frame and so the inputs can be applied by each client at the same frame in time and so client-side prediction can be even more accurate.