import { z } from 'zod';
import type { Appearance } from '../core/contract.js';
export declare const animationIds: readonly ["idle", "walk", "run", "jump", "fall", "land", "wave", "dance"];
export type AnimationId = (typeof animationIds)[number];
export declare const intentSchema: z.ZodObject<{
    type: z.ZodLiteral<"input">;
    seq: z.ZodNumber;
    x: z.ZodNumber;
    z: z.ZodNumber;
    facing: z.ZodNumber;
    jump: z.ZodBoolean;
    run: z.ZodBoolean;
}, z.core.$strict>;
export declare const clientMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
    type: z.ZodLiteral<"input">;
    seq: z.ZodNumber;
    x: z.ZodNumber;
    z: z.ZodNumber;
    facing: z.ZodNumber;
    jump: z.ZodBoolean;
    run: z.ZodBoolean;
}, z.core.$strict>, z.ZodObject<{
    type: z.ZodLiteral<"emote">;
    seq: z.ZodNumber;
    id: z.ZodEnum<{
        wave: "wave";
        dance: "dance";
    }>;
}, z.core.$strict>, z.ZodObject<{
    type: z.ZodLiteral<"interact">;
    seq: z.ZodNumber;
    id: z.ZodEnum<{
        "race-ready": "race-ready";
        "showroom-switch": "showroom-switch";
        respawn: "respawn";
        "race-reset": "race-reset";
    }>;
}, z.core.$strict>, z.ZodObject<{
    type: z.ZodLiteral<"diagnostic">;
    seq: z.ZodNumber;
    stage: z.ZodEnum<{
        "scene-ready": "scene-ready";
        "room-joined": "room-joined";
    }>;
}, z.core.$strict>], "type">;
export type InputIntent = z.infer<typeof intentSchema>;
export type ClientMessage = z.infer<typeof clientMessageSchema>;
export type Motion = {
    x: number;
    y: number;
    z: number;
    vy: number;
    facing: number;
    grounded: boolean;
    locomotion: AnimationId;
};
export type Pose = Motion & {
    id: string;
    name: string;
    color: string;
    ack: number;
    revision: number;
    emote: {
        id: 'wave' | 'dance';
        startedAt: number;
        endsAt: number;
    } | null;
};
export type RaceState = {
    round: number;
    phase: 'lobby' | 'countdown' | 'running' | 'results' | 'reset';
    startedAt: number;
    phaseEndsAt: number;
    ready: string[];
    checkpoints: {
        x: number;
        y: number;
        z: number;
    }[];
    racers: Record<string, {
        checkpoint: number;
        finishedMs: number | null;
        dnf: boolean;
    }>;
};
export type GameState = {
    switchOn: boolean;
    race: RaceState;
};
export type RoomSnapshot = {
    type: 'snapshot';
    tick: number;
    time: number;
    actors: Pose[];
    game: GameState;
};
export type RoomMessage = RoomSnapshot | {
    type: 'welcome';
    actorId: string;
    generation: number;
    time: number;
    expiresAt: number;
    appearances: Record<string, Appearance>;
    snapshot: RoomSnapshot;
} | {
    type: 'appearance';
    actorId: string;
    appearance: Appearance;
} | {
    type: 'error';
    code: string;
    message: string;
} | {
    type: 'central';
    available: boolean;
};
export type ConnectionState = 'handshaking' | 'appearance-loading' | 'asset-loading' | 'connecting' | 'ready' | 'reconnecting' | 'offline' | 'expired';
export declare const neutralInput: () => InputIntent;
