Client Packet Reference
Copy-paste these classes into your game client. They define every packet type the Altruist framework sends and expects.
Complete Client Types
Pick your language and drop the file into your project:
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using MessagePack;
namespace Altruist.Client
{
// ── Envelope ──────────────────────────────────────
[MessagePackObject]
public class PacketHeader
{
[Key(0)][JsonPropertyName("sender")] public string Sender { get; set; } = "";
[Key(1)][JsonPropertyName("receiver")] public string Receiver { get; set; } = "";
}
[MessagePackObject]
public class MessageEnvelope
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; }
[Key(1)][JsonPropertyName("header")] public PacketHeader Header { get; set; } = new();
[Key(2)][JsonPropertyName("message")] public object? Message { get; set; }
}
// ── Message Codes ─────────────────────────────────
public static class PacketCodes
{
public const uint Text = 1;
public const uint Sync = 3;
public const uint Altruist = 4; // Event routing
public const uint Success = 5;
public const uint Failed = 6;
public const uint HandshakeRequest = 7;
public const uint HandshakeResponse = 8;
public const uint JoinGame = 9;
public const uint LeaveGame = 10;
public const uint Room = 11;
public const uint SessionAuth = 12;
}
// ── Server → Client ───────────────────────────────
[MessagePackObject]
public class HandshakeResponse
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; }
[Key(1)][JsonPropertyName("rooms")] public RoomInfo[] Rooms { get; set; } = Array.Empty<RoomInfo>();
}
[MessagePackObject]
public class RoomInfo
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; }
[Key(1)][JsonPropertyName("id")] public string Id { get; set; } = "";
[Key(2)][JsonPropertyName("maxCapacity")] public uint MaxCapacity { get; set; }
[Key(3)][JsonPropertyName("connectionIds")] public HashSet<string> ConnectionIds { get; set; } = new();
}
[MessagePackObject]
public class SuccessPacket
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; }
[Key(1)][JsonPropertyName("code")] public int Code { get; set; }
[Key(2)][JsonPropertyName("payload")] public object? Payload { get; set; }
}
[MessagePackObject]
public class FailedPacket
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; }
[Key(1)][JsonPropertyName("code")] public int Code { get; set; }
[Key(2)][JsonPropertyName("reason")] public string Reason { get; set; } = "";
}
[MessagePackObject]
public class SyncPacket
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; }
[Key(1)][JsonPropertyName("entityType")] public string EntityType { get; set; } = "";
[Key(2)][JsonPropertyName("data")] public Dictionary<string, object?> Data { get; set; } = new();
}
[MessagePackObject]
public class LeaveGamePacket
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; }
[Key(1)][JsonPropertyName("clientId")] public string ClientId { get; set; } = "";
}
// Combat (when using AltruistCombatPortal)
[MessagePackObject]
public class DamagePacket
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; }
[Key(1)][JsonPropertyName("vid")] public uint VID { get; set; }
[Key(2)][JsonPropertyName("flags")] public byte Flags { get; set; }
[Key(3)][JsonPropertyName("damage")] public int Damage { get; set; }
}
[MessagePackObject]
public class DeathPacket
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; }
[Key(1)][JsonPropertyName("vid")] public uint VID { get; set; }
}
[MessagePackObject]
public class TargetPacket
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; }
[Key(1)][JsonPropertyName("vid")] public uint VID { get; set; }
[Key(2)][JsonPropertyName("hpPercent")] public byte HPPercent { get; set; }
}
// ── Client → Server ───────────────────────────────
[MessagePackObject]
public class HandshakeRequest
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; } = PacketCodes.HandshakeRequest;
[Key(1)][JsonPropertyName("token")] public string Token { get; set; } = "";
}
[MessagePackObject]
public class JoinGameRequest
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; } = PacketCodes.JoinGame;
[Key(1)][JsonPropertyName("name")] public string Name { get; set; } = "";
[Key(2)][JsonPropertyName("roomId")] public string? RoomId { get; set; }
[Key(3)][JsonPropertyName("world")] public int? WorldIndex { get; set; } = 0;
[Key(4)][JsonPropertyName("position")] public float[]? Position { get; set; } = new[] { 0f, 0f };
}
[MessagePackObject]
public class EventPacket
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; } = PacketCodes.Altruist;
[Key(1)][JsonPropertyName("event")] public string Event { get; set; } = "";
}
// Combat (when using AltruistCombatPortal)
[MessagePackObject]
public class AttackPacket
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; } = PacketCodes.Altruist;
[Key(1)][JsonPropertyName("type")] public byte Type { get; set; }
[Key(2)][JsonPropertyName("targetVID")] public uint TargetVID { get; set; }
}
[MessagePackObject]
public class TargetRequestPacket
{
[Key(0)][JsonPropertyName("messageCode")] public uint MessageCode { get; set; } = PacketCodes.Altruist;
[Key(1)][JsonPropertyName("vid")] public uint VID { get; set; }
}
// Auth (HTTP JSON responses)
public class LoginResponse
{
[JsonPropertyName("accessToken")] public string AccessToken { get; set; } = "";
[JsonPropertyName("refreshToken")] public string RefreshToken { get; set; } = "";
}
public class UpgradeResponse
{
[JsonPropertyName("accessToken")] public string AccessToken { get; set; } = "";
[JsonPropertyName("refreshToken")] public string RefreshToken { get; set; } = "";
[JsonPropertyName("accessExpiration")] public DateTime AccessExpiration { get; set; }
[JsonPropertyName("refreshExpiration")] public DateTime RefreshExpiration { get; set; }
}
}
Message Code Reference
| Code | Name | Direction | Description |
|---|---|---|---|
| 1 | Text | Both | Simple text message |
| 3 | Sync | Server → Client | Entity property sync ([Synced] fields) |
| 4 | Altruist | Client → Server | Event routing — event field maps to [Gate] |
| 5 | Success | Server → Client | Operation succeeded |
| 6 | Failed | Server → Client | Operation failed — reason explains why |
| 7 | HandshakeRequest | Client → Server | Send immediately after connecting |
| 8 | HandshakeResponse | Server → Client | Your client ID + available rooms |
| 9 | JoinGame | Client → Server | Join a game room |
| 10 | LeaveGame | Both | Player left (client sends or server broadcasts) |
| 1000+ | Your packets | Both | Custom game packets |
Automatic Server Behavior
These systems work without any specific packets — the client doesn't need to handle them:
| System | What Happens | Client Impact |
|---|---|---|
| Visibility | Entities spawn/despawn based on view range | Your collision handlers decide what packets to send |
| Hibernation | Entities with zero observers are suspended | Transparent |
| Autosave | Dirty entities batched to database | Transparent |
| Zone tracking | Entity zone transitions detected | Your collision handlers decide what to send |
Note:
Framework packets use codes 0–13. Use 1000+ for your game packets to avoid conflicts.