WebSocket Protocol Documentation

Welcome to the Life-Itself API documentation. This document outlines the WebSocket protocol used to communicate with the simulation server, enabling you to build your own clients, tools, and visualizations.

1. Connection & Protocol

The server exposes a WebSocket endpoint. All communication is performed using binary frames. Data payloads are serialized with MessagePack and then compressed with GZip for maximum efficiency.

Endpoint: ws://your-server-address:5050

2. Communication Flow

  1. On Connect: The client establishes a WebSocket connection.
  2. Receive Full State: The server immediately sends a message with `MessageType = 1 (FullState)`. This contains a compressed `SimSaveState` object with the entire world state.
  3. Client Ready: After processing the initial state, the client must send a simple text message `"READY"` to the server to begin receiving incremental updates.
  4. Receive Delta States: Subsequently, the server will periodically broadcast messages with `MessageType = 2 (DeltaState)`, containing compressed `SimDeltaState` objects.

3. Data Models (MessagePack Keys)

The following are the primary C# data structures serialized with MessagePack. The key numbers correspond to the `[Key(n)]` attributes in the source code.

SimSaveState `(FullState)`

// C# Class: SimSaveState
[MessagePackObject]
public class SimSaveState {
    [Key(0)] public float CurrentTime;
    [Key(1)] public List<NPC> Npcs;
    [Key(2)] public WorldData WorldState;
    [Key(3)] public List<District> Districts;
}

SimDeltaState `(DeltaState)`

// C# Class: SimDeltaState
[MessagePackObject]
public class SimDeltaState {
    [Key(0)] public float CurrentTime;
    [Key(1)] public List<NPC> NpcUpdates;
    [Key(2)] public List<Guid> NpcRemovals;
    [Key(3)] public List<Cell> CellUpdates;
}

NPC

// C# Class: NPC
[MessagePackObject]
public class NPC {
    [Key(0)] public Guid Id;
    [Key(1)] public string Name;
    [Key(2)] public (int X, int Y) Position;
    [Key(3)] public string CurrentStatus;
    [Key(4)] public float NextTickTime;
    [Key(5)] public int Age;
    [Key(6)] public int Health;
    [Key(7)] public List<Need> Needs;
}

Cell

// C# Class: Cell
[MessagePackObject]
public class Cell {
    [Key(0)] public (int X, int Y) Position;
    [Key(1)] public Building? Building;
    [Key(2)] public int DistrictId;
}

District

// C# Class: District
[MessagePackObject]
public class District {
    [Key(0)] public string DistrictName;
    [Key(1)] public int DistrictId;
    [Key(2)] public List<Building> Buildings;
}

Building

// C# Class: Building
[MessagePackObject]
public class Building {
    [Key(0)] public string Name;
    [Key(1)] public double Weight;
    [Key(2)] public List<Satisfaction>? Satisfactions;
}

Need

// C# Class: Need
[MessagePackObject]
public class Need {
    [Key(0)] public string Name;
    [Key(1)] public float DecayRate;
    [Key(2)] public float Threshold;
    [Key(3)] public float Amount;
}

Satisfaction

// C# Class: Satisfaction
[MessagePackObject]
public class Satisfaction {
    [Key(0)] public string NeedName;
    [Key(1)] public float Amount;
    [Key(2)] public float TimeCostInHours;
}

4. Client Interaction

After establishing a WebSocket connection and receiving the initial FullState, clients must signal their readiness to receive delta updates. This is done by sending a simple text message.

Sending "READY" Signal:

// Example in JavaScript (WebSockets API)
websocket.send("READY");

// Example in C# (Client-side)
byte[] readyBytes = Encoding.UTF8.GetBytes("READY");
await webSocket.SendAsync(new ArraySegment<byte>(readyBytes), WebSocketMessageType.Text, true, CancellationToken.None);

Upon receiving "READY", the server will begin broadcasting DeltaState messages periodically.