Files
2026-07-22 00:34:09 -05:00

73 lines
2.1 KiB
TypeScript

// ---------------------------------------------------------------------------
// Network protocol shared between server and client (JSON over WebSocket)
// ---------------------------------------------------------------------------
export interface PelletData {
id: number;
x: number;
y: number;
v: number; // food value (also drives render size)
c: number; // color index into PELLET_COLORS
}
export interface SnakeSnap {
id: number;
n: string; // nickname
c: number; // color index into SNAKE_COLORS
s: number; // score
p: number[]; // flat body points [x0,y0,x1,y1,...], head first
b: boolean; // boosting
k: number; // kills
sp?: boolean; // spawn protection active (ghost)
}
export type GameEvent =
| { t: 'die'; id: number; x: number; y: number; c: number; s: number; p: number[] }
| { t: 'join'; id: number; n: string }
| { t: 'leave'; id: number };
export interface LeaderboardRow {
id: number;
n: string;
s: number;
}
export interface YouState {
score: number;
rank: number;
alive: boolean;
kills: number;
best: number;
}
// --- server -> client -------------------------------------------------------
export interface InitMsg {
t: 'init';
id: number; // your snake id
arena: number; // arena radius
pellets: PelletData[]; // full pellet list (deltas arrive afterwards)
}
export interface SnapMsg {
t: 'snap';
tick: number;
snakes: SnakeSnap[];
add: PelletData[]; // pellets added since last snapshot
rem: number[]; // pellet ids removed since last snapshot
ev: GameEvent[]; // events since last snapshot
lb: LeaderboardRow[];
you?: YouState;
total: number; // total snakes alive
}
export type ServerMsg = InitMsg | SnapMsg;
// --- client -> server -------------------------------------------------------
export interface JoinMsg { t: 'join'; name: string }
export interface InputMsg { t: 'in'; a: number; b: boolean } // angle, boosting
export interface RespawnMsg { t: 'respawn' }
export type ClientMsg = JoinMsg | InputMsg | RespawnMsg;