この仕様は、AiProcessManagerとAIプロセス間の標準入出力を使用したJSON形式の通信プロトコルを定義します。このプロトコルにより、独立したプロセスとして実行されるAIコードと、ゲームエンジン間での安全な情報交換を実現します。
- 標準入力: AiProcessManager → AIプロセス(JSON形式)
- 標準出力: AIプロセス → AiProcessManager(JSON形式)
- エンコーディング: UTF-8
- 区切り文字: 各JSONメッセージは改行文字(
\n)で区切る
全てのメッセージは以下の基本構造を持ちます:
{
"type": "message_type",
"timestamp": "2025-09-24T01:30:00Z",
"data": { /* message-specific data */ }
}AIプロセス起動時に送信される初期化情報:
{
"type": "initialize",
"timestamp": "2025-09-24T01:30:00Z",
"data": {
"game_id": "123",
"round_number": 1,
"player_index": 0,
"player_ai_id": "456",
"rand_seed": 12345,
"game_map": {
"width": 15,
"height": 15,
"map_data": [
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0]
],
"goal_position": { "x": 14, "y": 14 }
},
"initial_position": { "x": 0, "y": 0 },
"initial_items": {
"dynamite_left": 2,
"bomb_left": 2
},
"game_constants": {
"max_turns": 50,
"turn_timeout": 5
}
}
}各ターン開始時に送信される現在のゲーム状態:
{
"type": "turn_start",
"timestamp": "2025-09-24T01:30:01Z",
"data": {
"turn_number": 1,
"current_player": {
"id": "789",
"position": { "x": 0, "y": 0 },
"previous_position": { "x": 0, "y": 0 },
"score": 0,
"character_level": 1,
"dynamite_left": 2,
"bomb_left": 2,
"walk_bonus_counter": 0,
"acquired_positive_items": [0, 0, 0, 0, 0, 0],
"status": "playing"
},
"other_players": [
{
"id": "790",
"position": { "x": 14, "y": 0 },
"status": "playing",
"character_level": 1
}
],
"enemies": [
{
"id": "801",
"position": { "x": 7, "y": 7 },
"previous_position": { "x": 7, "y": 6 },
"state": "normal_state",
"enemy_kill": "no_kill",
"killed": false
}
],
"visible_map": {
"width": 15,
"height": 15,
"map_data": [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, "a", 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "A", 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]
]
}
}
}AIプロセスからturn_overアクションを受信した後の確認:
{
"type": "turn_end_confirm",
"timestamp": "2025-09-24T01:30:05Z",
"data": {
"turn_number": 1,
"actions_processed": 2,
"next_turn_will_start": true
}
}ゲーム/ラウンド終了時に送信:
{
"type": "game_end",
"timestamp": "2025-09-24T01:35:00Z",
"data": {
"reason": "goal_reached",
"final_score": 150,
"final_position": { "x": 14, "y": 14 },
"round_winner": "player_1",
"total_turns": 23
}
}AIプロセス起動時に送信する準備完了通知:
{
"type": "ready",
"timestamp": "2025-09-24T01:30:00Z",
"data": {
"player_name": "timeout_player",
"ai_version": "1.0.0",
"status": "initialized"
}
}ターンの終了と実行するアクションを通知(最大2つのアクション):
{
"type": "turn_over",
"timestamp": "2025-09-24T01:30:05Z",
"data": {
"actions": [
{
"action_type": "move",
"direction": "right"
},
{
"action_type": "explore",
"target_position": { "x": 5, "y": 5 },
"area_size": 5
}
]
}
}{
"action_type": "move",
"direction": "up"
}{
"action_type": "move",
"target_x": 1,
"target_y": 2
}{
"action_type": "use_item",
"item": "dynamite",
"position": { "x": 2, "y": 3 }
}{
"action_type": "explore",
"target_position": { "x": 5, "y": 5 },
"area_size": 5
}デバッグ情報の出力:
{
"type": "debug",
"timestamp": "2025-09-24T01:30:02Z",
"data": {
"level": "info",
"message": "同じ場所を探索中: 0:0",
"context": {
"current_action": "explore",
"turn_number": 1
}
}
}実行時エラーの報告:
{
"type": "error",
"timestamp": "2025-09-24T01:30:03Z",
"data": {
"error_type": "invalid_move",
"message": "指定された座標(15, 15)はマップ範囲外です",
"details": {
"attempted_position": { "x": 15, "y": 15 },
"map_bounds": { "width": 15, "height": 15 }
}
}
}AiProcessManager → AIプロセス: initialize メッセージ
AIプロセス → AiProcessManager: ready メッセージ
ゲームループ(最大50ターン):
AiProcessManager → AIプロセス: turn_start メッセージ
AIプロセス処理:
AIプロセス → AiProcessManager: debug メッセージ (任意)
AIプロセス → AiProcessManager: turn_over メッセージ (最大2つのアクションを含む)
AiProcessManager → AIプロセス: turn_end_confirm メッセージ
AiProcessManager → AIプロセス: game_end メッセージ
AIプロセス終了
AIプロセスが5秒間出力を行わない場合:
- AiEngineがプロセスを強制終了
- プレイヤーのステータスを
timeoutに変更 - ゲームから除外
不正なJSON形式を受信した場合:
- エラーログを記録
- そのメッセージを無視
- 処理を継続
実行不可能なアクションを受信した場合:
- 無効なアクションを無視
- そのターンは何も実行しない
- エラーログを記録
{ "x": integer, "y": integer }"move": 移動"use_item": アイテム使用"explore": 探索
"dynamite": ダイナマイト"bomb": 爆弾
"up": 上"down": 下"left": 左"right": 右
"playing": プレイ中"completed": ゴール到達または敵に倒された"timeout": AIタイムアウト"timeup": 制限時間切れ
"normal_state": 通常状態"angry": 怒りモード"kill": やられるぞモード"done": 撃退済み
AiProcessManager → AIプロセス:
{
"type": "initialize",
"data": { /* 初期化データ */ }
}
AIプロセス → AiProcessManager:
{
"type": "ready",
"data": { "player_name": "timeout_player" }
}
AiProcessManager → AIプロセス:
{
"type": "turn_start",
"data": { "turn_number": 1, /* ゲーム状態 */ }
}
// AIプロセスは何も出力しない(タイムアウト)
5秒後:
AiProcessManagerがプロセス強制終了
// ターン1(右に移動)
AiProcessManager → AIプロセス: turn_start (turn_number: 1)
AIプロセス → AiProcessManager:
{
"type": "turn_over",
"data": {
"actions": [
{ "action_type": "move", "direction": "right" }
]
}
}
// ターン2(左に移動)
AiProcessManager → AIプロセス: turn_start (turn_number: 2)
AIプロセス → AiProcessManager:
{
"type": "turn_over",
"data": {
"actions": [
{ "action_type": "move", "direction": "left" }
]
}
}
- JSON形式の妥当性チェック
- データタイプの検証
- 範囲チェック(座標、値の上限下限)
- メッセージサイズ制限(最大1MB)
- 1ターンあたりのメッセージ数制限(最大100メッセージ)
- メモリ使用量監視
- 独立したプロセス空間での実行
- ファイルシステムアクセス制限
- ネットワークアクセス制限
このプロトコルは以下の拡張に対応できるよう設計されています:
- 新しいアクションタイプ:
action_typeフィールドに新しい値を追加 - 追加のゲーム状態:
turn_startメッセージのdataフィールドに新しい情報を追加 - カスタムメッセージタイプ: 新しい
type値の定義 - バージョニング: メッセージにプロトコルバージョンフィールドを追加可能
- JSON生成・パース機能
- プロセス管理(起動・停止・監視)
- タイムアウト管理
- エラーハンドリング
- 標準入力からのJSON読み取り
- 標準出力へのJSON書き込み
- Koshien APIメソッドのプロトコル変換
- 適切なエラーレポート
この仕様により、安全で拡張可能、かつデバッグしやすいAI実行環境を実現します。