Game Plugin SDK
Назначение
Единый контракт для добавления игр из шоу без изменения session/realtime слоя.
Интерфейс плагина
from abc import ABC, abstractmethod
from typing import Any
from pydantic import BaseModel
class ValidationResult(BaseModel):
ok: bool
error_code: str | None = None
message: str | None = None
class WebViewModel(BaseModel):
board: list[list[Any]]
highlights: list[tuple[int, int]]
dice: tuple[int, int] | None
phase: str
current_player_name: str
actions_available: list[str]
class TelegramViewModel(BaseModel):
caption: str
image_url: str | None
buttons: list[list[dict]] # inline keyboard rows
class GamePlugin(ABC):
plugin_id: str
display_name: str
min_players: int
max_players: int
version: str
@abstractmethod
def initial_state(self, player_ids: list[str], config: dict) -> dict: ...
@abstractmethod
def validate_action(
self, state: dict, action_type: str, payload: dict, player_id: str
) -> ValidationResult: ...
@abstractmethod
def apply_action(
self, state: dict, action_type: str, payload: dict, player_id: str
) -> dict: ...
@abstractmethod
def get_current_player(self, state: dict) -> str | None: ...
@abstractmethod
def is_finished(self, state: dict) -> bool: ...
@abstractmethod
def get_winner(self, state: dict) -> str | None: ...
@abstractmethod
def render_web(self, state: dict) -> WebViewModel: ...
@abstractmethod
def render_telegram(self, state: dict) -> TelegramViewModel: ...
def allowed_actions(self, state: dict, player_id: str) -> list[str]:
"""Опционально: список action_type для UI."""
return []
Регистрация плагина
# plugins/registry.py
PLUGINS: dict[str, GamePlugin] = {
"dice_board": DiceBoardPlugin(),
}
Фазы игры (общий паттерн)
| Phase |
Описание |
setup |
Расстановка, выбор параметров |
playing |
Основной цикл |
finished |
Победитель определён |
Action contract
| Поле |
Тип |
Обязательно |
action_id |
UUID |
да |
action_type |
string |
да |
payload |
object |
зависит от типа |
player_id |
UUID |
из auth context |
dice_board actions
| action_type |
payload |
phase |
roll_dice |
{} |
RollDice |
choose_cell |
{row, col} |
AwaitCellChoice |
pass |
{} |
TBD edge cases |
Тестирование плагина
- Unit —
validate_action, apply_action, is_finished
- Property — инварианты поля после каждого хода
- Gherkin — acceptance через game-runtime API
Tutorial: добавить новую игру
- Создать
plugins/my_game/plugin.py implements GamePlugin
- Добавить в
PLUGINS registry
- Описать
game-spec.md в docs/05-games/my-game/
- Добавить Gherkin в
acceptance-tests.md
- UI assets для media-service renderer
- Зарегистрировать в
catalog-roadmap.md
Связанные документы