> For the complete documentation index, see [llms.txt](https://kinematicsoup.gitbook.io/reactor/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kinematicsoup.gitbook.io/reactor/examples/execution_order.md).

# 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](/reactor/examples/timescaling.md) 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.

```
using KS.Reactor.Server;

public class srSkipUpdateCheck : ksServerRoomScript
{
    // Called after all other scripts on all entities are attached.
    public override void Initialize()
    {
        // Register an update handler in update group -100 so it runs before other scripts.
        Room.OnUpdate[-100] += Update;
    }
    
    // Called when the script is detached.
    public override void Detached()
    {
        Room.OnUpdate[-100] -= Update;
    }
    
    // Called during the update cycle
    private void Update()
    {
        // Skip running update groups after group -100 if there are no connected players.
        Room.SkipFrameUpdates = Room.ConnectedPlayerCount == 0;
        
        // Set time scale to 0 to prevent the physics simulation step if there are no connected players.
        Time.TimeScale = Room.SkipFrameUpdates ? 0f : 1f;
    }
}
```

## Execution Order of Events and Scripts

For each frame:

* Invoke `Room.OnPlayerJoin` events for new players.
* Invoke RPCs from players.
* Invoke `Room.OnPlayerLeave` events 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.
