| name | networking-servers |
| version | 2.0.0 |
| description | Multiplayer systems, netcode, game servers, synchronization, and anti-cheat.
Build scalable, responsive multiplayer experiences.
|
| sasmp_version | 1.3.0 |
| bonded_agent | 05-networking-multiplayer |
| bond_type | PRIMARY_BOND |
| parameters | [{"name":"architecture","type":"string","required":false,"validation":{"enum":["client_server","p2p","hybrid","dedicated"]}},{"name":"framework","type":"string","required":false,"validation":{"enum":["photon","mirror","netcode","fishnet","custom"]}}] |
| retry_policy | {"enabled":true,"max_attempts":5,"backoff":"exponential","jitter":true} |
| observability | {"log_events":["start","complete","error","reconnect"],"metrics":["latency_ms","packet_loss","bandwidth_kbps","player_count"]} |
Networking & Game Servers
Network Architecture
CLIENT-SERVER (AUTHORITATIVE):
┌─────────────────────────────────────────────────────────────┐
│ DEDICATED SERVER │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ • Authoritative game state │ │
│ │ • Physics simulation │ │
│ │ • Hit validation │ │
│ │ • Anti-cheat checks │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↑↓ ↑↓ ↑↓ ↑↓ │
│ [Client A] [Client B] [Client C] [Client D] │
│ └─ Prediction └─ Prediction └─ Prediction └─ Prediction│
└─────────────────────────────────────────────────────────────┘
Netcode Implementation
Client Prediction with Reconciliation
public class NetworkedMovement : NetworkBehaviour
{
private struct InputPayload
{
public uint Tick;
public uint Sequence;
public Vector2 MoveInput;
public bool Jump;
}
private Queue<InputPayload> _pendingInputs = new();
private CircularBuffer<PlayerState> _stateHistory;
private uint _inputSequence;
private void Update()
{
if (!IsOwner) return;
var input = new InputPayload
{
Tick = NetworkManager.ServerTime.Tick,
Sequence = _inputSequence++,
MoveInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis()),
Jump = Input.GetButtonDown()
};
ApplyInput(input);
_pendingInputs.Enqueue(input);
_stateHistory.Add(GetCurrentState());
SendInputServerRpc(input);
}
[]
{
(!IsOwner) ;
(_pendingInputs.Count > && _pendingInputs.Peek().Sequence <= ackedSequence)
_pendingInputs.Dequeue();
predictedState = _stateHistory.Get(ackedSequence);
(Vector3.Distance(predictedState.Position, serverState.Position) > )
{
SetState(serverState);
( input _pendingInputs)
ApplyInput(input);
}
}
}