Skip to content

Latest commit

 

History

History
135 lines (99 loc) · 3.14 KB

networking.md

File metadata and controls

135 lines (99 loc) · 3.14 KB

Networking

Basebound is a multiplayer gamemode with full networking support. The game runs at 50 ticks/second with client-server architecture.

Overview

  • Architecture: Client-server with RPC system
  • Tick Rate: 50/sec (20ms per tick)
  • Max Players: 64
  • Synchronization: Event-based RPC with state broadcast

Basic Networking

Spawning Networked Objects

// Clone a networked prefab at a location
var go = PlayerPrefab.Clone(SpawnPoint.Transform.World);
go.NetworkSpawn();

RPC (Remote Procedure Call)

Broadcasting an action to all clients:

[Rpc.Broadcast]
public void OnJump() => Log.Info($"{this} jumped!");

Proxy Objects

When you don't control an object (another player's character), it's a proxy:

// Bad: Processes input for remote players
if (Input.Down("attack")) Fire();

// Good: Only process input if this client controls the object
if (!IsProxy && Input.Down("attack"))
{
    Fire();
}

Network Flow

sequenceDiagram
    participant Client1
    participant Server
    participant Client2
    
    Client1->>Server: Action (Jump, Build, etc)
    Server->>Server: Validate
    Server->>Client1: RPC Response
    Server->>Client2: Broadcast Update
    Client2->>Client2: Update Visual
Loading

Best Practices

Input Validation

  • Client: Apply input immediately for responsiveness (optimistic update)
  • Server: Validate all input before applying state changes
  • Broadcast: Update all other clients with validated results

RPC Methods

  1. Keep RPC methods focused and simple
  2. Validate parameters server-side
  3. Use [Rpc.Broadcast] for events all clients should see
  4. Consider bandwidth for frequently-called RPCs

State Synchronization

  • Use fixed timestep OnFixedUpdate() for state that changes every tick
  • Broadcast critical state changes via RPC
  • Minimize network traffic with delta updates

Network Performance

  • Avoid excessive RPC calls (use bundling when possible)
  • Synchronize only necessary game state
  • Use proxy checks to avoid duplicate processing
  • Profile network usage during development

Networking Patterns

Economy System (Example)

public class EconomySystem : Component
{
    protected override void OnFixedUpdate()
    {
        if (IsProxy) return; // Server-only
        
        // Update economy state
        UpdatePlayerBalance();
        
        // Broadcast changes to all clients
        BroadcastEconomyUpdate();
    }
    
    [Rpc.Broadcast]
    public void BroadcastEconomyUpdate()
    {
        // All clients update their local economy view
        RefreshUI();
    }
}

Base Building (Example)

public class BaseBuilder : Component
{
    [Rpc.Broadcast]
    public void PlaceBlock(Vector3 position, int blockType)
    {
        if (!IsProxy) return; // Only execute on non-owning clients
        
        var block = SpawnBlock(blockType, position);
        // All clients now see the placed block
    }
}

Related Documentation