/**
 * Мультиплеер: игроки комнаты, общее состояние комнаты, команды,
 * адресные сообщения.
 */
declare namespace game {
    interface PlayerInfo {
        id: number | string;
        name: string;
        position: game.Vector3;
        hp: number;
        team: string | null;
    }

    interface PlayersApi {
        /** Я — текущий игрок в комнате. */
        me(): PlayerInfo | null;

        /** Список всех игроков комнаты. */
        all(): PlayerInfo[];

        /** Кол-во игроков в комнате. */
        count(): number;

        /** Получить игрока по id. */
        get(id: number | string): PlayerInfo | null;
    }
    const players: PlayersApi;

    /**
     * Игрок зашёл в комнату.
     * @example
     * game.onPlayerJoin((player) => game.ui.showText(`+ ${player.name}`, 2));
     */
    function onPlayerJoin(fn: (player: PlayerInfo) => void): void;

    /** Игрок вышел. */
    function onPlayerLeave(fn: (player: PlayerInfo) => void): void;

    /** Игрок умер. */
    function onPlayerDied(fn: (event: { source?: string }) => void): void;

    /** Игрок прыгнул. */
    function onPlayerJump(fn: () => void): void;

    /** Игрок приземлился. */
    function onPlayerLand(fn: () => void): void;

    /**
     * Адресное сообщение конкретному игроку (только в мультиплеере).
     * @example
     * game.sendTo(targetPlayer, 'invite', { gameId: 123 });
     */
    function sendTo(player: PlayerInfo | number | string, name: string, data?: any): void;

    /** Подписка на адресное сообщение. */
    function onMessage(name: string, fn: (data: any, from?: PlayerInfo) => void): void;

    /**
     * Состояние комнаты — синхронизировано между всеми клиентами.
     */
    interface RoomApi {
        set(key: string, value: any): void;
        get(key: string): any;
        onChange(key: string, fn: (newValue: any, oldValue: any) => void): void;
    }
    const room: RoomApi;

    /**
     * Команды (Teams) — командные спавны и лидерборды.
     */
    interface TeamsApi {
        create(name: string, color: game.Color): void;
        remove(name: string): void;
        all(): Array<{ name: string; color: game.Color; players: PlayerInfo[] }>;
        get(name: string): { name: string; color: game.Color; players: PlayerInfo[] } | null;
    }
    const teams: TeamsApi;

    /**
     * Phase 6.6: RemoteEvent -- именованное сетевое событие (как в Roblox).
     */
    interface RemoteEvent {
        readonly name: string;
        /** Отправить событие ВСЕМ клиентам комнаты (включая отправителя). */
        fireAllClients(data?: any): void;
        /** Отправить событие всем КРОМЕ отправителя. */
        fireOthers(data?: any): void;
        /** Отправить событие конкретному игроку (по sessionId или PlayerInfo). */
        fireClient(player: PlayerInfo | string, data?: any): void;
        /**
         * Подписаться на событие от любого клиента.
         * @param fn получает { from: sessionId, data }
         */
        on(fn: (event: { from: string; data: any }) => void): void;
    }

    interface RemoteApi {
        /**
         * Создать (или получить) именованное сетевое событие.
         * @example
         * const ev = game.remote.create('PlayerShoot');
         * ev.on(({ from, data }) => game.log(from, 'shot at', data));
         * ev.fireAllClients({ x: 10, z: 5 });
         */
        create(name: string): RemoteEvent;
    }
    const remote: RemoteApi;
}
