Message Types and Delivery

This networking library uses a small set of message types to communicate between clients and the server. Each message type has a specific purpose (RPC, Sync, Instantiate, Destroy, etc.), and each can be sent with different delivery methods depending on whether the data must arrive reliably or can tolerate loss.

Message Types

The library defines message types in UCNetwork.MessageType. These are sent as the first integer of every network packet.

MessageType

ID

Purpose

SyncUpdate

1

Full sync: position, rotation, and custom byte data. Used for continuous updates.

Instantiate

2

Spawn a new object across the network.

AddToArea

3

Client requests entry into an area.

RemoveFromArea

4

Client requests to leave an area.

RPC

5

Remote Procedure Call (discrete actions).

IdAllocation

6

Server grants a pool of object IDs.

OwnershipGained

7

Notify a client it now owns an object.

OwnershipLost

8

Notify a client it lost ownership.

Destroy

9

Remove an object from all clients.

VoiceData

10

(Stubbed) Voice chat packets.

LiteSyncUpdate

11

Custom byte data only, no transform.

ConnectNetworkSync

12

Attach an existing scene object to the networking system.

AddObjectToArea

13

Place a specific object into an area.

RemoveObjectFromArea

14

Remove a specific object from an area.

Message Receivers

Every RPC or Sync message specifies a MessageReceiver, which tells the server who should receive the message.

Defined in UCNetwork.MessageReceiver:

  • ServerOnly (1) Execute only on the server.

  • AllClients (2) Forward to every connected client.

  • OtherClients (4) Forward to all clients except the sender.

  • AllClientsInArea (8) Forward to all clients in the same area(s).

  • OtherClientsInArea (16) Forward to all clients in the same area(s), except the sender.

  • SingleClient (32) Forward only to one client, chosen by ID.

Delivery Methods

Different messages have different reliability needs. The library uses Lidgren’s delivery options, exposed as UCNetwork.DeliveryMethod:

  • ReliableOrdered Packets are guaranteed to arrive and arrive in order. Best for object lifecycle events (Instantiate, Destroy, Ownership).

  • UnreliableSequenced Packets may be dropped, but only the newest one is kept. Best for high-frequency updates (SyncUpdate, LiteSyncUpdate).

Sequence Channels

The library separates traffic into sequence channels to avoid interference between streams:

  • SyncSequenceChannel = 10 For SyncUpdate and LiteSyncUpdate (continuous state).

  • VoiceSequenceChannel = 11 Reserved for voice chat (stubbed).

Example: Choosing Delivery

  • Instantiate – Must always arrive → ReliableOrdered.

  • Destroy – Must always arrive → ReliableOrdered.

  • RPC (OpenDoor) – Must arrive and in order → ReliableOrdered.

  • SyncUpdate (movement) – Can drop old updates; newest is enough → UnreliableSequenced.

  • LiteSyncUpdate (ammo count, animation state) – Can drop old updates → UnreliableSequenced.

Message Flow Diagram

Client A (owner)               Server                 Client B (replica)
     |                          |                            |
     |-- SyncUpdate (UnrelSeq) ->|                            |
     |                          |-- forward SyncUpdate ----->|
     |                          |                            |
     |-- RPC(OpenDoor, Reliable)->|-- forward RPC ----------->|
     |                          |                            |
     |-- Destroy(Obj42,Reliable)->|-- forward Destroy ------->|

Best Practices

  • Pick the narrowest MessageReceiver possible to reduce bandwidth.

  • Use ReliableOrdered only when loss or reordering would break the game.

  • Use UnreliableSequenced for frequent, continuous state (movement).

  • Keep separate channels for different kinds of traffic.

  • Always expect loss, duplication, and reordering; code defensively.

  • Avoid sending large payloads in RPCs; pass IDs, not full objects.

Summary

  • All messages are categorized by MessageType and have a known ID.

  • MessageReceiver defines who executes the message.

  • DeliveryMethod defines how the packet is delivered (reliable vs unreliable).

  • Use the correct combination for each gameplay case.

  • Design for bandwidth efficiency and robustness.