Packets
Packets are the data structures exchanged between clients and the server. Every packet implements IPacketBase and carries a MessageCode that identifies its type.
Packet Architecture
Altruist uses a layered packet system:
- IPacketBase — Your packet data (the payload)
- MessageEnvelope — Wraps the packet with a
PacketHeader(sender, receiver, timestamp)
When a client sends data, the framework:
- Decodes the raw bytes into an
AltruistPacketto read theeventfield - Looks up the matching
[Gate]handler - Decodes the raw bytes again into the handler's specific packet type
- Calls the handler
Defining a Custom Packet
using System.Text.Json.Serialization;
using Altruist;
using MessagePack;
[MessagePackObject]
public struct ChatPacket : IPacketBase
{
[Key(0)]
public uint MessageCode { get; set; }
[Key(1)]
[JsonPropertyName("text")]
public string Text { get; set; }
public ChatPacket()
{
MessageCode = 1000;
Text = string.Empty;
}
public ChatPacket(string text)
{
MessageCode = 1000;
Text = text;
}
}
Rules
MessageCodemust always be at[Key(0)]- Framework packets use codes 0–999; user packets start at 1000+
- Packets can be
struct(recommended for small data) orclass - Both
[MessagePackObject]+[Key](for MessagePack) and[JsonPropertyName](for JSON) annotations are supported
MessageCode Constants
Organize your packet codes in a static class:
public static class PC
{
// Auth & Login (1000-1099)
public const uint Login = 1001;
public const uint LoginSuccess = 1002;
public const uint LoginFailure = 1003;
// Chat (1300-1349)
public const uint Chat = 1300;
public const uint Whisper = 1301;
// Movement (1200-1249)
public const uint Move = 1200;
}
Built-in Framework Packets
| Packet | MessageCode | Description |
|---|---|---|
TextPacket | 1 | Simple text message |
InterprocessPacket | 2 | Server-to-server communication |
SyncPacket | 3 | Entity synchronization data |
AltruistPacket | 4 | Generic event packet (has Event field for routing) |
SuccessPacket | 5 | Success result with optional payload |
FailedPacket | 6 | Failure result with error reason |
HandshakeRequestPacket | 7 | Client handshake request |
HandshakeResponsePacket | 8 | Server handshake response |
JoinGamePacket | 9 | Join game session request |
LeaveGamePacket | 10 | Leave game session request |
RoomPacket | 11 | Room information |
SessionAuthContext | 12 | Session authentication |
PacketHeader
Every packet sent by the server is wrapped in a MessageEnvelope containing a PacketHeader:
public struct PacketHeader
{
public long Timestamp { get; set; } // Server timestamp (ticks)
public string? Receiver { get; set; } // Target client ID
public string Sender { get; set; } // "server" for server-sent packets
}
Sending Packets
Use IAltruistRouter to send packets from within a portal or service:
// Send to one client
await _router.Client.SendAsync(clientId, new ChatPacket("Hello!"));
// Send to a room
await _router.Room.SendAsync(roomId, new ChatPacket("Room message"));
// Broadcast to all
await _router.Broadcast.SendAsync(new ChatPacket("Server announcement"));
The router automatically wraps your packet in a MessageEnvelope and encodes it with the configured codec (JSON or MessagePack).
Client-Side: Sending Events
Clients send packets as the configured codec format (JSON shown here). The event field routes to the matching [Gate]:
{
"messageCode": 4,
"event": "chat",
"text": "Hello world!"
}
The messageCode: 4 tells the framework this is a generic AltruistPacket. The event field routes it to the [Gate("chat")] handler, where the full payload is deserialized into the handler's packet type.
Result Packets
For standardized success/failure responses, use the built-in helpers:
// Success with payload
var result = ResultPacket.Success(TransportCode.Ok, new TextPacket("Player joined!"));
// Failure with reason
var result = ResultPacket.Failed(TransportCode.BadRequest, "Username is required");
Transport Codes
| Code | Meaning |
|---|---|
| 200 | Ok |
| 201 | Created |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 409 | Conflict |
| 500 | Internal Server Error |