Skip to content

API リファレンス

@uzupj/uzu-sdk パッケージの公開 API 一覧です。

パッケージ情報

項目
パッケージ名@uzupj/uzu-sdk
モジュール形式ES Modules
依存関係なし (devDependencies: typescript ^5.7.0 のみ)

関数

init(): void

SDK を初期化し、Flutter ホスト / 親ウィンドウに準備完了を通知する。

typescript
import { init } from '@uzupj/uzu-sdk';

init();

動作:

  1. Flutter WebView / iframe 環境に応じてメッセージ受信口を登録
  2. URL に ?roomId=xxx があれば Relay WebSocket に自動接続

TIP

run() / sync() を使う場合は内部で init() を呼ぶため、直接呼ぶ必要はありません。 Relay ベース (onRoom()) のゲームでのみ、最初に呼び出してください。

run<S>(config: GameConfig<S>): void

Host-authoritative ゲームループを実行する。

typescript
import { run } from '@uzupj/uzu-sdk';

run({
  logic,
  onState(state, myPlayerId) {
    currentState = state;
    myId = myPlayerId;
  },
  inputs(sendAction) {
    canvas.addEventListener('click', () => {
      sendAction('choose', { hand: 'rock' });
    });
  },
  events: {
    sound(data) {
      new Audio(`/sounds/${data.sound}.mp3`).play().catch(() => {});
    },
  },
  playerCount: 2,
});

モードの自動判定:

  • URL に ?roomId=xxx がない → ローカルモード (サーバー不要)
  • URL に ?roomId=xxx&server=xxx がある → オンラインモード
  • URL に ?__dev=N がある → Dev ハーネスモード

sync<S>(config: SyncConfig<S>): void

Server-authoritative な JSON Patch ベースの状態同期を開始する。

typescript
import { sync, SERVER_TIME } from '@uzupj/uzu-sdk';
import type { Player } from '@uzupj/uzu-sdk';

sync<GameState>({
  playerCount: 2,
  initialState(players: Player[]) {
    return { board: createBoard(8), currentPlayer: players[0].id };
  },
  onState(state, myPlayerId, serverTime) {
    currentState = state;
    render();
  },
  inputs(patch, set) {
    canvas.addEventListener('click', (e) => {
      const { row, col } = getCellFromClick(e);
      patch([
        { op: 'replace', path: `/board/${row}/${col}`, value: myPlayerId },
        { op: 'replace', path: '/lastMoveAt', value: SERVER_TIME },
      ]);
    });
  },
  connection: {
    onConnectionStateChange(state) {
      console.log('Connection:', state);
    },
    onPatchFailed(error) {
      console.error('Patch failed:', error);
    },
  },
});

send(message: PlayScreenMessage): void

Flutter ホスト / 親ウィンドウへ任意のメッセージを送信する。

typescript
import { send } from '@uzupj/uzu-sdk';

send({ type: 'playSound', sound: 'sounds/clear.mp3' });

on(type: string, handler: MessageHandler): void

Flutter / ホストからのメッセージに対するハンドラを登録する。同一 type に複数登録可能。

typescript
import { on } from '@uzupj/uzu-sdk';
import type { PlayersChangedMessage } from '@uzupj/uzu-sdk';

on('playersChanged', (msg) => {
  const { players } = msg as unknown as PlayersChangedMessage;
  for (const [id, state] of Object.entries(players)) {
    switch (state.audioStatus) {
      case 'speaking':
        highlightAvatar(id);
        break;
      case 'listening':
        showNormalAvatar(id);
        break;
      case 'muted':
        showMuteIcon(id);
        break;
      case 'unstable':
        showUnstableBadge(id);
        break;
      case null:
        showNoVoice(id);
        break;
    }
  }
});

playSound(sound: string): void

効果音の再生リクエストを送信する。

typescript
import { playSound } from '@uzupj/uzu-sdk';
playSound('sounds/clear.mp3');

playBgm(sound: string): void / stopBgm(): void

BGM の再生・停止を制御する。

