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

CodeNameDirectionDescription
1TextBothSimple text message
3SyncServer → ClientEntity property sync ([Synced] fields)
4AltruistClient → ServerEvent routing — event field maps to [Gate]
5SuccessServer → ClientOperation succeeded
6FailedServer → ClientOperation failed — reason explains why
7HandshakeRequestClient → ServerSend immediately after connecting
8HandshakeResponseServer → ClientYour client ID + available rooms
9JoinGameClient → ServerJoin a game room
10LeaveGameBothPlayer left (client sends or server broadcasts)
1000+Your packetsBothCustom game packets

Automatic Server Behavior

These systems work without any specific packets — the client doesn't need to handle them:

SystemWhat HappensClient Impact
VisibilityEntities spawn/despawn based on view rangeYour collision handlers decide what packets to send
HibernationEntities with zero observers are suspendedTransparent
AutosaveDirty entities batched to databaseTransparent
Zone trackingEntity zone transitions detectedYour collision handlers decide what to send

Note:

Framework packets use codes 0–13. Use 1000+ for your game packets to avoid conflicts.