Server Execution Order
Summary
Shows the execution order of events and scripts on the server, and how to control when scripts update using update groups. For example, you can use update groups to ensure all hit detection code runs after all movement code.
Update Groups
Update handlers in server scripts are registered using Room.OnUpdate[groupNum] += Update; where groupNum is an integer that identifies which update group the handler is registered with and controls when and how it updates. All update handlers in group N will run before the handlers in group N+1. Handlers in the same group are called in the order they were registered. The update group number can be any integer. Calling Room.OnUpdate[groupNum] with a groupNum that does not exist will create a new update group.
The physics simulation step runs after the update handlers in update group -1, and before the update handlers in group 0.
Running Updates Only On Sync Frames
Setting Room.OnUpdate[groupNum].SyncFrameOnly = true; will make the update handlers in the group groupNum only get called on sync frames. Sync frames are the frames after which a snapshot of the server state is sent to players.
Running Updates in Parallel
Setting Room.OnUpdate[groupNum].Parallel = true; will make the update handlers in the group groupNum run in parallel. The next update group will not begin processing until all parallel updates in the current group are finished, so long blocking calls should not be made from parallel updates. Adding or removing update handlers from an update group while its updates are being processed in parallel is not allowed and will throw an exception.
When running updates in parallel you must be careful about thread-safety. It is not safe to spawn or destroy entities in parallel. Writing properties, updating transforms, or adding/removing scripts on the same object from multiple threads is also not thread-safe. It is best-practice to have only one update handler in a parallel update group per entity that only modifies that entity, so you don't end up with two threads modifying the same entity at the same time. You can safely run physics queries in parallel update groups.
Preventing Updates from Running
Setting Room.SkipFrameUpdates = true; will prevent updates handlers from running. If set from an update handler, all handlers in the current update group will finish running, but later update groups will not run. This values is set to false at the end of each frame. Setting it to true will not prevent the physics simulation step from running. To prevent the physics simulation step from running, set the time scale to zero. Time.TimeScale = 0;
Here is a simple room script that prevents updates and the physics simulation step from running when there are no players connected.
Execution Order of Events and Scripts
For each frame:
Invoke
Room.OnPlayerJoinevents for new players.Invoke RPCs from players.
Invoke
Room.OnPlayerLeaveevents for disconnected players.Invoke cluster RPCs from other rooms.
Update player controllers.
Update coroutines
Run updates for update groups below 0.
Run physics simulation step.
Invoke physics events.
Invoke sleep events.
Invoke wake events.
Invoke collision/overlap events.
Invoke broken joint events.
Run updates for update groups 0+.
Detach scripts from destroyed entities and call
Detached()on the scripts.
Room.OnSpawnEntity and Room.OnDestroyEntity are invoked immediately when you spawn or destroy entities.
Last updated