typescript
import { playBgm, stopBgm } from '@uzupj/uzu-sdk';

playBgm('bgm/main.mp3'); // ループ再生
stopBgm();

setMicEnabled(enabled: boolean): void

マイクのオンオフを切り替える。

typescript
import { setMicEnabled } from '@uzupj/uzu-sdk';
setMicEnabled(false); // ミュート

changeRoom(roomId: string | null): void

ボイスチャットルームを移動する。null でデフォルト (全体) ルームに戻る。

typescript
import { changeRoom } from '@uzupj/uzu-sdk';
changeRoom('room_a');
changeRoom(null);

isHosted

boolean (読み取り専用)。Flutter WebView または iframe 内で動作しているかを示す。

型定義

Player

typescript
interface Player {
  id: string;
  nickname: string;
  iconUrl: string;
  characterId?: string;
}

GameConfig<S> (run 用)

キー必須説明
logicGameLogic<S>Yesゲームロジック定義
onState(state: S, myPlayerId: string) => voidYesstate 更新時のコールバック
inputs(sendAction) => voidYes入力ハンドラ登録
eventsRecord<string, (data) => void>Noゲームイベントハンドラ
playerCountnumberYesプレイヤー数

GameLogic<S>

キー必須説明
setup(players: Player[], random: SeededRandom) => SYes初期 state を生成
actionsRecord<string, ActionHandler<S> | ServerOnlyAction<S>>Yesアクションハンドラ
update(state: S, ctx: UpdateContext) => voidYes毎 tick 実行
tickRatenumberNo秒間 tick 数 (default: 10)

SyncConfig<S> (sync 用)

キー必須説明
initialState(players: Player[]) => SYes初期 state を生成
onState(state: S, myPlayerId: string, serverTime: number) => voidYesstate 更新時のコールバック
inputs(patch: PatchFn, set: SetFn) => voidYes入力ハンドラ
eventsRecord<string, (data) => void>Noゲームイベントハンドラ
connectionConnectionCallbacksNo接続状態・エラーコールバック
playerCountnumberYesプレイヤー数

Operation (JSON Patch)

typescript
interface Operation {
  op: 'replace' | 'add' | 'remove';
  path: string; // JSON Pointer パス
  value?: unknown; // SERVER_TIME sentinel 使用可
}

PlayerVoiceState

typescript
interface PlayerVoiceState {
  audioStatus: 'speaking' | 'listening' | 'muted' | 'unstable' | null;
}

SeededRandom

GameLogic.setup / update の引数で提供される決定論的乱数生成器。

メソッド説明
float()0.0〜1.0 の浮動小数点
int(max)0〜max-1 の整数
pick(array)配列からランダムに 1 つ選択
shuffle(array)配列をシャッフル (新しい配列を返す)

SERVER_TIME

サーバー時刻 sentinel 定数 ('__SERVER_TIME__')。Patch の value に指定すると、サーバー側で Date.now() に自動置換される。

typescript
import { SERVER_TIME } from '@uzupj/uzu-sdk';
set('/meta/phaseStartedAt', SERVER_TIME);

Room API (Relay 用)

onRoom() コールバックで受け取る Room インスタンスのメソッド。

room.myId

string (readonly)。自分の playerId。

room.broadcast(msg)

自分以外の全メンバーにメッセージを送信。

typescript
room.broadcast({ type: 'attack', lines: 2 });

room.send(id, msg)

特定のプレイヤーにメッセージを送信。

room.on(type, handler)

メッセージタイプに対するハンドラを登録。受信データには __from (送信者 playerId) が含まれる。

typescript
room.on('attack', (msg) => {
  console.log(`${msg.__from} sent ${msg.lines} lines`);
});

URL パラメータ

パラメータ説明
?server=WebSocket サーバーの URL
?roomId=ルーム ID。指定するとオンラインモード
?playerId=プレイヤー ID
?players=JSON エンコードされたプレイヤーリスト
?__dev=NDev ハーネスモード (N 画面)