Translate all project documentation into English

This commit is contained in:
Emil
2026-09-12 23:43:10 +03:00
parent 6682668c16
commit 54af124a6d
8 changed files with 477 additions and 475 deletions
+40 -38
View File
@@ -1,56 +1,58 @@
# minecraft-builder-mcp
Строительный редактор Minecraft для совместной работы человека и ИИ-агента.
A Minecraft building editor for collaboration between a human and an AI agent.
Рабочий прототип: Paper-плагин, ядро редактирования, MCP/ACP Bridge и Fabric-мод камеры. Строительство, конфликты, undo, аварийное восстановление и `.schem` проверены на локальном Paper через HTTP и настоящий MCP stdio. Камера проверена в Prism с одним клиентом: настоящий PNG 1280×720 передан через MCP. Вход в отдельный профиль Codex и первый ход модели через ACP ещё предстоит проверить.
Working prototype: a Paper plugin, an editing core, an MCP/ACP Bridge, and a Fabric camera mod. Building, conflicts, undo, crash recovery, and `.schem` have been tested against local Paper through HTTP and real MCP stdio. The camera has been tested in Prism with one client: a real 1280×720 PNG was delivered through MCP. Signing in to the separate Codex profile and completing the first model turn through ACP still need verification.
## Что умеет
## Features
- Читает ограниченные участки и строит коробки, линии, цилиндры и повторяющиеся элементы.
- Сначала сохраняет план, затем применяет его порциями с проверкой текущих блоков. Ручное изменение останавливает конфликтующую запись; отмена тоже проверяет состояние мира.
- Хранит журнал на диске, различает повтор запроса и новую операцию, останавливает неоднозначные операции после сбоя.
- Сохраняет именованные части и их защиту, экспортирует и импортирует ограниченный Sponge v2 `.schem` через тот же механизм планов.
- Даёт 14 MCP-инструментов и `/ai` для игрового чата через закреплённый `codex-acp`.
- Снимает настоящие изображения через локальный Worker на spectator-клиенте. Проверен также один клиент с временным переключением владельца в spectator.
- Reads bounded regions and builds boxes, lines, cylinders, and repeated elements.
- Saves a plan before applying it in slices with live block checks. Manual changes stop conflicting writes; undo also checks the current world state.
- Keeps an on-disk journal, distinguishes request retries from new operations, and stops ambiguous operations after a crash.
- Saves named parts and their protection, and exports/imports a limited Sponge v2 `.schem` subset through the same planning engine.
- Provides 14 MCP tools and `/ai` game chat through a pinned `codex-acp` adapter.
- Captures real images through a local worker on a spectator client. A single client with the owner temporarily in spectator has also been tested.
Сейчас это один владелец, один проект и один мир, до 4096 блоков на план, только загруженные чанки и ограниченный набор ванильных материалов. Полный журнал дельт, автоматическое объединение ручных правок и все возможности дизайн-документа ещё не реализованы. [Подробный статус и ограничения](docs/IMPLEMENTATION.md).
The current scope is one owner, one project, and one world, with at most 4096 blocks per plan, loaded chunks only, and a limited vanilla material palette. A complete delta history, automatic merging of manual edits, and the full design document are not implemented yet. [Detailed status and limitations](docs/IMPLEMENTATION.md).
## Сборка
The building palette contains 71 materials. Decorative additions include lanterns, `iron_chain` (the Minecraft 26.2 ID), iron bars, stone brick walls, persistent oak leaves, moss, gray/brown stained glass, glowstone, and gold blocks. Leaves require `persistent=true`; waterlogged states remain unsupported. The strict `.schem` codec currently retains the original 61-material subset.
Проверенная среда — Linux x64, Minecraft/Paper 26.2, Java 25, Node.js 22.22.3+. Из корня репозитория:
## Build
Verified environment: Linux x64, Minecraft/Paper 26.2, Java 25, and Node.js 22.22.3+. From the repository root:
```bash
./scripts/build.sh
```
Скрипт загружает закреплённые JDK 25.0.2 и Maven 3.9.11 в пользовательский кэш с проверкой хешей, устанавливает зависимости Bridge по lockfile и собирает все три компонента с тестами. Системная Java не меняется. Нужны уже установленные Python 3, Node.js и npm. [Закреплённые версии](docs/compatibility.json).
The script downloads pinned JDK 25.0.2 and Maven 3.9.11 into the user cache with hash verification, installs Bridge dependencies from the lockfile, and builds all three components with tests. It does not replace system Java. Python 3, Node.js, and npm must already be installed. [Pinned versions](docs/compatibility.json).
Результаты:
Build outputs:
- `paper-plugin/target/paper-plugin-0.1.0-SNAPSHOT.jar` — серверный плагин, ядро включено.
- `camera-mod/build/libs/minecraft-builder-camera-0.1.0-SNAPSHOT.jar` — клиентский мод.
- `bridge/dist/` — исполняемые MCP/ACP-компоненты.
- `paper-plugin/target/paper-plugin-0.1.0-SNAPSHOT.jar` — server plugin, including the editing core.
- `camera-mod/build/libs/minecraft-builder-camera-0.1.0-SNAPSHOT.jar` — client mod.
- `bridge/dist/` — executable MCP/ACP components.
## Локальный запуск
## Local setup
1. Подготовить отдельный тестовый Paper. На первой установке прочитать [Minecraft EULA](https://www.minecraft.net/eula), затем принять её явно:
1. Prepare a separate test Paper server. On first installation, read the [Minecraft EULA](https://www.minecraft.net/eula), then explicitly accept it:
```bash
python3 scripts/dev-server.py --accept-eula --run
```
Для последующих запусков достаточно `python3 scripts/dev-server.py --run`. Сервер хранится в `.runtime/server`, слушает `127.0.0.1:25575`, вход в Minecraft остаётся включён. Для уже подготовленного в этой рабочей папке сервера EULA принята пользователем.
For subsequent runs, use `python3 scripts/dev-server.py --run`. The server lives in `.runtime/server`, listens on `127.0.0.1:25575`, and keeps Minecraft authentication enabled. The user has accepted the EULA for the server already prepared in this workspace.
2. Подключиться клиентом Minecraft Java 26.2 к `127.0.0.1:25575`. В консоли **этого** сервера выдать своему игровому имени `op <имя>`. В игре выполнить:
2. Connect a Minecraft Java 26.2 client to `127.0.0.1:25575`. In **that server's** console, grant your game account operator access with `op <name>`. In the game, run:
```text
/ai setup
/ai area here
```
Вторая команда выбирает участок вокруг игрока. Чанки должны быть загружены, а рядом с местами записи — поддерживаемые блоки. Точные границы можно задать через `/ai area minX minY minZ maxX maxY maxZ`.
The second command selects an area around the player. Chunks must be loaded, and blocks next to writes must be supported. Set exact bounds with `/ai area minX minY minZ maxX maxY maxZ`.
3. В другом терминале из корня проекта проверить настройки и войти в отдельный профиль Codex:
3. From another terminal at the project root, check the settings and sign in to the separate Codex profile:
```bash
python3 scripts/bridge.py doctor
@@ -58,25 +60,25 @@
python3 scripts/bridge.py login --status
```
Вход выполняется самим пользователем по device code. Помощник читает локальные токены Paper без вывода в терминал. Обычный профиль `~/.codex` не копируется; состояние проекта хранится в `.runtime/bridge-state`. Первый настоящий ход ещё должен подтвердить авторизацию и разрешения MCP у закреплённого адаптера.
The user completes sign-in using a device code. The helper reads local Paper tokens without printing them. It does not copy the normal `~/.codex` profile; project state lives in `.runtime/bridge-state`. The first real turn still needs to confirm authentication and MCP permissions in the pinned adapter.
4. Запустить чат:
4. Start chat:
```bash
python3 scripts/bridge.py chat
```
Теперь можно отправить `/ai Построй небольшую башню рядом со мной`. Для выбора модели доступна переменная `MCB_MODEL`; без неё выбор остаётся за адаптером. `/ai status` показывает состояние, `/ai stop` останавливает дальнейшую запись и запрос к агенту. Уже сделанные изменения отменяются отдельным проверяемым undo.
You can now send `/ai Build a small tower next to me`. Set `MCB_MODEL` to choose a model; otherwise the adapter chooses. `/ai status` reports status, and `/ai stop` stops further writes and the agent request. Changes already made require a separate checked undo.
MCP можно подключить к внешнему клиенту командой `python3 scripts/bridge.py mcp`. Область владельца берётся из конфигурации Paper. Команда предназначена для запуска клиентом MCP по stdio, а не для интерактивного терминала.
Connect MCP to an external client using `python3 scripts/bridge.py mcp`. Owner scope comes from the Paper configuration. This command is intended for a client that launches MCP over stdio, rather than an interactive terminal.
## Камера
## Camera
Обычному игроку мод не нужен. Для наблюдателя установить Fabric Loader и API указанных версий, добавить JAR камеры в отдельный профиль 26.2. Перед запуском передать этому процессу `MCB_CAMERA_TOKEN` из поля `camera-token` приватной конфигурации плагина; в Paper заполнить `camera-player-uuid` и перезапустить сервер. Наблюдатель должен быть подключён к нему в spectator.
An ordinary player does not need the mod. For the observer, install the pinned Fabric Loader and API versions and add the camera JAR to a separate 26.2 profile. Before launching, pass `MCB_CAMERA_TOKEN` from the plugin's private `camera-token` setting to that process; set `camera-player-uuid` in Paper and restart the server. The observer must connect in spectator mode.
Если строитель и наблюдатель играют одновременно, нужны допустимые отдельные игровые сессии. Для одного клиента можно указать UUID владельца и временно включать spectator. Такой сценарий уже проверен в профиле Prism **26.2 MCP Building**; секрет передаётся Java через `scripts/camera-wrapper.py`, без добавления в логируемые переменные Prism. Точный порядок и ограничения снимка — в [инструкции камеры](camera-mod/README.md). После подключения `/ai camera save name` сохраняет ракурс владельца. [Результат локального теста с одним клиентом](docs/ONE_CLIENT_TEST.md).
If the builder and observer play simultaneously, they need valid separate game sessions. With one client, set the camera UUID to the owner's UUID and temporarily enable spectator mode. This scenario has been verified in the Prism profile **26.2 MCP Building**; `scripts/camera-wrapper.py` passes the secret to Java without adding it to Prism's logged variables. See the [camera instructions](camera-mod/README.md) for the exact procedure and capture limitations. Once connected, `/ai camera save name` saves the owner's viewpoint. [Local single-client test results](docs/ONE_CLIENT_TEST.md).
## Проверки и документы
## Tests and documentation
```bash
./mvnw test
@@ -84,12 +86,12 @@ npm --prefix bridge test
JAVA_HOME="$HOME/.cache/minecraft-builder-mcp/jdk-25.0.2" camera-mod/gradlew --project-dir camera-mod test
```
`python3 scripts/live-server-test.py` запускает и останавливает собственный процесс в `.runtime/server`, проверяет конфликты и undo, намеренно завершает этот процесс для проверки восстановления, затем прогоняет MCP и `.schem`. Для него сначала собрать проект, один раз запустить плагин и принять EULA; текущий сервер должен быть остановлен. Проверка предназначена для подготовленного тестового мира и изменяет только ограниченные тестовые области. Результаты сохраняются в `.runtime/live-server-results.json` и `.runtime/live-mcp-results.log`.
`python3 scripts/live-server-test.py` starts and stops its own process in `.runtime/server`, checks conflicts and undo, deliberately terminates that process to test recovery, and then exercises MCP and `.schem`. First build the project, run the plugin once, and accept the EULA; any existing server must be stopped. This test targets the prepared test world and changes only bounded test regions. Results are saved in `.runtime/live-server-results.json` and `.runtime/live-mcp-results.log`.
- [Дизайн проекта и дальнейшие этапы](docs/DESIGN.md).
- [Что реализовано и чем проверено](docs/IMPLEMENTATION.md).
- [Готический зал по референсу: 29 354 блока в живом мире](docs/builds/GOTHIC_HALL.md).
- [Протокол](docs/PROTOCOL.md), [ядро и журнал](world-core/README.md).
- [Bridge, вход и ограничения ACP](bridge/README.md).
- [Project design and future phases](docs/DESIGN.md).
- [Implementation status and verification](docs/IMPLEMENTATION.md).
- [Gothic hall from a reference: 29,354 blocks in the live world](docs/builds/GOTHIC_HALL.md).
- [Protocol](docs/PROTOCOL.md), [editing core and journal](world-core/README.md).
- [Bridge, sign-in, and ACP limitations](bridge/README.md).
Git инициализирован, ветка `main`. Сгенерированные миры, секреты, зависимости и сборки исключены через `.gitignore`.
Git is initialized on branch `main`. Generated worlds, secrets, dependencies, and build outputs are excluded by `.gitignore`.
+38 -38
View File
@@ -1,51 +1,51 @@
# Bridge
Локальные MCP-инструменты и игровой ACP-клиент для `minecraft-builder-mcp`.
Local MCP tools and an in-game ACP client for `minecraft-builder-mcp`.
Требуется Node.js 22.22.3+ и работающий Paper-плагин проекта. Установка воспроизводима по `package-lock.json`:
Requires Node.js 22.22.3+ and the project's running Paper plugin. Installation is reproducible from `package-lock.json`:
```bash
npm ci --ignore-scripts
npm test
```
Прямые зависимости закреплены: `codex-acp` 1.11.0, ACP SDK 1.4.0, MCP SDK 1.30.0, Zod 4.6.2, TypeScript 7.0.2. Закреплённая транзитивная версия Codex — 0.153.4. `npm ci` не выбирает свежие версии.
Direct dependencies are pinned: `codex-acp` 1.11.0, ACP SDK 1.4.0, MCP SDK 1.30.0, Zod 4.6.2, and TypeScript 7.0.2. The transitive Codex version is pinned to 0.153.4. `npm ci` does not select newer versions.
## Запуск
## Running
Секреты берутся из окружения, а не из аргументов командной строки. Плагин создаёт отдельные административный и агентский токены. Не коммитьте их. Пример конфигурации переменных — `.env.example`; сам bridge не загружает `.env` автоматически.
Secrets come from environment variables, not command-line arguments. The plugin creates separate administrator and agent tokens. Do not commit them. `.env.example` shows the environment configuration; the bridge does not automatically load `.env`.
- `npm run doctor` проверяет `/health` Paper при наличии `MCB_TOKEN`, создаёт отдельную минимальную конфигурацию Codex и выводит JSON с настройками, ограничениями и точной командой входа.
- `npm run login` вручную запускает вход через device code в отдельный Codex home; `npm run login -- status` проверяет этот вход.
- `npm run mcp` запускает MCP по stdio для внешнего агента. Нужны `MCB_AGENT_TOKEN`, `MCB_PLAYER_ID`, `MCB_PROJECT_ID`.
- `npm run chat` запускает опрос `/ai` и ACP. Нужны `MCB_TOKEN` и `MCB_AGENT_TOKEN`.
- `node dist/rpc.js project_context` — прямой диагностический RPC с агентской областью доступа.
- `npm run doctor` checks Paper's `/health` when `MCB_TOKEN` is present, creates a separate minimal Codex configuration, and prints JSON containing settings, limitations, and the exact sign-in command.
- `npm run login` explicitly starts device-code sign-in in a separate Codex home; `npm run login -- status` checks that sign-in.
- `npm run mcp` starts MCP over stdio for an external agent. Requires `MCB_AGENT_TOKEN`, `MCB_PLAYER_ID`, and `MCB_PROJECT_ID`.
- `npm run chat` starts `/ai` polling and ACP. Requires `MCB_TOKEN` and `MCB_AGENT_TOKEN`.
- `node dist/rpc.js project_context` makes a direct diagnostic RPC with agent scope.
Для локального сервера из этого репозитория удобнее запускать из корня `python3 scripts/bridge.py doctor`, `python3 scripts/bridge.py login`, `python3 scripts/bridge.py status` и затем `python3 scripts/bridge.py chat`. Обёртка использует общую папку `.runtime/bridge-state` и сама читает приватные токены Paper. `status` эквивалентен `login status` или `login --status`; эти команды только проверяют вход и не начинают авторизацию. `doctor`, `login` и `status` можно запускать ещё до создания конфигурации Paper. Не смешивайте вход через эту обёртку с обычным `npm run chat` без соответствующего `MCB_STATE_DIR`: у них разные папки состояния по умолчанию.
For this repository's local server, run `python3 scripts/bridge.py doctor`, `python3 scripts/bridge.py login`, `python3 scripts/bridge.py status`, and then `python3 scripts/bridge.py chat` from the repository root. The wrapper shares `.runtime/bridge-state` and reads Paper's private tokens itself. `status` is equivalent to `login status` or `login --status`; these commands only check sign-in and do not start authentication. `doctor`, `login`, and `status` can run before the Paper configuration exists. Do not mix sign-in through this wrapper with a plain `npm run chat` without the matching `MCB_STATE_DIR`: their default state directories differ.
`MCB_BACKEND_URL` по умолчанию `http://127.0.0.1:8765`. Разрешён только HTTP на loopback; для удалённого сервера нужен локальный SSH-туннель. UUID игрока/проекта поступают из доверенной конфигурации или ответа Paper, а сервер повторно проверяет владельца и область. В прототипе сервер поддерживает одного настроенного владельца.
`MCB_BACKEND_URL` defaults to `http://127.0.0.1:8765`. Only loopback HTTP is allowed; a remote server requires a local SSH tunnel. Player/project UUIDs come from trusted configuration or Paper's response, and the server rechecks ownership and scope. The prototype server supports one configured owner.
Игровой мост запускает установленный локальный `codex-acp`, без `npx @latest`. Он использует отдельный Codex home в `.state/chat/codex-home`; вход и настройки обычного `~/.codex` автоматически не копируются. Один раз запустите `npm run login` из той же рабочей директории и с тем же `MCB_STATE_DIR`, что и `chat`. Помощник использует закреплённый Codex CLI с `login --device-auth`; вход начинается только при явном запуске этой команды. Мост сам не открывает браузер и не обращается к модели во время сборки/обычных тестов. Для API-ключа задайте `MCB_OPENAI_API_KEY` или `MCB_CODEX_API_KEY` и `MCB_ACP_AUTH_METHOD=api-key`; общий `OPENAI_API_KEY` из родительского окружения не наследуется.
The game bridge launches the locally installed `codex-acp`, without `npx @latest`. It uses a separate Codex home at `.state/chat/codex-home`; sign-in and settings from the normal `~/.codex` are not copied automatically. Run `npm run login` once from the same working directory and with the same `MCB_STATE_DIR` used for `chat`. The helper uses the pinned Codex CLI with `login --device-auth`; authentication starts only when this command is explicitly invoked. The bridge does not open a browser itself or contact a model during builds or ordinary tests. For API-key authentication, set `MCB_OPENAI_API_KEY` or `MCB_CODEX_API_KEY` and `MCB_ACP_AUTH_METHOD=api-key`; the parent's generic `OPENAI_API_KEY` is not inherited.
Необязательные настройки:
Optional settings:
- `MCB_MODEL`: ID модели; применяется через объявленный ACP model selector. Без значения выбирает адаптер.
- `MCB_ACP_COMMAND`: путь к альтернативному ACP-агенту; без него используется текущий Node и закреплённый `codex-acp`.
- `MCB_ACP_ARGS`: JSON-массив аргументов, без shell-интерпретации.
- `MCB_STATE_DIR`: папка состояния, по умолчанию `.state/chat` относительно рабочей директории.
- `MCB_CODEX_HOME`: явный путь к отдельному Codex home для входа. Если там существует отличающийся `config.toml`, мост откажется запускаться и сохранит файл; используйте отдельную пустую папку, а не обычный профиль Codex.
- `MCB_MODEL`: model ID, applied through the advertised ACP model selector. If unset, the adapter chooses.
- `MCB_ACP_COMMAND`: path to an alternative ACP agent. Otherwise, the current Node executable and pinned `codex-acp` are used.
- `MCB_ACP_ARGS`: JSON array of arguments, with no shell interpretation.
- `MCB_STATE_DIR`: state directory, defaulting to `.state/chat` relative to the working directory.
- `MCB_CODEX_HOME`: explicit path to a separate Codex home for sign-in. If a different `config.toml` already exists there, the bridge refuses to start and preserves that file; use a separate empty directory rather than the normal Codex profile.
Дочерний процесс получает только разрешённые переменные окружения, отдельные HOME/XDG/CODEX_HOME и минимальный конфиг. Настройки запрашивают `read-only`, `on-request`, проверку пользователем, запрет сети внутри командного sandbox и отключение shell, приложений, браузера, computer use, hooks, plugins и дополнительных агентов. Источники и параметры приведены в `src/security.ts`. Проверка закреплённого CLI подтвердила отключённый `shell_tool` и перечисленные интеграции; `unified_exec` этот CLI оставляет включённым даже при явном отключении, что отражено в doctor.
The child process receives only allowlisted environment variables, separate HOME/XDG/CODEX_HOME directories, and a minimal configuration. Settings request `read-only`, `on-request`, user review, no network inside the command sandbox, and disabled shell, apps, browser, computer use, hooks, plugins, and additional agents. Sources and settings are in `src/security.ts`. Inspection of the pinned CLI confirmed that `shell_tool` and the listed integrations were disabled; that CLI keeps `unified_exec` enabled even when explicitly disabled, which doctor reports.
Есть ограничение самого `codex-acp` 1.11.0: его режим `read-only` посылает на каждый ход sandbox `workspace-write` с выключенной сетью, а не буквальный read-only. Поэтому папка конкретной сессии и временные пути могут оставаться доступными для записи. Код не заявляет полной изоляции ОС, и ещё не проверен на настоящем ходе модели. Процессы Bridge/ACP/MCP также остаются доверенными локальными программами; права Paper проверяются отдельно сервером.
There is a limitation in `codex-acp` 1.11.0 itself: its `read-only` mode sends a `workspace-write` sandbox with networking disabled for every turn, rather than a literal read-only sandbox. As a result, the individual session directory and temporary paths may remain writable. The code does not claim complete OS isolation and has not yet been verified on a real model turn. Bridge/ACP/MCP processes also remain trusted local programs; Paper permissions are checked separately by the server.
Bridge отклоняет дополнительные запросы разрешений с сообщением в игре. Интерактивное подтверждение разрешений через Minecraft пока не реализовано. ACP capabilities для файлов и терминала не объявляются. Административный токен Paper не передаётся дочернему агенту; MCP получает отдельный ограниченный агентский токен. Конфигурацию нужно проверять через doctor после смены версий или при наличии системных политик Codex. Для динамически передаваемого Minecraft MCP override `default_tools_approval_mode` не устанавливается: закреплённый адаптер передаёт только command/args/env и заменяет соответствующую таблицу конфигурации. Поэтому поведение разрешений MCP остаётся проверкой первого настоящего хода после входа пользователя; сборка и initialize не подтверждают, что строительство через модель уже работает.
The Bridge denies additional permission requests and reports this in the game. Interactive permission approval through Minecraft is not implemented. It does not advertise ACP file or terminal capabilities. Paper's administrator token is not passed to the child agent; MCP receives a separate restricted agent token. Check configuration with doctor after version changes or when system-wide Codex policies are present. The dynamically supplied Minecraft MCP override does not set `default_tools_approval_mode`: the pinned adapter passes only command/args/env and replaces the corresponding configuration table. MCP permission behavior therefore remains a check for the first real turn after user sign-in; a successful build and initialize do not prove that model-driven building already works.
## MCP
Инструменты: `project_context`, `region_inspect`, `build_prepare`, `build_apply`, `operation_status`, `operation_cancel`, `operation_undo_prepare`, `part_get`, `part_define`, `camera_list`, `camera_capture`, `asset_list`, `schematic_export`, `schematic_import_prepare`.
Tools: `project_context`, `region_inspect`, `build_prepare`, `build_apply`, `operation_status`, `operation_cancel`, `operation_undo_prepare`, `part_get`, `part_define`, `camera_list`, `camera_capture`, `asset_list`, `schematic_export`, `schematic_import_prepare`.
Рецепт первой версии:
Version 1 recipe:
```json
{
@@ -59,30 +59,30 @@ Bridge отклоняет дополнительные запросы разре
}
```
Необязательный `part_id` в `build_prepare` ограничивает запись точной маской зарегистрированной части; расширение задаётся отдельной частью.
An optional `part_id` in `build_prepare` restricts writes to the exact mask of a registered part; extensions use a separate part.
Инструменты отсылают данные на Paper для финальной проверки и вычисления. Мост не хранит блоки и не пишет мир. MCP принимает один уровень `repeat`; глубоко вложенные повторения, произвольный код, арки и общие трансформации пока не объявлены. Поддерживаемые состояния блоков и лимиты берутся из `project_context`.
Tools send data to Paper for final validation and computation. The bridge does not store blocks or write to the world. MCP accepts one level of `repeat`; deeply nested repeats, arbitrary code, arches, and general transforms are not advertised yet. Supported block states and limits come from `project_context`.
`build_prepare` возвращает `plan_id` и `plan_hash`. Для `build_apply` нужно передать их вместе со стабильным `idempotency_key`. При таймауте запись могла уже начаться: сначала проверьте `operation_status` и используйте тот же ключ. Мост не повторяет запись автоматически.
`build_prepare` returns `plan_id` and `plan_hash`. Pass both to `build_apply` with a stable `idempotency_key`. After a timeout, writing may already have started: check `operation_status` first and reuse the same key. The bridge does not automatically retry writes.
Локальная библиотека `.schem` поддерживает до 64 файлов, Sponge v2, плотные области до 4096 блоков и повороты 0/90/180/270°. Файлы вручную помещаются в папку `schematics` внутри данных Paper-плагина. `asset_list` возвращает метаданные без выдуманных превью; `schematic_export` сохраняет регион и возвращает ID; `schematic_import_prepare` создаёт обычный проверяемый план, который затем применяется через `build_apply`. Пути, сущности, block entities и неподдерживаемые блоки не принимаются.
The local `.schem` library supports up to 64 files, Sponge v2, dense regions of at most 4096 blocks, and rotations of 0/90/180/270°. Place files manually in the `schematics` directory inside the Paper plugin's data directory. `asset_list` returns metadata without invented previews; `schematic_export` saves a region and returns its ID; `schematic_import_prepare` creates a normal checked plan that is then applied through `build_apply`. Paths, entities, block entities, and unsupported blocks are rejected. The strict codec currently supports the original 61-material subset; the ten newer decorative materials in the building palette are not yet supported by `.schem`.
`camera_capture` возвращает `pending` и `captureId`; запрос с `capture_id` читает результат. Только `completed` с настоящим изображением превращается в MCP `ImageContent`. Если камеры нет или снимок не готов, изображение не выдумывается. Обычный текстовый ответ ограничен 64 KiB; чтение слишком большой области завершается ошибкой с просьбой уменьшить область. HTTP ограничен по времени, входному объёму и размеру потокового ответа.
`camera_capture` returns `pending` and `captureId`; a request with `capture_id` reads the result. Only `completed` with a real image becomes MCP `ImageContent`. If the camera is absent or the capture is not ready, no image is fabricated. Ordinary text responses are limited to 64 KiB; reading an oversized region fails with a request to reduce its size. HTTP has time, input-size, and streaming response-size limits.
## Диалоги и остановка
## Conversations and cancellation
Один активный ход на проект, до восьми сообщений в очереди. Разные проекты могут обрабатываться независимо. Сессии и папки разделены по проекту и UUID игрока. Ответы отправляются только инициатору через `chat_reply`; общий игровой чат, мысли модели, tool-аргументы и stderr адаптера не транслируются.
One active turn per project, with up to eight queued messages. Different projects can run independently. Sessions and directories are separated by project and player UUID. Replies go only to the initiating player through `chat_reply`; public game chat, model reasoning, tool arguments, and adapter stderr are not broadcast.
Каждый запрос включает переданные сервером позицию игрока, направление взгляда и целевой блок, если они доступны. Вывод сообщений ограничен до четырёх сообщений в секунду для одного игрока.
Each request includes the player position, viewing direction, and targeted block supplied by the server, when available. Message output is limited to four messages per second per player.
ID ACP-сессии и последняя компактная сводка сохраняются атомарной заменой `session.json` с правами `0600`. После перезапуска мост пробует `session/load`; при отказе начинает новый диалог со сводкой и явно сообщает об этом. Повтор истории при загрузке не выводится в чат. Незавершённый предыдущий ход помечается отдельно; уже начатые операции необходимо сверить на Paper. Сводка хранит последнее задание и итог, она не заменяет `project_context`.
The ACP session ID and latest compact summary are persisted by atomically replacing `session.json` with permissions `0600`. After restarting, the bridge tries `session/load`; if that fails, it starts a new conversation with the summary and explicitly reports the fallback. Replayed history is not shown in chat. An unfinished previous turn is marked separately; operations already started must be checked on Paper. The summary stores the latest request and outcome and does not replace `project_context`.
`/ai stop` должен одновременно установить серверный флаг остановки записи и доставить мосту событие `type:"cancel"`. ACP отменяет генерацию; уже изменённые блоки остаются в журнале. Прерванный агент, не отвечающий на cancel пять секунд, завершается. При каждом запуске мост создаёт `client_id` и передаёт его в `chat_poll`. Смена ID позволяет Paper остановить активные записи и завершить оставшиеся арендованные запросы с уведомлением пользователя; такие задания автоматически не повторяются. Очередь входящих сообщений Paper пока хранится в памяти. После `/ai stop` сервер удерживает запись на паузе до нового задания владельца или `/ai resume`.
`/ai stop` must both set the server's write-stop flag and deliver a `type:"cancel"` event to the bridge. ACP cancels generation; blocks already changed remain in the journal. An interrupted agent that does not respond to cancellation within five seconds is terminated. On each launch, the bridge creates a `client_id` and passes it to `chat_poll`. A changed ID lets Paper stop active writes and finish outstanding leased requests while notifying the user; those requests are not replayed automatically. Paper's incoming message queue is currently in memory. After `/ai stop`, the server keeps writing paused until a new owner request or `/ai resume`.
## Проверки
## Verification
`npm test` выполняет HTTP-тесты и настоящий stdio MCP handshake, а также использует отдельный mock ACP-процесс для проверки сессий, резюме, скрытия истории, отказа разрешений и отмены. Проверки очередей подтверждают сериализацию внутри проекта и независимость других проектов. Реальный закреплённый `codex-acp` также прошёл бесплатный `initialize`: ACP v1, `loadSession: true`, методы входа `api-key` и `chat-gpt` до ограничения окружения. Повторная проверка в отдельном home также успешна; при `NO_BROWSER=1` адаптер объявляет только `api-key`, а ChatGPT-вход выполняется отдельным helper `login`. Это не доказывает вход ChatGPT, качество модели или поведение Minecraft: для этого требуется запуск всей системы на настоящем сервере/клиенте.
`npm test` runs HTTP tests and a real stdio MCP handshake, and uses a separate mock ACP process to test sessions, summaries, history suppression, permission denial, and cancellation. Queue tests verify serialization within a project and independence between projects. The real pinned `codex-acp` also passed a free `initialize`: ACP v1, `loadSession: true`, and authentication methods `api-key` and `chat-gpt` before environment restrictions. A repeat check in a separate home also passed; with `NO_BROWSER=1`, the adapter advertises only `api-key`, while ChatGPT sign-in uses the separate `login` helper. This does not prove ChatGPT authentication, model quality, or Minecraft behavior: those require the complete system running against a real server/client.
Опциональный `node test/live-paper.mjs` запускается только против отдельного настоящего тестового Paper: проверяет полый куб, повторное применение с тем же ключом, экспорт `.schem`, библиотеку ассетов, отмену, импорт в тот же anchor, вторую отмену до 27 блоков воздуха, границы и честный ответ недоступной камеры. Он оставляет экспортированный тестовый asset в локальной библиотеке. Это изменяющая мир проверка, она не входит в обычный `npm test`.
The optional `node test/live-paper.mjs` runs only against a separate real test Paper server: it checks a hollow cube, applying again with the same key, `.schem` export, the asset library, undo, import at the same anchor, a second undo back to 27 air blocks, bounds, and a truthful unavailable-camera response. It leaves the exported test asset in the local library. This test changes the world and is not part of ordinary `npm test`.
Исходные API сверены с [ACP SDK](https://github.com/agentclientprotocol/typescript-sdk), [codex-acp](https://github.com/agentclientprotocol/codex-acp), [MCP SDK](https://github.com/modelcontextprotocol/typescript-sdk) [справочником конфигурации Codex](https://learn.chatgpt.com/docs/config-file/config-reference) и [документацией MCP Codex](https://learn.chatgpt.com/docs/extend/mcp?surface=cli).
The original APIs were checked against the [ACP SDK](https://github.com/agentclientprotocol/typescript-sdk), [codex-acp](https://github.com/agentclientprotocol/codex-acp), [MCP SDK](https://github.com/modelcontextprotocol/typescript-sdk), [Codex configuration reference](https://learn.chatgpt.com/docs/config-file/config-reference), and [Codex MCP documentation](https://learn.chatgpt.com/docs/extend/mcp?surface=cli).
+40 -40
View File
@@ -1,61 +1,61 @@
# Minecraft Builder Camera
Клиентский Fabric-мод для `minecraft-builder-mcp`. Предоставляет настоящий PNG из framebuffer Minecraft через защищённый локальный HTTP-интерфейс. Отрисовка требует запущенного клиента с рабочим графическим окружением. Мод не входит в серверный JAR и не изменяет блоки.
A client-side Fabric mod for `minecraft-builder-mcp`. It provides real PNG images from Minecraft's framebuffer through an authenticated local HTTP interface. Rendering requires a running client with a working graphics environment. The mod is separate from the server JAR and does not modify blocks.
## Закреплённая платформа
## Pinned platform
- Minecraft Java Edition **26.2**, Java **25**.
- Fabric Loader **0.19.5**, Fabric API **0.160.0+26.2**.
- Fabric Loom **1.17.20**, Gradle Wrapper **9.5.1** (SHA-256 дистрибутива проверяется).
- JUnit **5.12.2** используется только при сборке тестов.
- Fabric Loom **1.17.20**, Gradle Wrapper **9.5.1** (distribution SHA-256 is verified).
- JUnit **5.12.2** is used only to build and run tests.
Версии проверены по [Fabric Maven](https://maven.fabricmc.net/), [Fabric Meta](https://meta.fabricmc.net/v2/versions/loader/26.2) и [официальному примеру 26.2](https://github.com/FabricMC/fabric-example-mod/tree/26.2). Начиная с 26.1 Minecraft не обфусцирован; Yarn и перепривязка имён для этой сборки не нужны. [Инструкция Fabric для 26.2](https://www.fabricmc.net/2026/06/15/262.html).
Versions were checked against [Fabric Maven](https://maven.fabricmc.net/), [Fabric Meta](https://meta.fabricmc.net/v2/versions/loader/26.2), and the [official 26.2 example](https://github.com/FabricMC/fabric-example-mod/tree/26.2). Since 26.1, Minecraft is unobfuscated; this build needs neither Yarn nor name remapping. [Fabric instructions for 26.2](https://www.fabricmc.net/2026/06/15/262.html).
## Сборка и установка
## Build and installation
```bash
cd camera-mod
JAVA_HOME=/path/to/jdk-25 ./gradlew build
```
Результат: `build/libs/minecraft-builder-camera-0.1.0-SNAPSHOT.jar`. Установить его и закреплённый Fabric API в отдельный профиль Minecraft 26.2 с Fabric Loader. Клиент обычного строителя не требует этого мода.
Output: `build/libs/minecraft-builder-camera-0.1.0-SNAPSHOT.jar`. Install it and the pinned Fabric API in a separate Minecraft 26.2 profile with Fabric Loader. An ordinary builder's client does not need this mod.
Перед запуском профиля задать окружение процесса:
Set the process environment before launching the profile:
```bash
export MCB_CAMERA_TOKEN='<отдельный секрет длиной не менее 32 символов>'
export MCB_CAMERA_TOKEN='<separate secret of at least 32 characters>'
export MCB_CAMERA_PORT=8766
```
Тот же секрет указать в конфигурации Paper-плагина для подключения камеры. Paper принимает 32–512 символов из `A–Z`, `a–z`, `0–9`, `.`, `_`, `~`, `-`, без пробелов и переносов; автоматически созданное значение уже подходит. Все три ключа Paper должны различаться. Без `MCB_CAMERA_TOKEN` HTTP-служба отключена. `MCB_CAMERA_PORT` необязателен; допустимы порты 1024–65535. Адрес всегда `127.0.0.1`, переключения на публичный интерфейс нет.
Set the same secret in the Paper plugin's camera configuration. Paper accepts 32–512 characters from `A–Z`, `a–z`, `0–9`, `.`, `_`, `~`, and `-`, without spaces or line breaks; the automatically generated value already meets these requirements. All three Paper tokens must differ. Without `MCB_CAMERA_TOKEN`, the HTTP service is disabled. `MCB_CAMERA_PORT` is optional; allowed ports are 1024–65535. The address is always `127.0.0.1`, with no option to bind a public interface.
Запустить отдельного наблюдателя, подключиться к нужному Paper-серверу и перевести его в spectator разрешённым серверным способом. Указать UUID наблюдателя в Paper-плагине. Нужна допустимая отдельная игровая сессия, если строитель остаётся на сервере одновременно; мод не обходит вход или ограничения аккаунтов. Держать клиент с закрытыми меню, без слежения за другой сущностью. Свёрнутое окно может прекратить рендеринг и вызвать таймаут.
Launch a separate observer, connect to the intended Paper server, and switch it to spectator using an authorized server mechanism. Configure the observer's UUID in the Paper plugin. A valid separate game session is required if the builder stays on the server simultaneously; the mod does not bypass authentication or account restrictions. Keep client menus closed and do not spectate another entity. A minimized window may stop rendering and cause a timeout.
### Один клиент через Prism
### One client through Prism
Для локального теста достаточно одной учётной записи: владелец проекта одновременно служит камерой. Этот вариант проверен на настоящем клиенте Prism с Paper 26.2. В выбранный профиль установить мод и зависимости, подключиться к серверу и привязать владельца через `/ai setup`. В приватном конфиге Paper `camera-player-uuid` должен совпадать с `owner-uuid`. Владелец должен быть онлайн, иметь разрешение `minecraftbuilder.use` и находиться в spectator. Изменения конфигурации применяются после перезапуска плагина/сервера.
A local test can use one account: the project owner also acts as the camera. This configuration has been tested with a real Prism client and Paper 26.2. Install the mod and dependencies in the selected profile, connect to the server, and register the owner with `/ai setup`. In Paper's private configuration, `camera-player-uuid` must match `owner-uuid`. The owner must be online, have the `minecraftbuilder.use` permission, and be in spectator mode. Configuration changes take effect after restarting the plugin/server.
Чтобы секрет не попадал в аргументы Java и журнал лаунчера, использовать [scripts/camera-wrapper.py](../scripts/camera-wrapper.py) как `WrapperCommand` профиля Prism, например `python3 /path/to/minecraft-builder-mcp/scripts/camera-wrapper.py`. Обёртка читает `camera-token` и `camera-port` из приватного `.runtime/server/plugins/MinecraftBuilderMCP/config.yml` и передаёт их только через окружение дочернего процесса. Другой путь к конфигу задаётся переменной `MCB_CAMERA_PAPER_CONFIG`.
To keep the secret out of Java arguments and launcher logs, use [scripts/camera-wrapper.py](../scripts/camera-wrapper.py) as the Prism profile's `WrapperCommand`, for example `python3 /path/to/minecraft-builder-mcp/scripts/camera-wrapper.py`. The wrapper reads `camera-token` and `camera-port` from the private `.runtime/server/plugins/MinecraftBuilderMCP/config.yml` and passes them only through the child process environment. Set `MCB_CAMERA_PAPER_CONFIG` to use a different configuration path.
Сохранить ракурс внутри области проекта командой `/ai camera save test`. Затем из корня репозитория запустить:
Save a viewpoint inside the project region with `/ai camera save test`. Then run from the repository root:
```bash
python3 scripts/live-camera-test.py --camera-id test --delay 8
```
[scripts/live-camera-test.py](../scripts/live-camera-test.py) проверяет совпадение UUID владельца и камеры, spectator и доступ к Paper. Через восемь секунд он вызывает настоящий `camera_capture` по авторизованному HTTP-маршруту Paper, ждёт PNG и сохраняет исходные байты вместе с очищенными метаданными в `.runtime/camera-test`. Вместо сохранённого ракурса можно передать `--pose X Y Z YAW PITCH`, дополнив его `--fov 85` для общего вида большой постройки (допустимо 30–110°); `--after-operation-id` связывает снимок с завершённой операцией.
[scripts/live-camera-test.py](../scripts/live-camera-test.py) checks that the owner and camera UUIDs match, spectator mode is active, and Paper is accessible. After eight seconds it calls the real `camera_capture` through Paper's authenticated HTTP route, waits for the PNG, and saves the original bytes with sanitized metadata in `.runtime/camera-test`. Instead of a saved viewpoint, pass `--pose X Y Z YAW PITCH`, optionally adding `--fov 85` for an overview of a large building (allowed range: 30–110°); `--after-operation-id` links the capture to a completed operation.
До начала съёмки вернуться в окно Minecraft, закрыть чат и меню, остановиться и не двигать мышь. Допустимое изменение поворота всего 0.1°, поэтому даже небольшой сдвиг отменяет кадр. Переключение в другое окно может открыть меню паузы. В этом режиме снимок временно использует твой игровой вид; серверная телепортация меняет твою позицию. Режим игры и прежняя позиция автоматически не восстанавливаются. Для возврата к строительству выбрать нужный режим и место вручную.
Before capture begins, return to Minecraft, close chat and menus, stop moving, and keep the mouse still. Rotation tolerance is only 0.1°, so even slight movement cancels the image. Switching windows may open the pause menu. In this mode, capture temporarily uses your game view; the server teleport changes your position. Your game mode and previous position are not restored automatically. Choose the desired mode and location manually when returning to building.
## Протокол
## Protocol
Все запросы, включая health и чтение изображения, требуют `Authorization: Bearer <MCB_CAMERA_TOKEN>`. JSON не записывается в лог.
All requests, including health checks and image retrieval, require `Authorization: Bearer <MCB_CAMERA_TOKEN>`. JSON is not written to the log.
- `GET /health` — кэш состояния последнего клиентского тика: `status`, `connected`, `spectator`, `busy`, `dimension`, `playerId`, `updatedAt`. Старое `updatedAt` означает, что клиент перестал обновляться.
- `POST /v1/capture` — поставить один снимок в работу. Ответ HTTP 202: `{"status":"pending","captureId":"<uuid>"}`. При занятой камере HTTP 409 и `camera_busy`.
- `GET /v1/captures/<uuid>` — получить `pending`, `completed` либо `error`. Неизвестный/истёкший ID: HTTP 404. Терминальный `error` имеет `error` и `message`, без изображения.
- `GET /health` — cached state from the latest client tick: `status`, `connected`, `spectator`, `busy`, `dimension`, `playerId`, and `updatedAt`. A stale `updatedAt` means the client has stopped updating.
- `POST /v1/capture` — queue one capture. HTTP 202 response: `{"status":"pending","captureId":"<uuid>"}`. A busy camera returns HTTP 409 and `camera_busy`.
- `GET /v1/captures/<uuid>` — retrieve `pending`, `completed`, or `error`. Unknown/expired IDs return HTTP 404. A terminal `error` contains `error` and `message`, without an image.
Пример тела capture:
Example capture body:
```json
{
@@ -67,34 +67,34 @@ python3 scripts/live-camera-test.py --camera-id test --delay 8
}
```
`x/y/z` — позиция **ног игрока-наблюдателя**, как в Paper teleport. Paper сначала проверяет область/права и телепортирует настроенного наблюдателя; затем вызывает capture. Мод ждёт получения нужной позиции и измерения, но сам не отправляет `/tp` и не подменяет локальную позицию. `dimension` — клиентский ключ измерения, не имя папки и не Bukkit UUID. Дополнительные `world`/`world_id` принимаются как совместимые поля конверта, но не используются как доказательство измерения. `dimension` необязателен в низкоуровневом интерфейсе; серверный маршрут должен передавать его.
`x/y/z` specify the **observer player's feet position**, as in Paper teleportation. Paper first checks the region and permissions and teleports the configured observer, then calls capture. The mod waits for the requested position and dimension to arrive; it does not send `/tp` or override local position. `dimension` is the client's dimension key, rather than a directory name or Bukkit UUID. Additional `world`/`world_id` fields are accepted for envelope compatibility but are not used to verify the dimension. `dimension` is optional in the low-level interface; the server route should supply it.
Серверный маршрут Paper `camera_capture` передаёт POST, а при наличии `capture_id` опрашивает соответствующий GET. Конкретные названия внешних MCP-инструментов определяет Bridge.
Paper's `camera_capture` route forwards the POST request and polls the matching GET when `capture_id` is present. The Bridge determines the external MCP tool names.
Результат `completed` содержит `imageBase64`, `mimeType: "image/png"`, `captureId`, `capturedAt`, `dimension`, позицию ног, `eyeY`, фактические yaw/pitch, базовый FOV, размеры исходного framebuffer и изображения, а также метаданные готовности.
A `completed` result contains `imageBase64`, `mimeType: "image/png"`, `captureId`, `capturedAt`, `dimension`, feet position, `eyeY`, actual yaw/pitch, base FOV, source framebuffer and output image dimensions, and readiness metadata.
`width`/`height` задают максимальные размеры выходного изображения. Снимок вписывается в них с сохранением пропорций и без увеличения; разрешение окна не меняется. Это предотвращает искажение геометрии. Для точных 1280×720 следует использовать framebuffer такого же соотношения сторон и достаточного размера. Базовый FOV ограничен 30–110, ширина 320–1920, высота 180–1080; исходный framebuffer ограничен 16 мегапикселями. Поза требует конечных чисел, yaw -360..360 и pitch -90..90.
`width`/`height` specify maximum output dimensions. The capture fits within them while preserving aspect ratio and without upscaling; it does not resize the game window. This avoids distorting geometry. For exactly 1280×720, use a sufficiently large framebuffer with the same aspect ratio. Base FOV is limited to 30–110, width to 320–1920, and height to 180–1080; the source framebuffer is limited to 16 megapixels. Pose values must be finite, with yaw in -360..360 and pitch in -90..90.
## Что означает готовность
## What readiness means
Перед снимком проверяются spectator, совпадение позиции (±0.05 блока), измерения и собственного вида наблюдателя. Мод скрывает HUD, включает первый вид, отключает покачивание и влияние движения на FOV. Затем ждёт:
Before capture, the mod checks spectator mode, position agreement (±0.05 blocks), dimension, and use of the observer's own view. It hides the HUD, switches to first-person, and disables view bobbing and movement effects on FOV. It then waits for:
1. Девять клиентских чанков вокруг наблюдателя доступны не менее 20 тиков подряд.
2. В течение трёх кадров камера инициализирована, чанки доступны, очередь подготовки геометрии пуста.
3. Поза и окно остаются подходящими до чтения framebuffer.
1. Nine client chunks around the observer to remain available for at least 20 consecutive ticks.
2. Three frames with an initialized camera, available chunks, and an empty geometry preparation queue.
3. The pose and window to remain suitable until framebuffer readback.
PNG снимается через `Screenshot.takeScreenshot` после рендера кадра, с GPU readback через Blaze3D; прямого OpenGL-кода нет. Кодирование и уменьшение PNG выполняются отдельным потоком. HUD, FOV, перспектива, покачивание и поворот, сохранённые при начале работы мода с кадром, восстанавливаются на клиентском потоке после завершения или ошибки. Сохранение начинается после получения серверной позиции; это не возврат к положению игрока до телепортации. Позиция после серверной телепортации остаётся серверной.
PNG capture uses `Screenshot.takeScreenshot` after the frame renders, with GPU readback through Blaze3D and no direct OpenGL code. PNG encoding and downscaling run on a separate thread. The HUD, FOV, perspective, view bobbing, and rotation saved when the mod starts handling the capture are restored on the client thread after success or error. Saving starts after the server position arrives; this does not return the player to the position before teleportation. The server remains authoritative over the post-teleport position.
Это **проверяемая эвристика загрузки**, а не подтверждение конкретной серверной ревизии. Ответ всегда содержит `readiness: "local_chunks_and_render_queue_stable"` и `serverRevisionVerified: false`. Поле `afterOperationId` служит корреляцией; само по себе оно не доказывает, что клиент получил все обновления операции. Нельзя выдавать такой результат за проверку ревизии. Для строгой свежести нужен дополнительный серверный маркер и подтверждение обработки соответствующих пакетов. Дальняя геометрия вне проверенных чанков и изменения после кадра остаются ограничениями.
This is a **checked loading heuristic**, not confirmation of a specific server revision. The response always contains `readiness: "local_chunks_and_render_queue_stable"` and `serverRevisionVerified: false`. `afterOperationId` is for correlation; by itself it does not prove the client received every update from that operation. Do not present this result as revision verification. Strict freshness requires an additional server marker and acknowledgment that the corresponding packets were processed. Distant geometry outside the checked chunks and changes after capture remain limitations.
Ошибки загрузки, отключение, смена мира/позиции, открытые меню, вмешательство в поворот и неполученный framebuffer возвращают ошибку вместо старого кадра. Таймаут 20 секунд контролируется отдельным потоком даже при зависшем рендере. Следующий снимок разрешается после восстановления состояния на клиентском потоке. Хранятся максимум четыре результата не дольше двух минут; PNG до 8 MiB, тело запроса до 8192 байт. Изображения находятся в памяти и не записываются в общий каталог screenshots.
Loading failures, disconnection, world/position changes, open menus, rotation interference, and missing framebuffer data return an error instead of a stale image. A separate thread enforces the 20-second timeout even if rendering hangs. Another capture is allowed after state restoration on the client thread. At most four results are retained for up to two minutes; PNGs are limited to 8 MiB and request bodies to 8192 bytes. Images remain in memory and are not written to the shared screenshots directory.
## Проверки и границы прототипа
## Verification and prototype limits
`./gradlew build` компилирует мод против настоящих зависимостей Minecraft 26.2; тесты проверяют bearer-аутентификацию HTTP, ограничение размера запроса и валидацию параметров. Для них не запускаются клиент или вход в аккаунт.
`./gradlew build` compiles the mod against real Minecraft 26.2 dependencies; tests cover HTTP bearer authentication, request-size limits, and parameter validation. These tests do not launch the client or sign in to an account.
12 сентября 2026 года выполнен реальный графический тест: один клиент Prism, владелец проекта в spectator, одинаковый UUID владельца и камеры, Paper 26.2 и построенная башня из 575 блоков. Проверены загрузка Mixin, подключение клиента, серверная телепортация, чтение framebuffer и доставка PNG через Paper HTTP. На изображении видна построенная башня без HUD.
A real graphical test ran on September 12, 2026: one Prism client, the project owner in spectator mode, matching owner and camera UUIDs, Paper 26.2, and a completed 575-block tower. Mixin loading, client connection, server teleportation, framebuffer readback, and PNG delivery through Paper HTTP were verified. The image shows the built tower without the HUD.
Первый запрос завершился `view_changed`: фактический поворот отличался от заданного. Повтор после стабилизации дал PNG **1280×720 за 2.052 секунды**, с yaw **140°**, pitch **31°**, после **20 тиков** и **3 кадров** готовности. Это подтверждённый локальный замер одного запроса, а не гарантия времени для других сцен и компьютеров. Артефакты проверки: `.runtime/camera-test/20260912T192813Z-2b100930.png` и соответствующий JSON; они остаются локальными и не входят в Git.
The first request ended with `view_changed`: actual rotation differed from the requested rotation. A retry after stabilization produced a **1280×720 PNG in 2.052 seconds**, with yaw **140°**, pitch **31°**, after **20 ticks** and **3 frames** of readiness. This is a verified local measurement of one request, not a timing guarantee for other scenes or computers. Verification artifacts: `.runtime/camera-test/20260912T192813Z-2b100930.png` and its JSON metadata; they remain local and are excluded from Git.
Успешный кадр получен после завершения строительной операции и содержит её `afterOperationId`, но **`serverRevisionVerified` остаётся `false`**: подтверждения обработки конкретной серверной ревизии ещё нет. Отдельно остаются проверки восстановления всех настроек вида, таймаута при свёрнутом окне, отключения посреди снимка, сторонних шейдеров и отдельного аккаунта камеры. Рабочий графический цикл подтверждён для описанного сценария с одним клиентом.
The successful image was captured after the building operation completed and includes its `afterOperationId`, but **`serverRevisionVerified` remains `false`**: processing of a specific server revision is not yet acknowledged. Remaining checks include restoration of all view settings, timeout with a minimized window, disconnection during capture, third-party shaders, and a separate camera account. The working graphical cycle is verified for the single-client scenario described above.
+245 -245
View File
@@ -1,407 +1,407 @@
# minecraft-builder-mcp — дизайн-документ
# minecraft-builder-mcp — design document
Версия документа: 0.1 · Дата: 12 сентября 2026 года
Document version: 0.1 · Date: September 12, 2026
Статус: целевой дизайн. Первый прототип создан; фактические возможности, проверки и отличия от этого документа перечислены в [IMPLEMENTATION.md](IMPLEMENTATION.md). Разделы ниже описывают также ещё не реализованные требования.
Status: target design. The first prototype has been created; its actual capabilities, tests, and deviations from this document are listed in [IMPLEMENTATION.md](IMPLEMENTATION.md). The sections below also describe requirements that have not yet been implemented.
## 1. Назначение
## 1. Purpose
Создать строительную среду для Minecraft Java Edition, в которой человек и ИИ-агент совместно проектируют, строят и редактируют карты. Пользователь общается с Codex в игровом чате или во внешнем клиенте. Агент получает структурированные сведения о мире, применяет массовые изменения через MCP, смотрит реальные снимки и исправляет результат.
Create a building environment for Minecraft Java Edition in which a person and an AI agent collaboratively design, build, and edit maps. The user talks to Codex through in-game chat or an external client. The agent receives structured information about the world, applies bulk changes through MCP, inspects real captures, and corrects the result.
Основной сценарий: «Построй башню здесь» → обследование участка → строительство → снимки → уточнение пропорций. Пользователь может параллельно строить вручную, а затем попросить: «Сохрани мои окна, добавь два этажа и переделай крышу».
The main scenario is: “Build a tower here” → site inspection → construction → captures → proportion adjustments. The user can build manually in parallel and then ask: “Keep my windows, add two floors, and redo the roof.”
Результат — обычные ванильные блоки. Карта должна оставаться пригодной к использованию после удаления наших компонентов. История, рецепты и названия частей хранятся отдельно от игровых блоков.
The result consists of ordinary vanilla blocks. The map must remain usable after our components are removed. History, recipes, and part names are stored separately from game blocks.
## 2. Решения и рабочие предположения
## 2. Decisions and working assumptions
Из обсуждения следуют требования: Paper как строительная среда с перспективой мини-игр; Codex через готовый `codex-acp`; Minecraft MCP для работы с миром; виртуальные камеры; массовые операции; именованные части; сохранение ручных правок; экономное использование контекста; отмена и перенос построек.
The discussion establishes these requirements: Paper as a building environment with future minigame use; Codex through the existing `codex-acp`; Minecraft MCP for world interaction; virtual cameras; bulk operations; named parts; preservation of manual edits; economical context use; undo; and transferring builds.
Для этого документа приняты следующие проектные решения, которые можно изменить до реализации:
This document adopts the following design decisions, which may be changed before implementation:
- Первая версия рассчитана на одного владельца и небольшой круг доверенных строителей, один Paper-сервер и одну активную операцию записи на строительную область.
- Плагин на сервере является единственным компонентом нашей системы, который непосредственно изменяет мир.
- Камеры обслуживает отдельный клиент Minecraft с Fabric-модом. Обычному игроку клиентский мод для чата не требуется.
- Bridge написан на TypeScript; Paper-плагин и Fabric-мод — на Java. Точные версии инструментов фиксируются после проверки совместимости.
- Строительный язык первой версии — ограниченное декларативное описание геометрии и повторений. Произвольный Python/JavaScript внутри сервера не выполняется.
- Снимки, конфликты и история не имеют собственной модели внутри MCP. Их интерпретирует агент с поддержкой изображений.
- Пользовательская команда на строительство разрешает обычные изменения внутри выбранной области; подтверждение каждого пакета блоков не требуется. Настоящие конфликты и выход за полномочия обрабатываются отдельно.
- The first version targets one owner and a small group of trusted builders, one Paper server, and one active write operation per building area.
- The server plugin is the only component of our system that modifies the world directly.
- Cameras are served by a separate Minecraft client with a Fabric mod. Ordinary players do not need a client mod for chat.
- The Bridge is written in TypeScript; the Paper plugin and Fabric mod in Java. Exact tool versions are pinned after compatibility checks.
- The first version's building language is a restricted declarative description of geometry and repetition. Arbitrary Python/JavaScript is not executed inside the server.
- Captures, conflicts, and history do not have their own model within MCP. An image-capable agent interprets them.
- A user's building command authorizes ordinary changes within the selected area; approval is not required for every batch of blocks. Actual conflicts and actions outside the granted scope are handled separately.
## 3. Почему нужны клиентская и серверная части
## 3. Why both client and server components are needed
Клиентский мод может управлять камерой, снимать изображение, читать присланные клиенту чанки и отправлять команды, разрешённые игроку. Этого достаточно для прототипа, который строит через серверные команды. Но такой клиент не является источником окончательного состояния мира и не обеспечивает согласованную проверку и запись блоков на сервере.
A client mod can control the camera, capture an image, read chunks sent to the client, and send commands the player is allowed to use. This is sufficient for a prototype that builds through server commands. However, such a client is not the authoritative source of world state and cannot provide coordinated block validation and writing on the server.
Серверный компонент нужен для достоверного чтения участка, проверки прав, сравнения состояний непосредственно перед записью, журналирования и применения изменений с ограничением нагрузки. Он не умеет сам отрисовывать игровой вид. Клиентское и серверное исполнение в Minecraft разделены; рендеринг выполняет клиент. [Разделение сторон в Fabric](https://wiki.fabricmc.net/tutorial%3Aside).
A server component is needed for authoritative region reads, permission checks, state comparisons immediately before writing, journaling, and applying changes under load limits. It cannot render the game view itself. Client and server execution are separate in Minecraft; rendering is performed by the client. [Fabric side separation](https://wiki.fabricmc.net/tutorial%3Aside).
Целевая установка может целиком работать на одном компьютере: Paper, Bridge, Codex и клиент камеры. Выделенная машина и аренда хостинга не обязательны. Отдельный наблюдатель потребует собственной допустимой игровой сессии; нельзя предполагать, что одна учётная запись позволит одновременно держать игрока и камеру на одном сервере. При отсутствии второй сессии возможен режим камеры в клиенте пользователя с временным переключением вида; это отдельный компромисс интерфейса.
The target installation can run entirely on one computer: Paper, Bridge, Codex, and the camera client. A dedicated machine or rented hosting is not required. A separate observer needs its own permitted game session; we cannot assume that one account can keep both the player and camera connected to the same server simultaneously. If a second session is unavailable, camera mode in the user's client with temporary view switching is possible; this is a separate interface tradeoff.
Одиночная игра содержит встроенный сервер. В дальнейшем можно добавить Fabric-модуль для его серверной стороны, сохранив MCP-контракты. Это устраняет отдельный процесс Paper, но требует другого адаптера мира. Одного мода, исполняющегося только на логической клиентской стороне, для полных гарантий недостаточно.
Single-player includes an integrated server. A Fabric module for its server side can be added later while retaining the MCP contracts. This removes the separate Paper process but requires another world adapter. A mod running only on the logical client side is insufficient for the full guarantees.
## 4. Платформа и совместимость
## 4. Platform and compatibility
Кандидат для первого прототипа — Minecraft/Paper 26.2 и Java 25. На дату документа страница загрузки предлагает Paper 26.2, а документация указывает Java 25 для веток 26.1+. Это подтверждает наличие платформы, но не совместимость всех наших зависимостей. [Загрузка Paper](https://papermc.io/downloads/paper), [требования Java](https://docs.papermc.io/paper/getting-started/).
The candidate for the first prototype is Minecraft/Paper 26.2 with Java 25. On the document date, the download page offers Paper 26.2, and the documentation specifies Java 25 for the 26.1+ branches. This confirms platform availability, not compatibility of all our dependencies. [Paper downloads](https://papermc.io/downloads/paper), [Java requirements](https://docs.papermc.io/paper/getting-started/).
До реализации основной функциональности необходимо зафиксировать точные версии Paper, WorldEdit, Fabric Loader/API, Codex, `codex-acp`, MCP/ACP SDK и Node.js. Обновление зависимостей не должно происходить автоматически при каждом запуске. Версии и хеши сборок войдут в будущий файл совместимости.
Before implementing the main functionality, exact versions of Paper, WorldEdit, Fabric Loader/API, Codex, `codex-acp`, the MCP/ACP SDKs, and Node.js must be pinned. Dependencies must not update automatically on every launch. Build versions and hashes will be recorded in a future compatibility file.
WorldEdit используется для выделений и формата `.schem`; возможность использовать его как механизм записи проверяется отдельно. Его `EditSession` поддерживает пакетирование и историю, однако это не заменяет нашу проверку конфликтов, постоянный журнал и управление временем исполнения. Буферизация не должна переносить фактическую запись за пределы проверенного серверного шага. [WorldEdit Edit Sessions](https://worldedit.enginehub.org/en/latest/api/concepts/edit-sessions/).
WorldEdit is used for selections and the `.schem` format; using it as the write mechanism is evaluated separately. Its `EditSession` supports batching and history, but this does not replace our conflict checks, persistent journal, or execution-time control. Buffering must not defer actual writes beyond the validated server step. [WorldEdit Edit Sessions](https://worldedit.enginehub.org/en/latest/api/concepts/edit-sessions/).
Начальный гарантируемый набор — ванильные строительные блоки без инвентарей и пользовательского NBT, включая протестированные состояния брёвен, ступеней и плит. Допускается воздух как результат удаления. Двери и другие составные конструкции подключаются только после реализации неделимых групп изменений. Гравитационные блоки, жидкости, редстоун, сущности и block entities не входят в первоначальную гарантию редактирования и отмены.
The initial guaranteed set consists of vanilla building blocks without inventories or custom NBT, including tested log, stair, and slab states. Air is allowed as the result of deletion. Doors and other multipart structures are added only after indivisible change groups are implemented. Gravity-affected blocks, fluids, redstone, entities, and block entities are outside the initial editing and undo guarantees.
Ограничение действует и на исходное содержимое: операция не может молча затереть сундук или другой неподдерживаемый блок. Предварительная проверка обнаруживает это до применения и возвращает понятную причину.
The restriction also applies to existing content: an operation must not silently overwrite a chest or another unsupported block. Preflight validation detects this before application and returns a clear reason.
## 5. Границы первой версии
## 5. First-version scope
В v0.1 входят:
v0.1 includes:
- Команды чата, отдельная сессия проекта, поток коротких сообщений о ходе работы и остановка.
- Выделенная строительная область и локальный осмотр мира.
- Компактные описания форм, повторения, палитры и воспроизводимый `seed`.
- Предварительный план, подсчёт изменений и применение порциями.
- Именованные части с точными наборами принадлежащих им блоков.
- Проверка изменений после чтения, остановка на конфликте и отмена с проверками.
- Постоянный журнал операций и обнаружение незавершённой записи после перезапуска.
- Одна обслуживающая камера, несколько сохранённых ракурсов и выдача изображений через MCP.
- Импорт и экспорт `.schem` в пределах поддерживаемого набора данных.
- Chat commands, a separate project session, a stream of short progress messages, and stopping.
- A designated building area and local world inspection.
- Compact shape descriptions, repetition, palettes, and a reproducible `seed`.
- A prepared plan, change counts, and application in slices.
- Named parts with exact sets of blocks belonging to them.
- Checks for changes since reading, stopping on conflict, and checked undo.
- A persistent operation journal and detection of unfinished writes after restart.
- One serving camera, several saved viewpoints, and image delivery through MCP.
- `.schem` import and export within the supported data set.
За пределами v0.1: публичный сервис для любых игроков, несколько одновременно пишущих агентов в одной области, Folia, полноценные мини-игры, произвольный доступ к серверной консоли, генерация 3D сторонними сервисами, автоматическая вокселизация мешей, универсальная физическая симуляция, произвольные скрипты с доступом к ОС и интеллектуальное перенесение любой ручной правки при смене геометрии.
Outside v0.1: a public service for arbitrary players, multiple agents writing simultaneously in one area, Folia, complete minigames, arbitrary server-console access, third-party 3D generation services, automatic mesh voxelization, general-purpose physics simulation, arbitrary scripts with OS access, and intelligent transfer of any manual edit when geometry changes.
Система помогает строить карты для мини-игр, но не реализует правила самих мини-игр. Автоматическая оценка красоты не является гарантией качества.
The system helps build minigame maps but does not implement the minigames' rules. Automatic aesthetic assessment is not a quality guarantee.
## 6. Компоненты и связи
## 6. Components and connections
Путь запроса: игровой чат → Paper-плагин → Bridge как ACP-клиент → `codex-acp` → Codex. Путь изменения: Codex → Minecraft MCP в Bridge → Paper-плагин → мир. Путь изображения: Codex → Minecraft MCP → Camera Worker → Fabric-клиент → изображение.
Request path: in-game chat → Paper plugin → Bridge as ACP client → `codex-acp` → Codex. Change path: Codex → Minecraft MCP in the Bridge → Paper plugin → world. Image path: Codex → Minecraft MCP → Camera Worker → Fabric client → image.
### Paper-плагин
### Paper plugin
Отвечает за команды, личности игроков, области, полномочия, снимки состояния блоков, валидацию планов, расписание применения и постоянную историю. Плагин проверяет ограничения независимо от того, что обещали агент и Bridge.
Responsible for commands, player identities, regions, permissions, block-state snapshots, plan validation, application scheduling, and persistent history. The plugin enforces limits independently of any promises made by the agent or Bridge.
### Bridge
Запускает закреплённую версию `codex-acp`, реализует ACP-клиент и предоставляет инструменты Minecraft MCP. Хранит связь проекта с диалогом, форматирует сообщения для игрового чата и ограничивает объём данных, передаваемых модели. Не становится альтернативным источником истины о блоках.
Launches the pinned `codex-acp` version, implements the ACP client, and exposes Minecraft MCP tools. Maintains the project's connection to its conversation, formats messages for in-game chat, and limits the amount of data sent to the model. It does not become an alternative source of truth about blocks.
`codex-acp` уже реализует преобразование ACP в операции Codex App Server, поддерживает изображения и подключение MCP-серверов. Поэтому отдельный ACP-адаптер Codex в проекте не пишется. Возможности конкретной закреплённой версии проверяются при установлении соединения. [Репозиторий codex-acp](https://github.com/agentclientprotocol/codex-acp).
`codex-acp` already translates ACP into Codex App Server operations and supports images and MCP server connections. The project therefore does not implement a separate Codex ACP adapter. The capabilities of the particular pinned version are checked during connection setup. [codex-acp repository](https://github.com/agentclientprotocol/codex-acp).
### Camera Worker
Управляет очередью снимков и подключённым Fabric-клиентом. Хранит ракурсы, проверяет загрузку сцены и возвращает изображения с метаданными. Отказ камеры не уничтожает историю и не мешает чтению блоков; задача явно получает статус «визуально не проверено».
Manages the capture queue and the connected Fabric client. Stores viewpoints, checks scene loading, and returns images with metadata. Camera failure does not destroy history or prevent block reads; the task explicitly receives a “not visually verified” status.
### Хранилища
### Storage
Плагин хранит SQLite для метаданных и индексирования, а крупные снимки и изменения — в сжатых файлах с контрольными суммами. Он единственный писатель своей базы. Bridge отдельно хранит ACP-сессии и компактные сводки; Camera Worker — изображения. Общая база, которую одновременно напрямую меняют Java и Node.js, не используется.
The plugin stores metadata and indexes in SQLite, and large snapshots and changes in compressed files with checksums. It is the only writer to its database. The Bridge separately stores ACP sessions and compact summaries; the Camera Worker stores images. There is no shared database directly modified by both Java and Node.js.
Локальные соединения по умолчанию привязаны к loopback и защищены отдельными секретами компонентов. Для удалённой установки предполагается SSH-туннель или проверенное защищённое соединение; публичный доступ к интерфейсу изменения мира не нужен.
Local connections bind to loopback by default and are protected by separate component secrets. Remote installations are expected to use an SSH tunnel or a verified secure connection; the world-editing interface does not need public access.
## 7. Сессии и игровой интерфейс
## 7. Sessions and the in-game interface
Основные команды, проектируемые для v0.1:
Main commands proposed for v0.1:
- `/ai <текст>` — сообщение агенту в активном проекте.
- `/ai project create <имя>` и `/ai project use <имя>` — создание и выбор проекта.
- `/ai area set` — зафиксировать выбранный участок после проверки размеров и прав.
- `/ai status` — состояние текущего запроса, операции и камеры.
- `/ai stop` — остановить агентский ход и запросить остановку активного изменения мира.
- `/ai undo <operation>` — подготовить и применить проверяемую отмену собственной операции.
- `/ai camera save <имя>` — сохранить положение и направление взгляда.
- `/ai protect <part>` — защитить часть от изменений агента.
- `/ai <text>` — message the agent in the active project.
- `/ai project create <name>` and `/ai project use <name>` — create and select a project.
- `/ai area set` — commit the selected region after checking its size and permissions.
- `/ai status` — show the current request, operation, and camera status.
- `/ai stop` — stop the agent turn and request cancellation of the active world change.
- `/ai undo <operation>` — prepare and apply checked undo for the user's own operation.
- `/ai camera save <name>` — save the position and view direction.
- `/ai protect <part>` — protect a part from agent changes.
Обычный общий чат не отправляется модели целиком. Сообщения `/ai` и явные упоминания передаются только после проверки отправителя. Ответ по умолчанию виден инициатору; общий строительный канал можно добавить настройкой.
Ordinary public chat is not sent to the model in full. `/ai` messages and explicit mentions are forwarded only after sender validation. Replies are visible to the initiator by default; a shared building channel can be added through configuration.
На проект назначается очередь запросов. В v0.1 один активный ход агента на проект; новые сообщения очередятся, а изменение задания во время работы требует согласованного прерывания. UUID игрока, UUID мира и идентификатор проекта берутся с сервера. Модель не может подменить их текстом запроса.
Each project has a request queue. v0.1 allows one active agent turn per project; new messages are queued, and changing the task during execution requires coordinated interruption. The player UUID, world UUID, and project ID come from the server. The model cannot replace them through prompt text.
Bridge хранит идентификатор ACP-сессии, но проект не зависит от вечной доступности этого диалога. При невозможности возобновления создаётся новая сессия и передаются сводка проекта, текущая операция и ссылки на данные. Подключение к текущему диалогу настольного Codex автоматически не предполагается. Жизненный цикл сверяется с [ACP Session Setup](https://agentclientprotocol.com/protocol/v1/session-setup) и [ACP Prompt Turn](https://agentclientprotocol.com/protocol/v1/prompt-turn).
The Bridge stores the ACP session ID, but the project does not depend on that conversation remaining available forever. If resumption is impossible, a new session receives the project summary, current operation, and data references. Automatic attachment to the current Codex desktop conversation is not assumed. The lifecycle is checked against [ACP Session Setup](https://agentclientprotocol.com/protocol/v1/session-setup) and [ACP Prompt Turn](https://agentclientprotocol.com/protocol/v1/prompt-turn).
Чат показывает этапы и результат, а не каждую установку блока. Сообщения ограничены по длине и частоте. В сообщении о конфликте пользователь видит часть здания, место и последствия выбора; технические идентификаторы доступны в деталях.
Chat displays stages and results, not every block placement. Message length and frequency are limited. A conflict message shows the user the building part, location, and consequences of their choice; technical identifiers are available in the details.
## 8. Модель данных
## 8. Data model
**Project:** стабильный ID, владелец, участники, world UUID, world epoch, разрешённые области, политика блоков, настройки качества и краткая сводка замысла. Epoch меняется при восстановлении или замене мира, чтобы старые планы нельзя было применить к другой копии.
**Project:** stable ID, owner, members, world UUID, world epoch, permitted regions, block policy, quality settings, and a brief design summary. The epoch changes when a world is restored or replaced so that old plans cannot be applied to a different copy.
**Region:** измерение, включительные целочисленные границы `min/max`, ограничения чтения и записи. Координаты блоков хранятся целыми; камеры — вещественными. Высота и граница мира берутся из сервера. Локальные координаты рецептов имеют явно заданную точку привязки и преобразование в координаты мира.
**Region:** dimension, inclusive integer `min/max` bounds, and read/write limits. Block coordinates are integers; camera coordinates are floating-point values. World height and border come from the server. Local recipe coordinates have an explicit anchor and transformation into world coordinates.
**Part:** ID, имя, родитель, теги, точная маска блоков, ограничивающий объём, точка привязки, ревизия, режим защиты, ссылка на рецепт. Ограничивающий прямоугольник нужен для поиска и не означает владения всем его содержимым. В v0.1 редактируемые дочерние маски не пересекаются; родитель объединяет их.
**Part:** ID, name, parent, tags, exact block mask, bounding volume, anchor, revision, protection mode, and recipe reference. The bounding box is used for lookup and does not imply ownership of everything inside it. In v0.1, editable child masks do not overlap; the parent is their union.
**Recipe:** версия языка, версия генератора, параметры, палитра, seed, подчасти и преобразования. Одинаковые входы и версии должны порождать одинаковый план. Повороты преобразуют и координаты, и направленные состояния блоков. Неподдерживаемые преобразования отклоняются.
**Recipe:** language version, generator version, parameters, palette, seed, subparts, and transforms. Identical inputs and versions must produce the same plan. Rotations transform both coordinates and directional block states. Unsupported transforms are rejected.
**Snapshot:** ID, мир и epoch, маска, канонические состояния блоков, ревизии секций и хеши. Снимок, собранный за несколько тиков, не объявляется глобально атомарным: изменившиеся во время сборки секции перечитываются или снимок помечается нестабильным.
**Snapshot:** ID, world and epoch, mask, canonical block states, section revisions, and hashes. A snapshot assembled over several ticks is not declared globally atomic: sections that change during collection are reread, or the snapshot is marked unstable.
**Plan:** неизменяемый ID и хеш содержимого, инициатор, область, базовый снимок, read set зависимостей, write set с `expected/desired`, группы взаимосвязанных блоков, срок действия и статистика. Read set включает опоры и свободные проходы, если от них зависит решение. План хранится на сервере; модели возвращается сводка.
**Plan:** immutable ID and content hash, initiator, region, base snapshot, dependency read set, write set with `expected/desired`, groups of related blocks, expiry, and statistics. The read set includes supports and clear passages when the decision depends on them. The plan is stored on the server; the model receives a summary.
**Operation:** ID, idempotency key, plan ID, состояние, номера порций, число подтверждённых записей, конфликты, автор, временные метки и связь с операцией отмены. Точное исходное и полученное содержимое хранится в постоянном журнале.
**Operation:** ID, idempotency key, plan ID, status, slice numbers, count of confirmed writes, conflicts, author, timestamps, and a link to the undo operation. Exact original and resulting contents are stored in the persistent journal.
**Camera:** имя, мир, позиция, yaw/pitch, FOV, разрешение, профиль отображения. **Capture:** ID изображения, camera ID, время, связанная операция, сведения о загрузке и статус свежести. Снимок относится к моменту наблюдения, а не является атомарным изображением состояния всего сервера.
**Camera:** name, world, position, yaw/pitch, FOV, resolution, and display profile. **Capture:** image ID, camera ID, time, associated operation, loading information, and freshness status. A capture corresponds to an observation time; it is not an atomic image of the entire server state.
## 9. Строительный язык и рабочий цикл
## 9. Building language and workflow
В v0.1 агент передаёт JSON-программу: параметры, палитру и последовательность операций `box`, `line`, `cylinder`, `arch`, `repeat`, `transform`, `replace` и `paste`. Это проектируемые примитивы, а не существующие инструменты. Для `replace` обязательны маска области и фильтр исходных состояний.
In v0.1, the agent submits a JSON program: parameters, a palette, and a sequence of `box`, `line`, `cylinder`, `arch`, `repeat`, `transform`, `replace`, and `paste` operations. These are proposed primitives, not existing tools. `replace` requires a region mask and a filter on source states.
Повторения ограничены счётчиком; разрешены только определённые числовые выражения и ссылки на параметры. Нет `eval`, бесконечных циклов, загрузки модулей, сети и файловых путей. Исполнитель имеет лимиты глубины, операций, памяти, времени и итогового числа блоков. Поддержка произвольного кода в будущем требует отдельного изолированного процесса с ограничениями ОС, а не запрета нескольких строк в скрипте.
Repetitions have a bounded count; only specified numeric expressions and parameter references are allowed. There is no `eval`, infinite looping, module loading, networking, or file paths. The interpreter has limits on depth, operations, memory, time, and the resulting block count. Future support for arbitrary code requires a separate process with OS-enforced isolation, not merely banning a few strings in a script.
Последовательность работы:
Workflow:
1. Агент узнаёт возможности сервера, активный проект, участок и ракурсы.
2. Запрашивает сводку рельефа и существующих частей; при необходимости — локальные блоки и снимок.
3. Формирует рецепт или точечную правку конкретной части.
4. Плагин создаёт снимок зависимостей, рассчитывает план и проверяет ограничения без записи в мир.
5. Агент получает объём, материалы, пересечения и предупреждения о непроверенных свойствах.
6. Допустимый план применяется порциями. Для обычной разрешённой постройки повторное подтверждение не требуется.
7. После применения выполняются структурные проверки и снимки выбранных ракурсов.
8. Исправление создаёт новую операцию. Число самостоятельных повторов ограничено; при отсутствии улучшения агент сообщает, что не удалось решить.
1. The agent discovers server capabilities, the active project, the region, and viewpoints.
2. It requests a terrain summary and existing parts; if needed, local blocks and a capture.
3. It creates a recipe or a targeted edit to a specific part.
4. The plugin snapshots dependencies, computes a plan, and checks limits without writing to the world.
5. The agent receives volume, materials, intersections, and warnings about unverified properties.
6. A permitted plan is applied in slices. An ordinary authorized build does not require repeated approval.
7. After application, structural checks and captures from selected viewpoints are performed.
8. A correction creates a new operation. The number of autonomous retries is limited; if there is no improvement, the agent reports what it could not resolve.
Рецепт не является единственным источником текущей геометрии. После ручного изменения агент обязан опираться на актуальный мир. В v0.1 нельзя просто повторно сгенерировать целую часть поверх текущего содержимого.
The recipe is not the sole source of current geometry. After a manual change, the agent must use the actual world state. v0.1 must not simply regenerate an entire part over its current contents.
Качество постройки задаётся кратким замыслом проекта: назначение, масштаб относительно игрока, силуэт, палитра, основные материалы, входы, внутренние помещения и опорные ракурсы. Для крупной задачи агент сначала делает план объёмов, затем конструкцию, потом детали. Эти этапы остаются отдельными операциями, чтобы удачный силуэт не терялся при неудачной детализации. Пустой интерьер считается допустимым только тогда, когда он соответствует заданию.
Build quality is guided by a brief project intent: purpose, scale relative to the player, silhouette, palette, primary materials, entrances, interior spaces, and reference viewpoints. For a large task, the agent first plans the major volumes, then builds the structure, then adds details. These stages remain separate operations so that unsuccessful detailing does not destroy a successful silhouette. An empty interior is acceptable only when it matches the brief.
Структурная проверка v0.1 подтверждает заявленные размеры, границы, состояния блоков и фактическое завершение плана. Смысловые свойства вроде удобства навигации, баланса арены и красоты фасада оцениваются отдельно и не выдаются за результат простого сравнения блоков.
Structural validation in v0.1 confirms declared dimensions, bounds, block states, and actual plan completion. Semantic properties such as navigability, arena balance, and facade aesthetics are assessed separately and are not presented as results of simple block comparison.
## 10. Ручные изменения и конфликты
## 10. Manual edits and conflicts
Сравнение выполняет серверный код. Модель не получает полный список блоков для самостоятельного вычисления разницы.
Server code performs the comparison. The model does not receive the full block list to compute the difference itself.
Для обычной записи используются базовое состояние `B`, текущее `C` и желаемое `D`:
An ordinary write uses base state `B`, current state `C`, and desired state `D`:
- `C = B`: запись `D` допустима, если неизменны зависимости и соблюдены права.
- `C = D`: блок уже соответствует результату; запись не требуется и не включается в новую историю как наша работа.
- Иначе: конфликт. Состояние не перезаписывается автоматически.
- `C = B`: writing `D` is allowed if dependencies are unchanged and permissions are satisfied.
- `C = D`: the block already matches the result; no write is needed, and it is not recorded in the new history as our work.
- Otherwise: a conflict. The state is not overwritten automatically.
В v0.1 при обнаружении ручного расхождения внутри перестраиваемой части автоматическая повторная генерация этой части останавливается. Агент может подготовить локальный план, который явно сохраняет текущую геометрию, либо строить другую, незатронутую часть.
In v0.1, detecting a manual divergence inside a part being rebuilt stops automatic regeneration of that part. The agent may prepare a local plan that explicitly preserves current geometry, or build a different, unaffected part.
Для v0.2 предлагается трёхстороннее объединение: сравниваются предыдущий сгенерированный результат `G0`, текущий мир `C` и новый результат `G1`. Если `G1 = G0`, ручная правка сохраняется; если `C = G0`, можно принять новую геометрию; если `C = G1`, запись не нужна; остальные пересечения требуют решения. Это объединение по координатам, а не понимание смысла окна или лестницы.
A three-way merge is proposed for v0.2: compare the previous generated result `G0`, the current world `C`, and the new result `G1`. If `G1 = G0`, preserve the manual edit; if `C = G0`, the new geometry may be accepted; if `C = G1`, no write is needed; other overlaps require a decision. This is a coordinate-based merge, not an understanding of what a window or staircase means.
Пример: ручное окно в неизменяемой стене сохраняется при добавлении верхних этажей. Если новый этаж сдвигает всю стену, система не знает автоматически, куда перенести окно. В v0.1 такая перестройка останавливается и предлагается локальный новый план. Автоматическое перенесение поправок в координатах рецепта относится к следующей версии.
Example: a manually added window in an unchanged wall is preserved when upper floors are added. If a new floor shifts the entire wall, the system does not automatically know where to move the window. In v0.1, such rebuilding stops and a new local plan is proposed. Automatic transfer of edits in recipe coordinates belongs to the next version.
При заранее найденном конфликте план не начинает запись. Если конфликт возник во время выполнения, операция останавливается перед следующей затронутой группой и возвращает частичный результат. Она не продолжает молча строить остальные фрагменты: это может оставить конструкцию геометрически неверной.
If a conflict is found in advance, the plan does not begin writing. If a conflict arises during execution, the operation stops before the next affected group and returns a partial result. It does not silently continue building the remaining fragments, since this could leave the structure geometrically incorrect.
Варианты разрешения: сохранить текущий мир и перепланировать; исключить защищённую часть; по явному решению владельца заменить конкретный конфликтующий фрагмент. Новый выбор создаёт новый план от свежего состояния. Глобального режима «игнорировать все конфликты» в инструментах агента нет.
Resolution options are: preserve the current world and replan; exclude a protected part; or, following an explicit owner decision, replace a specific conflicting fragment. A new decision creates a new plan from fresh state. The agent's tools do not offer a global “ignore all conflicts” mode.
События игроков, природных изменений и интеграция WorldEdit ускоряют обновление ревизий. Однако не все сторонние плагины обязаны вызывать одинаковые события. Поэтому хеши и ревизии служат ускорением, а проверка живых блоков непосредственно перед записью остаётся обязательной. Неизвестный источник изменения называется «внешнее изменение», а не приписывается игроку.
Player events, natural-change events, and WorldEdit integration speed up revision updates. However, third-party plugins are not all required to emit the same events. Hashes and revisions therefore serve as optimizations, while live block checks immediately before writing remain mandatory. An unknown source is described as an “external change,” not attributed to a player.
Серверная проверка защищает текущее содержимое. Если неподконтрольный плагин изменил блок и вернул его обратно между проверками, одно сравнение содержимого не восстановит эту историю. Полная авторская история всех возможных изменений мира не обещается.
Server validation protects current content. If an uncontrolled plugin changes a block and changes it back between checks, content comparison alone cannot reconstruct that history. A complete authorship history of every possible world change is not promised.
## 11. Применение, остановка и восстановление
## 11. Application, stopping, and recovery
Состояния операции: `prepared` → `queued` → `applying` → `applied`. Ветви завершения: `conflict`, `cancelled`, `failed`, `recovery_required`. Каждое состояние сопровождается количеством реально подтверждённых блоков: даже `cancelled` может означать частично изменённый мир. Визуальная проверка имеет отдельный статус `pending/passed/needs_changes/unavailable`; снимок не определяет завершённость записи.
Operation states: `prepared` → `queued` → `applying` → `applied`. Other terminal branches: `conflict`, `cancelled`, `failed`, `recovery_required`. Every state includes the count of actually confirmed blocks: even `cancelled` can mean a partially modified world. Visual validation has a separate `pending/passed/needs_changes/unavailable` status; a capture does not determine whether writing has finished.
Подготовка геометрии, сжатие, работа с файлами, сеть и запросы к модели выполняются вне игрового потока. Чтение и изменение живого мира выполняются через допустимые серверные API в серверном потоке. Такой подход соответствует ограничениям [Paper Scheduler](https://docs.papermc.io/paper/dev/scheduler/).
Geometry preparation, compression, file operations, networking, and model requests run outside the game thread. Live world reads and writes use supported server APIs on the server thread. This follows the restrictions of the [Paper Scheduler](https://docs.papermc.io/paper/dev/scheduler/).
Алгоритм порции:
Slice algorithm:
1. Сформировать ограниченную группу изменений и зависимости от её окружения. Общий диспетчер плагина сериализует пересекающиеся операции по UUID мира и области, в том числе между разными проектами. Блокировка одного проекта не считается достаточной защитой.
2. В серверном потоке прочитать фактическое исходное состояние и подготовить запись намерения с `before/after`, ID группы и контрольной суммой.
3. Сохранить намерение в постоянный журнал вне серверного потока и дождаться подтверждения сохранения. До этого мир не меняется.
4. Вернуться в серверный поток; повторно проверить полномочия, epoch, ограничения, ожидаемые состояния и зависимости. При изменениях остановиться до записи этой группы.
5. В том же серверном шаге без уступки управления применить допустимую небольшую группу, проверить результат и зарегистрировать фактически изменённые блоки. Запись намерения со статусом пропуска или ошибки также сохраняется.
6. Зафиксировать завершение группы и только затем продолжить следующую. Обновить сводку операции и инвалидировать затронутые кэши.
1. Form a bounded group of changes and dependencies on its surroundings. A plugin-wide dispatcher serializes overlapping operations by world UUID and region, including across different projects. A lock on a single project is not sufficient protection.
2. On the server thread, read the actual initial state and prepare an intent record with `before/after`, a group ID, and a checksum.
3. Save the intent to the persistent journal off the server thread and wait for persistence acknowledgement. The world does not change before this.
4. Return to the server thread; recheck permissions, epoch, limits, expected states, and dependencies. If anything changed, stop before writing this group.
5. In the same server step, without yielding control, apply a permitted small group, verify the result, and record blocks actually changed. Intent records with skipped or error outcomes are also persisted.
6. Commit group completion before continuing to the next group. Update the operation summary and invalidate affected caches.
План должен объявлять зависимости. Если часть зависит от ранее обработанных блоков, последующие проверки учитывают уже подтверждённые значения самой операции. Изменение важной опоры после её обработки приостанавливает дальнейшие зависимые шаги. Полная согласованность всего здания на протяжении многих тиков без блокировки всех внешних писателей не гарантируется; после записи нужна итоговая проверка.
A plan must declare dependencies. If a part depends on blocks processed earlier, subsequent checks account for the operation's own confirmed values. A change to an important support after it was processed pauses subsequent dependent steps. Full consistency of the entire building across many ticks is not guaranteed without locking out all external writers; a final check is required after writing.
Обычная ручная правка не вклинивается между проверкой и записью одной серверной порции. Но даже порция не является ACID-транзакцией Minecraft: исключение, вложенные события или физика могут дать частичное изменение. Исполнитель записывает фактический результат, а операция останавливается. Для составных объектов задаются маленькие неделимые логические группы и отдельные правила проверки. Поддержка таких групп не означает атомарности при падении процесса.
An ordinary manual edit cannot interleave between validation and writing within one server slice. Even a slice, however, is not a Minecraft ACID transaction: an exception, nested events, or physics may cause partial changes. The executor records the actual result, and the operation stops. Multipart objects use small indivisible logical groups and separate validation rules. Support for these groups does not imply atomicity if the process crashes.
`/ai stop` имеет два независимых действия: ACP-отмена хода модели и серверный флаг отмены операции. Остановка модели сама по себе не отменяет уже запущенную запись. Плагин проверяет флаг перед каждой порцией; выполненные изменения остаются в истории. Потеря Bridge запрещает запуск новых порций после короткого таймаута соединения; выполненная порция не повторяется вслепую.
`/ai stop` has two independent effects: ACP cancellation of the model turn and a server-side operation cancellation flag. Stopping the model alone does not cancel an already running write. The plugin checks the flag before each slice; completed changes remain in history. Losing the Bridge prevents new slices after a short connection timeout; a completed slice is not replayed blindly.
Все изменяющие запросы имеют idempotency key, связанный с проектом и хешем содержимого. Повтор с тем же ключом и тем же планом возвращает существующую операцию; тот же ключ с другим содержимым отклоняется. Повтор после сетевого таймаута начинается с запроса состояния операции.
All mutating requests have an idempotency key bound to the project and content hash. A retry with the same key and plan returns the existing operation; the same key with different content is rejected. Retrying after a network timeout starts with an operation-status request.
После сбоя плагин обнаруживает незавершённые группы и переходит в `recovery_required`. Сохранение файлов мира и журнала не является одной общей транзакцией. Поэтому при запуске выполняется сверка живого мира с `before/after`: старое значение, новое значение либо постороннее состояние. Ни неизвестное состояние, ни неоднозначная история не перезаписываются автоматически. Возобновление или отмена строятся как новый проверенный план; запись блоков по одному лишь последнему статусу журнала запрещена.
After a crash, the plugin detects unfinished groups and enters `recovery_required`. World-file persistence and journal persistence do not form a single shared transaction. Startup therefore compares the live world with `before/after`: the old value, the new value, or an unrelated state. Neither unknown states nor ambiguous history are overwritten automatically. Resumption or undo is constructed as a new validated plan; writing blocks based solely on the journal's last status is prohibited.
Отмена создаёт обратную операцию только для фактически записанных нами блоков. Она возвращает `before`, если текущее состояние совпадает с подтверждённым `after` и нет известной более поздней записи другого действия. Для известного последующего изменения возвращается конфликт, даже если итоговое значение случайно совпало. Для неизвестных внешних действий остаётся ограничение проверки по содержимому из раздела 10.
Undo creates a reverse operation only for blocks we actually wrote. It restores `before` if the current state matches the confirmed `after` and there is no known later write by another action. A known subsequent change produces a conflict even if its final value happens to match. Unknown external actions remain subject to the content-check limitation in section 10.
Производные эффекты — течение воды, падение песка, изменения инвентарей, рост растений, обновления редстоуна — не восстанавливаются простым обратным списком блоков. В v0.1 такие сценарии исключены из гарантируемой строительной области. Журнал не заменяет резервную копию мира. Поддержка полноценной симуляции побочных эффектов потребует отдельного дизайна.
Secondary effects — flowing water, falling sand, inventory changes, plant growth, and redstone updates — cannot be restored with a simple reverse block list. v0.1 excludes these scenarios from the guaranteed building area. The journal does not replace a world backup. Full simulation of side effects requires a separate design.
Проверка учитывает поддерживаемое окружение, а не только заменяемые блоки: удаление камня под песком или рядом с водой тоже может запустить побочный эффект. Для первой версии используется контролируемая строительная область; обнаруженное неподдерживаемое окружение останавливает подготовку. Абсолютная изоляция от произвольных плагинов и физики соседнего мира не обещается.
Validation considers supported surroundings, not just replaced blocks: removing stone beneath sand or beside water can also trigger side effects. The first version uses a controlled building area; detected unsupported surroundings stop preparation. Absolute isolation from arbitrary plugins and neighboring-world physics is not promised.
## 12. Экономия контекста
## 12. Context economy
Модель получает сведения, необходимые для решения. Полные снимки, списки блоков, история и вычисление разницы находятся на стороне системы. Неизменённые данные не отправляются заново без причины.
The model receives the information needed for its decision. Full snapshots, block lists, history, and difference computation remain on the system side. Unchanged data is not resent without a reason.
Уровни чтения:
Read levels:
1. Сводка проекта: назначение карты, палитра, области, части, активная задача, ограничения и последняя проверка.
2. Сводка участка: высоты поверхности с заданным шагом, материалы, занятые объёмы и ссылки на части. Неизвестные свойства отмечаются явно. Система не обещает автоматически распознавать здания в произвольном старом мире.
3. Изменения с курсора: количество блоков, затронутые части и ограничивающие объёмы; подробности доступны страницами.
4. Небольшой точный фрагмент: палитра состояний и сжатое представление координат либо срез. Распаковка миллионов блоков в текст не допускается.
5. Изображение нужного ракурса: сначала общий вид, затем детали проблемного участка.
1. Project summary: map purpose, palette, regions, parts, active task, constraints, and latest validation.
2. Region summary: surface heights at a specified sampling interval, materials, occupied volumes, and part references. Unknown properties are explicitly marked. The system does not promise automatic building recognition in an arbitrary existing world.
3. Changes since a cursor: block count, affected parts, and bounding volumes; details are paginated.
4. A small exact fragment: a state palette and compressed coordinates, or a slice. Expanding millions of blocks into text is not allowed.
5. An image from the required viewpoint: start with an overview, then inspect details of the problem area.
Сводка о правке формируется детерминированно: например, «34 блока изменены, 6 пересекаются с планом». Формулировка «игрок добавил окно» возможна только как вывод модели или подтверждённая метка, а не как достоверный результат простого diff.
Edit summaries are generated deterministically: for example, “34 blocks changed; 6 intersect the plan.” A statement such as “the player added a window” is valid only as a model inference or a confirmed label, not as an authoritative result of a simple diff.
Курсоры изменений включают world epoch, область, позицию журнала и версию схемы. После очистки журнала, потери наблюдения или замены мира ответ — `resync_required`, а не пустой список изменений. Bridge запрашивает новую локальную сводку. Сторонние изменения, не попавшие в события, ищутся повторной проверкой выбранных секций; дельты не объявляются полным журналом всего сервера.
Change cursors include the world epoch, region, journal position, and schema version. After journal cleanup, an observation gap, or world replacement, the response is `resync_required`, not an empty change list. The Bridge requests a new local summary. Third-party changes absent from events are sought by rechecking selected sections; deltas are not presented as a complete journal of the entire server.
Обычный ответ инструмента стремится укладываться в 2–4 тысячи токенов; точные ограничения задаются также числом элементов и байтов. При превышении возвращаются счётчик, курсор и признак усечения. Сжатые бинарные блоки и base64-изображения не вставляются в текст: снимок возвращается как изображение MCP, крупные данные остаются артефактами с ID.
An ordinary tool response targets 2–4 thousand tokens; exact limits also constrain item counts and bytes. If exceeded, the response returns a count, cursor, and truncation flag. Compressed binary blocks and base64 images are not inserted into text: a capture is returned as an MCP image, while large data remains in artifacts referenced by ID.
Начальный бюджет одной визуальной проверки — 2 общих ракурса, при необходимости до 4 дополнительных. Серии кадров не отправляются постоянно. Начальный лимит самостоятельных циклов исправления — 3; это настраиваемая политика, а не ограничение возможностей модели.
The initial budget for one visual check is 2 overview viewpoints, with up to 4 additional viewpoints if needed. Frame sequences are not sent continuously. The initial limit on autonomous correction cycles is 3; this is a configurable policy, not a limit on the model's capabilities.
Нельзя обещать фиксированную цену задачи: она зависит от модели, тарифа, истории, числа изображений и повторов. Bridge учитывает фактически доступные сведения об использовании и размеры ответов. Процент экономии относительно передачи всего мира нужно измерить на тестовых задачах.
A fixed task price cannot be promised: it depends on the model, pricing plan, history, image count, and retries. The Bridge records actually available usage information and response sizes. Savings compared with sending the entire world must be measured on test tasks.
## 13. Виртуальные камеры
## 13. Virtual cameras
Камера — сохранённый ракурс, а не обязательная сущность или блок в мире. Один Camera Worker последовательно обслуживает несколько ракурсов. Одновременные независимые виды не входят в v0.1.
A camera is a saved viewpoint, not necessarily an entity or block in the world. One Camera Worker serves multiple viewpoints sequentially. Simultaneous independent views are outside v0.1.
Для съёмки клиент наблюдателя перемещается к нужному месту, чтобы сервер прислал соответствующие чанки. Недостаточно сместить только матрицу камеры далеко от игрока: клиент может не иметь данных окружающего мира. Перемещение ограничено разрешёнными областями и измерениями; учётная запись камеры не получает права редактирования.
For capture, the observer client moves to the required location so the server sends the corresponding chunks. Moving only the camera matrix far from the player is insufficient: the client may not have the surrounding world data. Movement is limited to permitted regions and dimensions; the camera account receives no editing permissions.
Процедура съёмки:
Capture procedure:
1. Дождаться подтверждения завершения нужной операции на сервере.
2. Установить мир, позицию, ориентацию, FOV и профиль отображения.
3. Дождаться клиентской загрузки обязательных чанков и доступных сигналов завершения перестройки геометрии, затем нескольких кадров стабилизации.
4. Снять кадр без HUD и посторонних интерфейсов, вернуть изображение и метаданные.
5. Проверить, не менялась ли наблюдаемая область во время съёмки. При обнаруженных изменениях пометить изображение как потенциально устаревшее и предложить повтор.
1. Wait for confirmation that the required server operation has completed.
2. Set the world, position, orientation, FOV, and display profile.
3. Wait for required client chunks to load and for available geometry-rebuild completion signals, followed by several stabilization frames.
4. Capture a frame without the HUD or unrelated interfaces, and return the image with metadata.
5. Check whether the observed area changed during capture. If changes are detected, mark the image as potentially stale and suggest a retry.
Подтверждение сервера ещё не означает, что клиент уже отобразил все изменения. Точный критерий готовности рендера нужно проверить прототипом на выбранной версии Fabric. При таймауте возвращается `capture_not_ready`; старый кадр не выдаётся за новый. Проверка ревизий не гарантирует отсутствия неотслеживаемых внешних изменений.
Server acknowledgement does not mean the client has already displayed all changes. The exact render-readiness criterion must be tested in a prototype on the selected Fabric version. A timeout returns `capture_not_ready`; an old frame is not presented as new. Revision checks do not guarantee the absence of untracked external changes.
Начальный профиль — стандартный ресурспак, без шейдеров, одинаковые FOV и разрешение для сравнения. Время суток и погода фиксируются только явно выбранным режимом проверки; ради красивого скриншота глобальный мир самовольно не меняется. Ракурсы внутри помещений проверяются на попадание камеры в непрозрачный блок.
The initial profile uses the standard resource pack, no shaders, and consistent FOV and resolution for comparisons. Time of day and weather are fixed only in an explicitly selected validation mode; the global world is not changed without authorization for the sake of a pretty screenshot. Interior viewpoints are checked for the camera being inside an opaque block.
Автоматический обзор предлагает вход, противоположную сторону, диагональ сверху и заданные внутренние точки. Положение рассчитывается по границам части и уточняется по препятствиям. Пользователь может сохранить свои ракурсы. Пиксельное различие снимков не является метрикой красоты: его используют только как вспомогательный сигнал.
Automatic inspection proposes the entrance, the opposite side, an elevated diagonal view, and specified interior points. Positions are calculated from part bounds and adjusted for obstacles. Users can save their own viewpoints. Pixel differences between captures are not an aesthetic metric; they serve only as an auxiliary signal.
Клиент требует графического рендеринга. Запуск без видимого окна не означает отсутствие GPU/графического контекста и не обещается до проверки. Работа рендера в Fabric меняется между версиями, поэтому мод камеры изолируется от остальных компонентов. [Рендеринг Fabric](https://docs.fabricmc.net/develop/rendering/basic-concepts).
The client requires graphical rendering. Running without a visible window does not mean no GPU/graphics context is needed, and is not promised before testing. Fabric rendering changes between versions, so the camera mod is isolated from the other components. [Fabric rendering](https://docs.fabricmc.net/develop/rendering/basic-concepts).
## 14. Предлагаемые MCP-инструменты
## 14. Proposed MCP tools
Ниже — контракт проекта, а не перечень уже реализованных функций. Каталог разделяется на чтение, подготовку и изменение. Полномочия связаны с подключением, проектом и инициатором; передача `project_id` сама по себе не даёт доступа.
The following is the project's contract, not a list of already implemented functions. The catalog separates reading, preparation, and mutation. Permissions are bound to the connection, project, and initiator; supplying `project_id` alone does not grant access.
- `project_context(project_id)` — возможности, версия мира, область, части, ограничения и состояние операций.
- `region_inspect(region, detail, cursor?)` — сводка, высотная карта, срез или небольшой набор точных блоков.
- `region_changes(region, since_cursor, limit)` — дельта, полнота наблюдения и следующий курсор.
- `part_get(part_id)` — маска, параметры, защита, версия и сведения о внешних изменениях.
- `part_define(region_or_mask, name, parent_id?)` — зарегистрировать часть без изменения блоков; проверить права и пересечения.
- `build_prepare(target, recipe_or_patch, base_snapshot_id?, request_id)` — сохранить неизменяемый план; вернуть его ID, хеш, статистику и конфликты.
- `build_apply(plan_id, plan_hash, idempotency_key)` — проверить разрешение и поставить план в очередь; вернуть operation ID.
- `operation_status(operation_id, since_cursor?)` — прогресс, частичный результат, ошибки и ссылки на конфликты.
- `operation_cancel(operation_id, idempotency_key)` — остановить дальнейшее применение.
- `operation_undo_prepare(operation_id, request_id)` — создать обратный план со свежими проверками; применять через `build_apply`.
- `camera_list(project_id)` — доступные ракурсы и состояние Camera Worker.
- `camera_capture(camera_id_or_pose, after_operation_id?, profile)` — изображение с метаданными или ID ожидающего задания.
- `asset_list(query, cursor?)` — локальные схематики, размеры, палитры, версии и превью.
- `schematic_export(target, name)` — экспорт в разрешённое хранилище, возвращает artifact ID.
- `schematic_import_prepare(asset_id, transform, target)` — проверить файл и создать план вставки.
- `project_context(project_id)` — capabilities, world version, region, parts, limits, and operation status.
- `region_inspect(region, detail, cursor?)` — a summary, heightmap, slice, or small set of exact blocks.
- `region_changes(region, since_cursor, limit)` — a delta, observation completeness, and the next cursor.
- `part_get(part_id)` — mask, parameters, protection, version, and external-change information.
- `part_define(region_or_mask, name, parent_id?)` — register a part without modifying blocks; check permissions and intersections.
- `build_prepare(target, recipe_or_patch, base_snapshot_id?, request_id)` — persist an immutable plan; return its ID, hash, statistics, and conflicts.
- `build_apply(plan_id, plan_hash, idempotency_key)` — check authorization and queue the plan; return an operation ID.
- `operation_status(operation_id, since_cursor?)` — progress, partial result, errors, and conflict references.
- `operation_cancel(operation_id, idempotency_key)` — stop further application.
- `operation_undo_prepare(operation_id, request_id)` — create a reverse plan with fresh checks; apply through `build_apply`.
- `camera_list(project_id)` — available viewpoints and Camera Worker status.
- `camera_capture(camera_id_or_pose, after_operation_id?, profile)` — an image with metadata or a pending job ID.
- `asset_list(query, cursor?)` — local schematics, dimensions, palettes, versions, and previews.
- `schematic_export(target, name)` — export to permitted storage and return an artifact ID.
- `schematic_import_prepare(asset_id, transform, target)` — validate the file and create a paste plan.
Создание проекта, расширение разрешённой области, выдача прав и снятие защиты относятся к пользовательскому/административному управлению. Агент не может сам расширить свои полномочия вызовом инструмента.
Creating projects, expanding permitted areas, granting permissions, and removing protection belong to user/administrator controls. The agent cannot expand its own authority by calling a tool.
Общий ответ содержит `schema_version`, `request_id`, `status`, идентификатор мира/epoch, краткую сводку, `warnings`, `truncated` и курсор при необходимости. Чтение указывает момент и полноту наблюдения; изменение всегда возвращает operation ID. Большая операция асинхронна и не должна требовать одного MCP-вызова, открытого на всё время строительства.
The common response contains `schema_version`, `request_id`, `status`, a world identifier/epoch, a brief summary, `warnings`, `truncated`, and a cursor when needed. Reads specify observation time and completeness; mutations always return an operation ID. Large operations are asynchronous and must not require a single MCP call to remain open throughout construction.
Структурированные ошибки: `permission_denied`, `out_of_bounds`, `unsupported_block`, `stale_snapshot`, `conflict`, `budget_exceeded`, `busy`, `resync_required`, `camera_unavailable`, `capture_not_ready`, `version_mismatch`, `recovery_required`. Ошибка указывает возможность повтора; повтор изменяющего запроса соблюдает idempotency.
Structured errors: `permission_denied`, `out_of_bounds`, `unsupported_block`, `stale_snapshot`, `conflict`, `budget_exceeded`, `busy`, `resync_required`, `camera_unavailable`, `capture_not_ready`, `version_mismatch`, `recovery_required`. Errors indicate whether retry is possible; retries of mutating requests preserve idempotency.
Минимальный протокол между Bridge и плагином версионируется отдельно от MCP/ACP. Каждый запрос содержит correlation ID; команды выполняются от проверенного принципала с ограниченными возможностями, а не от имени произвольного UUID из тела запроса. Ключи и токены не попадают в видимые модели ответы.
The minimal protocol between the Bridge and plugin is versioned separately from MCP/ACP. Every request contains a correlation ID; commands run as a verified principal with limited capabilities, not as an arbitrary UUID taken from the request body. Keys and tokens do not appear in responses visible to the model.
## 15. Хранение, импорт и перенос
## 15. Storage, import, and transfer
Планируемая структура репозитория: `bridge/`, `paper-plugin/`, `camera-mod/`, `protocol/`, `fixtures/`, `docs/`. В этом документе она описана как будущая; исходный код ещё не создан.
Planned repository structure: `bridge/`, `paper-plugin/`, `camera-mod/`, `protocol/`, `fixtures/`, `docs/`. This document describes it as a future structure; source code has not yet been created.
Постоянные данные хранятся вне исходного кода и вне игровых блоков:
Persistent data is stored outside the source tree and separately from game blocks:
- На сервере: проекты, области, части, планы, журнал, снимки, рецепты, версии схемы и настройки доступа.
- У Bridge: связь диалогов с проектами, локальная сводка, состояние подключений.
- У камеры: ракурсы, профили и изображения с ID операций.
- В библиотеке: `.schem`, превью и метаданные происхождения, версии, размеров, точки привязки и лицензии.
- On the server: projects, regions, parts, plans, journal, snapshots, recipes, schema versions, and access settings.
- In the Bridge: conversation-to-project mappings, local summary, and connection state.
- At the camera: viewpoints, profiles, and images with operation IDs.
- In the library: `.schem` files, previews, and metadata for provenance, version, dimensions, anchor, and license.
Потеря Bridge не теряет историю блоков. Потеря базы плагина не удаляет постройки, но лишает систему достоверных рецептов и отмены. Отсутствие базы не даёт права повторно проиграть старые планы.
Losing the Bridge does not lose block history. Losing the plugin database does not delete buildings, but it deprives the system of reliable recipes and undo. A missing database does not authorize replaying old plans.
Очистка журнала сохраняет данные активных операций, восстановления и явно закреплённых контрольных точек. Истёкшая история делает соответствующую отмену недоступной; об этом сообщается прямо. Квота диска проверяется до начала записи, а при невозможности сохранить журнал новые изменения останавливаются. Конкретные сроки хранения выбираются после измерения объёма.
Journal cleanup preserves data for active operations, recovery, and explicitly pinned checkpoints. Expired history makes the corresponding undo unavailable; this is reported clearly. Disk quota is checked before writing starts, and new changes stop if the journal cannot be saved. Specific retention periods are chosen after measuring storage volume.
Импорт работает с локальным asset ID, не с произвольным путём или URL модели. Проверяются формат, распакованный объём, число блоков, версия, разрешённые состояния и данные block entities/сущностей. Неподдерживаемое содержимое отклоняется с отчётом, а не молча теряется. Схематика сначала превращается в план и проходит тот же путь конфликтов, что обычное строительство. Форматы загрузки и сохранения предоставляет [WorldEdit Clipboard](https://worldedit.enginehub.org/en/latest/usage/clipboard/).
Import uses a local asset ID, not an arbitrary path or URL supplied by the model. Validation covers format, decompressed size, block count, version, permitted states, and block-entity/entity data. Unsupported content is rejected with a report rather than silently lost. A schematic is first converted into a plan and follows the same conflict-handling path as ordinary construction. Loading and saving formats are provided by [WorldEdit Clipboard](https://worldedit.enginehub.org/en/latest/usage/clipboard/).
Для переноса здания экспортируется `.schem`; для переноса карты сохраняется согласованная резервная копия мира и проверяются измерения и настройки. Метаданные редактора можно приложить отдельным архивом. Перенос на другую серверную основу проверяется на копии и той же версии Minecraft; обратная совместимость со старыми версиями не обещается. Раскладка измерений зависит от серверной основы. [Миграция Paper](https://docs.papermc.io/paper/migration/).
To transfer a building, export `.schem`; to transfer a map, save a consistent world backup and check dimensions and settings. Editor metadata may be attached as a separate archive. Migration to another server implementation is tested on a copy using the same Minecraft version; backward compatibility with older versions is not promised. Dimension layout depends on the server implementation. [Paper migration](https://docs.papermc.io/paper/migration/).
## 16. Полномочия и эксплуатационные ограничения
## 16. Permissions and operational limits
Агент получает доступ только к выбранной строительной области и разрешённому набору инструментов. По умолчанию нет серверной консоли, выдачи OP, изменения плагинов, управления аккаунтами, внешней сети и чтения произвольных файлов через Minecraft MCP.
The agent receives access only to the selected building area and permitted tools. By default, Minecraft MCP provides no server console, OP grants, plugin changes, account management, external networking, or arbitrary file reads.
Codex запускается в отдельном рабочем каталоге с минимальными правами. Его собственные shell/file-инструменты не должны обходить серверные ограничения или читать секреты Bridge. Конкретный механизм изоляции процесса и доступные режимы закреплённого Codex проверяются в первом прототипе. Подключение MCP само по себе не ограничивает остальные инструменты агента.
Codex runs in a separate working directory with minimal permissions. Its own shell/file tools must not bypass server limits or read Bridge secrets. The specific process-isolation mechanism and available modes of the pinned Codex version are checked in the first prototype. Connecting MCP does not by itself restrict the agent's other tools.
Если Codex/ACP требует разрешение, Bridge связывает запрос с реальным инициатором и показывает конкретное действие. Чужое сообщение в чате не считается разрешением. Отмена и истечение срока закрывают ожидающий запрос. Обычная запись в заранее разрешённой области не должна порождать лишние подтверждения, но это не отменяет ограничения профиля Codex.
If Codex/ACP requires permission, the Bridge binds the request to the actual initiator and shows the specific action. Another person's chat message is not permission. Cancellation and expiry close a pending request. Ordinary writes inside a preauthorized area should not generate unnecessary confirmations, but this does not override the Codex profile's restrictions.
Текст табличек, названия предметов, импортированные метаданные и чужие сообщения рассматриваются как данные мира. Они не могут менять полномочия, системные инструкции или назначение проекта.
Sign text, item names, imported metadata, and other people's messages are treated as world data. They cannot change permissions, system instructions, or the project's purpose.
Один серверный план проверяет права и при подготовке, и перед исполнением порций. Отзыв доступа, изменение области или world epoch прекращает дальнейшую запись. При занятости участок ставится в очередь либо возвращает `busy`; скрытой конкуренции между нашими писателями нет.
A server plan checks permissions both during preparation and before slices execute. Revoking access or changing the region or world epoch stops further writing. A busy region is queued or returns `busy`; there is no hidden concurrency between our writers.
## 17. Первоначальные бюджеты и наблюдаемость
## 17. Initial budgets and observability
Следующие числа — стартовые настройки прототипа, а не измеренные показатели производительности:
The following numbers are initial prototype settings, not measured performance figures:
- До 100 000 изменяемых блоков в одном плане; более крупная стройка делится на осмысленные части.
- До 2 000 000 исследуемых позиций в одной операции подготовки; большая область требует грубого обзора и последующего уточнения.
- Порция записи — не более 512 блоков и целевой предел 5 мс работы нашего исполнителя на тик. Проверка времени идёт между маленькими логическими группами; одна дорогая операция API может превысить цель.
- При перегрузке или росте времени тика размер порции уменьшается, новые порции приостанавливаются. Скорость «блоков в секунду» не фиксируется до замеров.
- Точный текстовый ответ — до 4 096 блоков; страница событий — до 100 элементов; превышение обрабатывается усечением с курсором, а не скрытой потерей данных.
- Кадр по умолчанию — 1280×720; таймаут готовности 20 секунд; не более одной активной съёмки на Worker.
- План действует 10 минут, но проверяется перед применением независимо от возраста. По истечении строится новый план.
- Сигнал остановки принимается сразу; целевой срок прекращения новых порций — до 1 секунды при здоровом сервере и соединении. При зависшем игровом потоке это не гарантия реального времени.
- Up to 100 000 changed blocks in one plan; larger builds are divided into meaningful parts.
- Up to 2 000 000 inspected positions in one preparation operation; larger regions require a coarse overview followed by refinement.
- A write slice contains at most 512 blocks, with a target of 5 ms of executor work per tick. Time is checked between small logical groups; a single expensive API operation may exceed the target.
- Under overload or increasing tick time, slice size is reduced and new slices are paused. A blocks-per-second rate is not fixed before measurement.
- Exact textual responses contain up to 4 096 blocks; event pages up to 100 entries. Excess data is handled through truncation with a cursor, not silent loss.
- Default frame size is 1280×720; readiness timeout is 20 seconds; at most one active capture per Worker.
- A plan expires after 10 minutes, but is checked before application regardless of age. A new plan is created after expiry.
- A stop signal is accepted immediately; the target for stopping new slices is within 1 second with a healthy server and connection. This is not a real-time guarantee when the game thread is hung.
Измеряются длительности подготовки и порций, время тика с задачей и без неё, объём журнала, размер ответов модели, число снимков и повторов, конфликты, отставание камеры и время остановки. Корреляция строится по project/request/operation/capture ID.
Measurements include preparation and slice durations, tick time with and without the task, journal volume, model-response size, capture and retry counts, conflicts, camera lag, and stopping time. Correlation uses project/request/operation/capture IDs.
Токены и стоимость отображаются только по доступным фактическим данным провайдера; отсутствие данных не равно нулю. Не сохраняются скрытые рассуждения модели. Диагностические логи не содержат секретов и по умолчанию не копируют полный игровой чат.
Tokens and cost are displayed only from actual available provider data; missing data is not zero. Hidden model reasoning is not stored. Diagnostic logs contain no secrets and do not copy the full in-game chat by default.
## 18. Этапы реализации и критерии готовности
## 18. Implementation stages and readiness criteria
### Этап 0 — проверка совместимости
### Stage 0 — compatibility validation
Поднять тестовый мир на копии, закрепить версии, проверить ACP-сессию через `codex-acp`, вызов простого MCP-чтения и получение моделью одного изображения. Проверить подключение камеры к Paper, допустимую отдельную сессию наблюдателя и изоляцию Codex.
Start a test world on a copy, pin versions, and test an ACP session through `codex-acp`, a simple MCP read, and delivery of one image to the model. Check the camera connection to Paper, a permitted separate observer session, and Codex isolation.
Готовность: сообщение из игры доходит до агента; агент получает данные тестового блока и свежий снимок; версии и ограничения записаны. При отсутствии совместимого мода/WorldEdit пересматривается версия платформы до начала строительства реальной карты.
Ready when: an in-game message reaches the agent; the agent receives test-block data and a fresh capture; versions and limitations are documented. If a compatible mod/WorldEdit is unavailable, reconsider the platform version before starting construction of the real map.
### Этап 1 — безопасная запись без агента
### Stage 1 — safe writing without an agent
Реализовать области, канонические состояния, подготовку плана, порции, idempotency, журнал, конфликт, отмену и восстановление. Проверять прямым тестовым клиентом: работа базового движка не зависит от качества ответов модели.
Implement regions, canonical states, plan preparation, slices, idempotency, journal, conflicts, undo, and recovery. Test with a direct test client: the core engine's operation does not depend on the quality of model responses.
Готовность: сервер сохраняет ручную правку между подготовкой и применением; повтор запроса не дублирует работу; отмена не перезаписывает более позднюю правку; остановка и перезапуск дают честное состояние частичного результата.
Ready when: the server preserves a manual edit made between preparation and application; retrying a request does not duplicate work; undo does not overwrite a later edit; stopping and restarting report the partial result accurately.
### Этап 2 — строительный API и чат
### Stage 2 — building API and chat
Добавить примитивы, палитры, повторения, части, MCP-инструменты, очередь ACP и компактные сводки. Строительство маленького здания должно требовать геометрической программы, а не списка отдельных вызовов установки блоков.
Add primitives, palettes, repetition, parts, MCP tools, an ACP queue, and compact summaries. Building a small structure should require a geometry program rather than a list of individual block-placement calls.
Готовность: из чата создаётся башня с именованной крышей; правка крыши оставляет стену и вручную добавленное окно; конфликт лестницы с ручным окном возвращает точное пересечение.
Ready when: chat creates a tower with a named roof; editing the roof preserves the wall and a manually added window; a conflict between stairs and a manual window returns the exact intersection.
### Этап 3 — визуальный цикл
### Stage 3 — visual feedback loop
Добавить сохранённые камеры, готовность чанков/рендера, метаданные свежести и связку кадров с операциями. Агент выполняет ограниченное число осмысленных правок по снимкам.
Add saved cameras, chunk/render readiness, freshness metadata, and capture-to-operation links. The agent makes a bounded number of meaningful corrections based on captures.
Готовность: повторный кадр показывает завершённую правку; незагруженная сцена выдаёт ошибку; пользовательский вид при работе отдельной камеры не переключается. Визуально плохой результат может быть признан плохим, даже если техническая запись успешна.
Ready when: a subsequent frame shows the completed edit; an unloaded scene returns an error; the user's view does not switch when a separate camera is operating. A visually poor result can be acknowledged as poor even when the technical write succeeds.
### Этап 4 — перенос и выпуск v0.1
### Stage 4 — transfer and v0.1 release
Добавить `.schem`, локальную библиотеку, копирование проекта и процедуру резервирования. Проверить работу без компонентов редактора на копии мира.
Add `.schem`, a local library, project copying, and a backup procedure. Test a world copy without the editor components.
Готовность: эталонная постройка проходит экспорт/импорт с совпадением поддерживаемых состояний и ориентаций; неподдерживаемые данные не теряются молча; инструкция запуска воспроизводима на чистом окружении.
Ready when: a reference build survives export/import with matching supported states and orientations; unsupported data is not silently lost; startup instructions are reproducible in a clean environment.
## 19. Приёмочные сценарии
## 19. Acceptance scenarios
1. **Ручная правка после подготовки.** Изменить блок из write set перед применением. Ожидается конфликт и сохранение ручного значения.
2. **Правка между порциями.** Изменить ещё не записанную часть. Ожидается остановка на пересечении и точный отчёт об уже выполненной работе.
3. **Изменение опоры.** Удалить блок из read set, не входящий в write set. Ожидается перепланирование, а не установка зависящей от него конструкции.
4. **Отмена после ручного изменения.** Изменить блок после строительства и выполнить undo. Ожидается конфликт для этого блока; нет слепого возврата снимка всей области.
5. **Повтор запроса.** Повторить `build_apply` после таймаута. Ожидается тот же operation ID и отсутствие повторной записи.
6. **Падение процесса.** Прерывать сервер до/после сохранения намерения, в середине записи и до отметки завершения. Ожидается `recovery_required`, сверка и отсутствие автоматического уничтожения посторонних состояний.
7. **Потеря журнала изменений.** Запросить дельту устаревшим курсором. Ожидается `resync_required` и новая сводка.
8. **Внешний редактор.** Изменить блок через WorldEdit и через путь без ожидаемого события. Ожидается обнаружение реального расхождения перед нашей записью; источник может быть неизвестен.
9. **Состояния блоков.** Повернуть схему со ступенями, плитами и брёвнами. Ожидаются правильные направления и сохранение состояний после экспорта.
10. **Неподдерживаемые данные.** Попытаться заменить сундук, вставить сущность или импортировать слишком большой файл. Ожидается отказ до записи.
11. **Границы и права.** Выдать план за областью, подменить project ID, отозвать доступ во время записи. Ожидается серверный отказ или прекращение следующих порций.
12. **Камера.** Снимать до загрузки, после изменения и после разрыва связи. Ожидаются достоверные статусы готовности; старое изображение не помечается новым.
13. **Нагрузка.** Применить 10 000 и 100 000 блоков, записать оборудование, версии, настройки и влияние на время тика. Настроить порции по измерениям.
14. **Контекст.** Сравнить малый и большой планы одной формы. Объём обычного ответа модели ограничен сводкой; полный diff остаётся на сервере.
15. **Перенос.** Открыть копию мира без нашего плагина и камеры. Постройка остаётся; потеря функций редактора не меняет блоки.
1. **Manual edit after preparation.** Change a block in the write set before application. Expect a conflict and preservation of the manual value.
2. **Edit between slices.** Change a part that has not yet been written. Expect a stop at the intersection and an exact report of completed work.
3. **Support change.** Remove a block from the read set that is not in the write set. Expect replanning rather than placing a structure that depends on it.
4. **Undo after a manual edit.** Change a block after construction and perform undo. Expect a conflict for that block, not a blind restoration of the entire region snapshot.
5. **Request retry.** Repeat `build_apply` after a timeout. Expect the same operation ID and no repeated write.
6. **Process crash.** Interrupt the server before/after intent persistence, during writing, and before completion is recorded. Expect `recovery_required`, reconciliation, and no automatic destruction of unrelated states.
7. **Lost change journal.** Request a delta with a stale cursor. Expect `resync_required` and a new summary.
8. **External editor.** Change a block through WorldEdit and through a path without the expected event. Expect detection of the actual divergence before our write; the source may be unknown.
9. **Block states.** Rotate a schematic containing stairs, slabs, and logs. Expect correct directions and preservation of states after export.
10. **Unsupported data.** Attempt to replace a chest, insert an entity, or import an oversized file. Expect rejection before writing.
11. **Bounds and permissions.** Submit an out-of-region plan, substitute a project ID, or revoke access during writing. Expect server-side rejection or stopping of subsequent slices.
12. **Camera.** Capture before loading, after a change, and after disconnection. Expect accurate readiness statuses; an old image must not be labeled new.
13. **Load.** Apply 10 000 and 100 000 blocks, recording hardware, versions, settings, and tick-time impact. Tune slices based on measurements.
14. **Context.** Compare small and large plans of the same shape. An ordinary response to the model is bounded by the summary; the full diff stays on the server.
15. **Transfer.** Open a world copy without our plugin and camera. The building remains; losing editor functions does not modify blocks.
Алгоритмы разницы, ограничений, преобразований и idempotency проверяются модульно; потоки, физика, журнал и камера — на настоящем тестовом сервере/клиенте. Моки не доказывают корректность поведения Minecraft. Эти проверки запланированы, но ещё не выполнены.
Difference, constraint, transformation, and idempotency algorithms are unit-tested; threading, physics, journal, and camera behavior are tested on a real test server/client. Mocks do not prove Minecraft behavior correct. These checks are planned but have not yet been performed.
## 20. Что заимствуем из Blender MCP
## 20. What we borrow from Blender MCP
Из [Blender MCP](https://github.com/ahujasid/blender-mcp) берём сочетание осмотра сцены, работы с именованными объектами, компактного программного построения, изображений и библиотеки ассетов. В Minecraft это превращается в осмотр региона, маски частей, геометрический язык, камеры и `.schem`.
From [Blender MCP](https://github.com/ahujasid/blender-mcp), we borrow the combination of scene inspection, named objects, compact programmatic construction, images, and an asset library. In Minecraft, these become region inspection, part masks, a geometry language, cameras, and `.schem`.
Собственные дополнения проекта: согласование с ручными правками, серверные порции, журнал до записи, восстановление после сбоя, курсоры дельт и проверка поддерживаемых состояний. Наличие этих функций у Blender MCP не утверждается. Произвольное выполнение Python и сторонние сервисы генерации 3D не копируются в первую версию.
The project's own additions are reconciliation with manual edits, server-side slices, a journal persisted before writing, crash recovery, delta cursors, and supported-state validation. We do not claim that Blender MCP provides these features. Arbitrary Python execution and third-party 3D generation services are not copied into the first version.
## 21. Открытые вопросы и последующие версии
## 21. Open questions and later versions
Вопросы не блокируют завершение этого документа; они определяют работы этапа 0 и решения перед соответствующей функцией:
These questions do not block completion of this document; they define stage 0 work and decisions required before the relevant feature:
- Какие точные версии WorldEdit и Fabric совместимы с выбранной веткой 26.2? Если нет общей рабочей комбинации, какую поддерживаемую версию выбрать до строительства карты?
- Где запускается камера и есть ли отдельная игровая сессия для неё? Рабочий вариант — отдельный локальный клиент; запасной — камера в клиенте пользователя.
- Можно ли получить надёжный сигнал готовности геометрии на выбранной версии клиента? Если нет, какой проверяемый критерий свежести достаточен и какие ограничения показывать?
- Использовать ли WorldEdit для фактической записи либо только для форматов и выделений? Решение определяется контролем момента записи, побочных эффектов и времени порции.
- Какие блоки и соседние обновления проходят тесты гарантированной отмены? Расширение списка требует тестов, а не только добавления ID.
- Какое оборудование и размер проектов считать целевыми? До замеров значения раздела 17 остаются бюджетами прототипа.
- Which exact WorldEdit and Fabric versions are compatible with the selected 26.2 branch? If there is no working combination, which supported version should be selected before map construction begins?
- Where does the camera run, and is a separate game session available for it? The working option is a separate local client; the fallback is a camera in the user's client.
- Can the selected client version provide a reliable geometry-readiness signal? If not, what verifiable freshness criterion is sufficient, and which limitations should be shown?
- Should WorldEdit perform actual writes or only provide formats and selections? The decision depends on control over write timing, side effects, and slice duration.
- Which blocks and neighboring updates pass tests for guaranteed undo? Extending the list requires tests, not just adding IDs.
- What hardware and project sizes should be targeted? Until measurements are available, the values in section 17 remain prototype budgets.
v0.2 может добавить трёхстороннее объединение рецептов с ручными поправками, составные блоки, проверку проходов и маршрутов, библиотеку параметрических деталей и более удобное сравнение ракурсов. Для неизвестных построек возможна ручная регистрация частей, позже — предложенная моделью сегментация с проверкой.
v0.2 may add three-way merging of recipes with manual edits, multipart blocks, passage and route validation, a library of parametric details, and more convenient viewpoint comparisons. Unknown buildings can support manual part registration, followed later by model-proposed segmentation with validation.
Дальнейшие направления: Fabric-адаптер встроенного сервера для одиночной игры; командное строительство в независимых областях; несколько камер; инструменты проверки мини-игровых карт; изолированные строительные скрипты общего назначения. Они не должны задерживать проверку базового цикла «запрос → план → запись → наблюдение → правка».
Further directions: a Fabric adapter for the integrated single-player server; collaborative building in independent areas; multiple cameras; minigame-map validation tools; and isolated general-purpose building scripts. These must not delay validation of the basic request → plan → write → observe → edit loop.
## 22. Итоговые критерии проекта
## 22. Overall project criteria
Успех первой версии означает, что пользователь может построить и уточнить небольшое здание из игрового чата, агент видит результат, ручная правка не затирается молча, отмена имеет честные ограничения, контекст не заполняется полным миром, а карту можно использовать без редактора.
Success for the first version means that the user can build and refine a small structure through in-game chat, the agent can see the result, manual edits are not silently overwritten, undo has clearly stated limitations, context is not filled with the entire world, and the map can be used without the editor.
Этот документ фиксирует архитектуру и проверяемые требования. Он не подтверждает готовность прототипа, производительность, совместимость всех зависимостей или качество архитектурных решений модели.
This document records the architecture and testable requirements. It does not establish prototype readiness, performance, compatibility of all dependencies, or the quality of the model's architectural decisions.
+34 -34
View File
@@ -1,57 +1,57 @@
# Состояние реализации
# Implementation status
Первый прототип собран и проверен на настоящем локальном Paper 26.2, включая графический клиент камеры в Prism и передачу изображения через MCP. Он ещё не закрывает всю v0.1 из [дизайна](DESIGN.md): первый авторизованный ход Codex через ACP остаётся непроверенным.
The first prototype has been built and tested on a real local Paper 26.2 server, including the graphical camera client in Prism and image delivery through MCP. It does not yet cover all of v0.1 in the [design](DESIGN.md): the first authenticated Codex turn over ACP remains untested.
## Реализованные компоненты
## Implemented components
`world-core` содержит независимый от Bukkit редактор. Декларативный рецепт превращается в неизменяемый план с исходными и желаемыми состояниями, явными зависимостями чтения и сроком действия. Перед записью выполняется проверка; непосредственно при записи состояния сверяются повторно. Дисковые намерения сохраняются до изменения мира, результаты — после порции. Файловый ввод-вывод вынесен с серверного потока. Отмена останавливает следующие порции; уже записанное остаётся в истории.
`world-core` contains a Bukkit-independent editor. A declarative recipe becomes an immutable plan with original and desired states, explicit read dependencies, and an expiry time. Validation happens before writing; states are checked again at the point of each write. Disk intents are persisted before the world changes, and results after each slice. File I/O runs off the server thread. Cancellation stops subsequent slices; completed writes remain in history.
`paper-plugin` привязывает это ядро к серверному потоку, проверяет владельца, мир, эпоху, область и защищённые части. HTTP доступен только на loopback, с отдельными ключами администратора и агента. Плагин регистрирует `/ai`, хранит небольшую очередь чата, пересылает ответы только инициатору и управляет телепортацией наблюдателя. Журнал и метаданные находятся в каталоге плагина, игровые блоки остаются ванильными.
`paper-plugin` binds the core to the server thread and checks the owner, world, epoch, region, and protected parts. HTTP is available only on loopback, with separate administrator and agent keys. The plugin registers `/ai`, maintains a small chat queue, sends replies only to the initiator, and controls observer teleportation. The journal and metadata live in the plugin directory; game blocks remain vanilla.
`bridge` предоставляет 14 инструментов MCP по stdio, принимает события чата Paper и запускает закреплённый `codex-acp`. Диалоги разделены по игроку и проекту, очередь сериализована, остановка распространяется на ACP. Идентификатор сессии и компактная сводка сохраняются. Агент получает отдельный MCP-токен; ключ администратора остаётся у Bridge. Большие ответы ограничены, изображения передаются как MCP image content.
`bridge` exposes 14 MCP tools over stdio, accepts Paper chat events, and launches the pinned `codex-acp`. Conversations are separated by player and project, queues are serialized, and stopping propagates to ACP. The session ID and a compact summary are persisted. The agent receives a separate MCP token; the administrator key stays with the Bridge. Large responses are bounded, and images are delivered as MCP image content.
`camera-mod` содержит локальный HTTP Worker и захват framebuffer Minecraft 26.2. Камера ждёт spectator, нужную позицию и измерение, доступность соседних чанков и стабилизацию кадров. Настройки HUD/FOV восстанавливаются после снимка или ошибки. На настоящем клиенте Prism проверены Mixin, серверная телепортация и валидные PNG с нескольких ракурсов. Владелец и наблюдатель использовали один UUID.
`camera-mod` contains a local HTTP Worker and Minecraft 26.2 framebuffer capture. The camera waits for spectator mode, the requested position and dimension, neighboring chunk availability, and frame stabilization. HUD/FOV settings are restored after capture or failure. Mixin integration, server-side teleportation, and valid PNGs from several viewpoints have been tested in a real Prism client. The owner and observer used the same UUID.
## Подтверждённые проверки
## Verified checks
Текущая сборка: **100 автоматических тестов без ошибок** — 52 в ядре, 17 в Paper-модуле, 20 в Bridge и 11 в модуле камеры. Оба JAR собраны; результаты Java находятся в XML-отчётах Maven/Gradle, общий лог этой проверки — `.runtime/build-final.log`.
Current build: **100 automated tests passing** — 52 in the core, 17 in the Paper module, 20 in the Bridge, and 11 in the camera module. Both JARs have been built; Java results are in Maven/Gradle XML reports, and the combined log for this run is `.runtime/build-final.log`.
Автоматические Java-тесты проверяют геометрию, ограничения, идемпотентность, зависимости чтения, конфликты, прерывание порции, отмену, undo, журналирование, ошибки диска, восстановление и отдельные HTTP/NBT-контракты. Тесты Bridge используют настоящий MCP stdio и имитатор ACP для диалогов, разрешений, отмены и возобновления. Камера имеет проверки HTTP-аутентификации и валидации, без запуска графического клиента.
Automated Java tests cover geometry, limits, idempotency, read dependencies, conflicts, interrupted slices, cancellation, undo, journaling, disk failures, recovery, and individual HTTP/NBT contracts. Bridge tests use real MCP stdio and a mock ACP agent for conversations, permissions, cancellation, and resumption. Camera tests cover HTTP authentication and validation without launching a graphical client.
На настоящем Paper, в отдельном созданном тестовом мире, успешно выполнены:
The following scenarios passed on real Paper in a separately created test world:
- Изменение блока после подготовки плана: операция завершается конфликтом, чужой блок сохраняется.
- Изменение явной зависимости: применение останавливается до записи.
- Постройка, повтор с тем же ключом и проверяемая отмена; при более поздней внешней правке undo отвергается.
- Отмена операции, защита неподдерживаемого исходного блока и отказ за пределами области.
- Принудительное завершение собственного процесса сервера во время 4096-блочной операции, повторный запуск, `recovery_required` без автоматического воспроизведения.
- Административный разбор восстановления: агентскому ключу отказано, устаревший digest отвергнут, отказ от продолжения сохраняет текущее содержимое мира и разрешает новые операции после записи решения на диск. Защита части не мешает разбору, но продолжает запрещать запись в неё.
- Полый куб через настоящий MCP: 26 блоков; экспорт `.schem`, библиотека ассетов, undo, импорт на тот же anchor и повторный undo до 27 блоков воздуха.
- Отсутствующая камера возвращает ошибку, без подмены изображения.
- После установки мода в Prism построена 575-блочная башня и получены четыре реальных снимка 1280×720. Последний прошёл весь путь Camera → Paper → Bridge → MCP ImageContent. Первый запрос с изменившимся ракурсом завершился отказом; повтор при неподвижном клиенте успешен. [Протокол проверки](ONE_CLIENT_TEST.md).
- A block changed after plan preparation: the operation ends in a conflict and preserves the other edit.
- An explicit dependency changed: application stops before writing.
- Construction, a retry with the same key, and checked undo; undo is rejected after a later external edit.
- Operation cancellation, protection of an unsupported source block, and rejection outside the allowed area.
- Forced termination of the test's own server process during a 4096-block operation, restart, and `recovery_required` without automatic replay.
- Administrative recovery review: the agent key is denied, a stale digest is rejected, and abandonment preserves current world contents and permits new operations after the decision is written to disk. Part protection does not prevent review, but continues to prohibit writes to the part.
- A hollow cube through real MCP: 26 blocks; `.schem` export, the asset library, undo, import at the same anchor, and another undo restoring 27 blocks of air.
- A missing camera returns an error without substituting an image.
- After installing the mod in Prism, a 575-block tower was built and four real 1280×720 captures were obtained. The last completed the full Camera → Paper → Bridge → MCP ImageContent path. The first request failed when the viewpoint changed; a retry with the client stationary succeeded. [Test report](ONE_CLIENT_TEST.md).
Реальный `codex-acp` прошёл `initialize` в отдельном профиле без входа: ACP v1 и поддержка загрузки сессии подтверждены. Это ещё не проверка хода модели или вызова инструментов после авторизации. Тесты не вызывали модель и не расходовали её токены.
Real `codex-acp` completed `initialize` in a separate profile without login: ACP v1 and session loading support are confirmed. This does not yet test a model turn or tool calls after authentication. The tests did not invoke a model or consume model tokens.
## Существенные границы
## Significant limitations
**Ручные изменения.** Сравнение ожидаемого и текущего состояния защищает от отличающегося блока непосредственно перед записью. Известные события установки/ломания игроком дополнительно инвалидируют владение блока для undo, даже если игрок вернул прежний материал. Полного перехвата изменений других плагинов, команд, физики и всех переходов A→B→A нет; ревизии известных внешних событий пока не сохраняются между запусками. Нельзя считать этот прототип универсальной системой слияния любых параллельных правок.
**Manual edits.** Comparing expected and current states protects against a different block immediately before writing. Known player place/break events also invalidate block ownership for undo, even if the player restores the previous material. There is no complete interception of changes from other plugins, commands, physics, or all A→B→A transitions; revisions of known external events are not yet persisted across restarts. This prototype cannot be treated as a universal system for merging arbitrary concurrent edits.
**Авария.** JSON-журнал с fsync заменяет запланированную SQLite. Мир Minecraft и наш журнал не образуют одну транзакцию. Неоднозначная операция после сбоя блокирует новые записи. Доступен явный административный обзор и отказ от продолжения по свежему digest, без изменения мира и с отключением неоднозначного undo. Автоматического replay/rollback нет. Полный журнал загружается при старте и пока не имеет архивирования.
**Crashes.** A JSON journal with fsync replaces the planned SQLite storage. The Minecraft world and our journal do not form a single transaction. An ambiguous operation after a crash blocks new writes. Explicit administrative review and abandonment using a fresh digest are available, without modifying the world and with ambiguous undo disabled. There is no automatic replay/rollback. The full journal is loaded at startup and does not yet support archival.
**Область и производительность.** Один владелец, проект и мир; не более 4096 блоков и 512 явных зависимостей на план. Запись — до 128 блоков с целевым бюджетом до 5 мс на порцию; стоимость проверки и JVM не позволяют заявлять жёсткую гарантию времени тика. Полная подготовка ограниченного плана пока выполняется на серверном потоке. Долговременные нагрузочные проверки на большом сервере не проводились.
**Scope and performance.** One owner, project, and world; at most 4096 blocks and 512 explicit dependencies per plan. Writes are limited to 128 blocks with a target budget of up to 5 ms per slice; verification costs and the JVM prevent a hard tick-time guarantee. Full preparation of a bounded plan still runs on the server thread. Long-running load tests on a large server have not been conducted.
**Контекст.** Контекст проекта содержит краткие метаданные, до 20 операций и до 64 частей; точные блоки читаются отдельно. `region_changes` пока возвращает `resync_required`. Поэтому агент повторно читает выбранные участки; обещание «читает только дельты» ещё не реализовано. Диалог ACP имеет сохранение и сводку, но расход модели здесь не измерен.
**Context.** Project context contains brief metadata, up to 20 operations, and up to 64 parts; exact blocks are read separately. `region_changes` currently returns `resync_required`. The agent therefore rereads selected areas; the promise of reading only deltas is not implemented yet. ACP conversations support persistence and summaries, but model usage has not been measured here.
**Блоки и схематики.** Разрешён ограниченный набор из 61 ванильного материала, включая часть ступеней и плит; точный список возвращает `project_context`. Waterlogged, контейнеры, двери, redstone и другие сложные блоки не поддерживаются. Проверка окружающих блоков намеренно ограничивает использование возле неподдерживаемой среды. Sponge v2 `.schem` реализован без зависимости от WorldEdit: до 4096 блоков, до 64 файлов, повороты кратно 90°, без сущностей, block entities и биомов, без преобразования между версиями игры. Неподдерживаемый контент отвергается, а не удаляется при экспорте.
**Blocks and schematics.** A limited set of 71 vanilla materials is allowed, including selected stairs and slabs, lanterns, iron chains (`iron_chain` in Minecraft 26.2), iron bars, stone brick walls, oak leaves, moss, gray and brown glass, glowstone, and gold blocks; `project_context` returns the exact list. Leaves are allowed only with `persistent=true` so that they do not decay without a tree. Waterlogged blocks, containers, doors, redstone, and other complex blocks are unsupported. Checks of surrounding blocks intentionally restrict use near unsupported environments. Sponge v2 `.schem` is implemented without a WorldEdit dependency: up to 4096 blocks, up to 64 files, rotations in multiples of 90°, no entities, block entities, or biomes, and no conversion between game versions. Its strict codec currently supports the original 61-material palette; the ten new decorative materials are available through normal building operations. Unsupported content is rejected rather than removed during export.
**Строительный язык.** Есть box, line, cylinder и repeat. Арки, произвольные трансформации, декоративные палитры, исполнение JavaScript/Python и автоматическое согласование рецептов с ручными правками пока отсутствуют. Зарегистрированная часть содержит точную маску фактически записанных блоков, а не весь её bounding box.
**Building language.** Box, line, cylinder, and repeat are available. Arches, arbitrary transforms, decorative palettes, JavaScript/Python execution, and automatic reconciliation of recipes with manual edits are not yet available. A registered part contains an exact mask of blocks actually written, not its entire bounding box.
**Камера.** Нужен настроенный spectator-клиент; в проверенном сценарии это тот же игрок, что и владелец проекта. Во время снимка он не может продолжать обычное строительство. Автоматического возврата режима и исходной позиции нет. Готовность кадра эвристическая: `serverRevisionVerified: false`. Доступность соседних чанков и стабильность рендера не доказывают получение всех серверных обновлений. Реальная стройка и снимки проверены; сторонние шейдеры, отключение посреди кадра и все варианты зависания окна ещё не проверены.
**Camera.** A configured spectator client is required; in the tested scenario this is the same player as the project owner. During capture, that player cannot continue normal building. Game mode and original position are not restored automatically. Frame readiness is heuristic: `serverRevisionVerified: false`. Neighboring chunk availability and stable rendering do not prove receipt of all server updates. Real construction and captures have been tested; third-party shaders, disconnection during capture, and all forms of window freezing have not yet been tested.
**ACP.** Выделены отдельные HOME/CODEX_HOME, отключены лишние интеграции, shell и передача административного токена. Это не изоляция на уровне ОС. Закреплённый адаптер переводит режим `read-only` в `workspace-write`; временные пути могут оставаться доступными, а закреплённый CLI оставляет флаг `unified_exec` включённым при отключённом `shell_tool`. Дополнительные запросы разрешений пока отклоняются. Поведение разрешений динамического Minecraft MCP требует проверки первого настоящего хода. Подробности и диагностика — в [Bridge README](../bridge/README.md).
**ACP.** Separate HOME/CODEX_HOME directories are used; extra integrations, shell, and forwarding of the administrator token are disabled. This is not OS-level isolation. The pinned adapter maps `read-only` mode to `workspace-write`; temporary paths may remain accessible, and the pinned CLI keeps the `unified_exec` flag enabled when `shell_tool` is disabled. Additional permission requests are currently rejected. Permissions for the dynamically supplied Minecraft MCP need testing in the first real turn. Details and diagnostics are in the [Bridge README](../bridge/README.md).
## Следующий приёмочный этап
## Next acceptance stage
1. Пользователь входит в выделенный Codex-профиль, подключается к Paper и привязывает владельца. Проверяем маленькую постройку из игрового `/ai`, поток ответа, использование MCP и отмену.
2. Расширяем проверенный сценарий Prism с одним клиентом: проверяем отключение/зависание посреди снимка и удобное переключение между строительством и камерой.
3. Проходим цикл «построил → посмотрел → исправил» и только после этого уточняем готовность релиза, лимиты, дельты контекста и расширение геометрии.
1. The user logs in to the dedicated Codex profile, connects to Paper, and binds the owner. Test a small build requested through in-game `/ai`, response streaming, MCP use, and cancellation.
2. Extend the verified single-client Prism scenario: test disconnection/freezing during capture and convenient switching between building and camera use.
3. Complete the build → inspect → correct cycle, then reassess release readiness, limits, context deltas, and geometry extensions.
+24 -24
View File
@@ -1,48 +1,48 @@
# Проверка с одним клиентом Prism
# Single-client Prism test
Проверка выполнена в существующем профиле **26.2 MCP Building**: Minecraft 26.2, Fabric Loader 0.19.5, Fabric API 0.160.0+26.2 и Java 25.0.1 из Prism. Установлен собранный `minecraft-builder-camera-0.1.0-SNAPSHOT.jar`.
The test used the existing **26.2 MCP Building** profile: Minecraft 26.2, Fabric Loader 0.19.5, Fabric API 0.160.0+26.2, and Java 25.0.1 supplied by Prism. The built `minecraft-builder-camera-0.1.0-SNAPSHOT.jar` was installed.
Пользователь выбрал автономный профиль для локального теста. В этой рабочей установке `.runtime/server/server.properties` содержит `online-mode=false`, `server-ip=127.0.0.1`, `server-port=25575`; слушающий адрес не расширялся. Это изменение тестовой конфигурации, обычная первоначальная подготовка `dev-server.py` по-прежнему включает проверку аккаунта.
The user selected an offline profile for this local test. In this working installation, `.runtime/server/server.properties` contains `online-mode=false`, `server-ip=127.0.0.1`, and `server-port=25575`; the listening address was not broadened. This is a test configuration change; the normal initial setup through `dev-server.py` still enables account authentication.
В приватном конфиге плагина `owner-uuid` и `camera-player-uuid` совпадают. Игроку выданы права оператора на этом тестовом сервере; `allow-local-automation` остаётся выключенным, все вызовы выполнялись с областью владельца. Для фотографий режим временно менялся на spectator. После проверки игрок возвращён в creative на платформе перед башней; автоматического переключения внутри плагина пока нет.
In the plugin's private configuration, `owner-uuid` and `camera-player-uuid` match. The player was granted operator permissions on this test server; `allow-local-automation` remains disabled, and all calls used owner scope. The game mode was temporarily changed to spectator for photographs. After the test, the player was returned to creative on the platform in front of the tower; the plugin does not yet switch modes automatically.
## Что проверено
## What was verified
1. Prism загрузил Fabric-мод и подключил одного игрока к Paper. HTTP Worker сообщил подключение и правильный UUID.
2. Через агентский маршрут Paper подготовлена и применена постройка из 575 блоков на ранее пустом участке. Создана именованная часть `One-client camera test tower` с точной маской записи.
3. Первый снимок остановился с `view_changed`, без возврата старого кадра. При повторе неподвижный клиент дал настоящий PNG 1280×720. Метаданные подтверждают заданные yaw/pitch, 20 стабильных тиков и три кадра; запрос занял 2.052 секунды после задержки оператора.
4. Успешно снят второй ракурс и дневной вариант первого.
5. Отдельный MCP stdio-клиент запросил новый снимок и получил один `ImageContent` с PNG. Текстовый блок содержал только метаданные, без base64. Проверены идентификатор, время снимка, сигнатура и размеры PNG. Изображение просмотрено: на нём тестовая башня, кадр без HUD.
1. Prism loaded the Fabric mod and connected one player to Paper. The HTTP worker reported a connection and the correct UUID.
2. A 575-block structure was prepared and applied through Paper's agent route in a previously empty area. A named part, `One-client camera test tower`, was created with the exact write mask.
3. The first capture stopped with `view_changed`, without returning a stale frame. On retry, the stationary client produced a real 1280×720 PNG. Metadata confirms the requested yaw/pitch, 20 stable ticks, and three frames; the request took 2.052 seconds after the operator delay.
4. A second viewpoint and a daylight version of the first were captured successfully.
5. A separate MCP stdio client requested a new capture and received one `ImageContent` containing a PNG. The text block contained only metadata, without base64. The capture ID, timestamp, PNG signature, and dimensions were checked. The image was viewed: it shows the test tower without the HUD.
Все изображения — исходные данные Minecraft framebuffer. Они не генерировались нейросетью и не ретушировались. `serverRevisionVerified: false` остаётся честным ограничением: клиентская готовность пока эвристическая. Первый ход модели через `codex-acp` этим тестом не проверялся.
All images are original Minecraft framebuffer data. They were neither AI-generated nor retouched. `serverRevisionVerified: false` remains an explicit limitation: client readiness is still heuristic. This test did not verify the first model turn through `codex-acp`.
Локальные результаты:
Local results:
- `.runtime/camera-test/build.json` — идентификатор плана/операции, число блоков, часть и область.
- `.runtime/camera-test/20260912T192813Z-2b100930.png` и соседний JSON — первый успешный ракурс.
- `.runtime/camera-test/20260912T192831Z-776d8f9e.png` — второй ракурс.
- `.runtime/camera-test/20260912T192909Z-76b04afd.png` — дневной кадр.
- `.runtime/camera-test/mcp-975cd742-d23f-4b8d-bcc8-dc6e151a8f5c.png` и соседний JSON — изображение, полученное через MCP.
- `.runtime/camera-test/build.json` — plan/operation ID, block count, part, and region.
- `.runtime/camera-test/20260912T192813Z-2b100930.png` and the adjacent JSON — first successful viewpoint.
- `.runtime/camera-test/20260912T192831Z-776d8f9e.png` — second viewpoint.
- `.runtime/camera-test/20260912T192909Z-76b04afd.png` — daylight image.
- `.runtime/camera-test/mcp-975cd742-d23f-4b8d-bcc8-dc6e151a8f5c.png` and the adjacent JSON — image received through MCP.
Башня оставлена для осмотра около `12, 95, 12`, на платформе `x/z=4..20`, `y=94`. Она пересекает область автоматических серверных тестов. Перед их повторным запуском нужен отдельный чистый тестовый мир или проверяемая отмена этой операции; тесты сами не удаляют занятую область.
The tower was left for inspection near `12, 95, 12`, on a platform at `x/z=4..20`, `y=94`. It overlaps the automated server tests' region. Before rerunning those tests, use a separate clean test world or a checked undo of this operation; the tests do not clear an occupied region themselves.
## Повторение снимка
## Repeating a capture
В Prism у профиля настроен wrapper `python3 /путь/к/minecraft-builder-mcp/scripts/camera-wrapper.py`. Он читает приватный ключ камеры из Paper config и передаёт только процессу Java через окружение. Секрет не помещается в `instance.cfg` или командную строку. Исходный `instance.cfg` и `options.txt` сохранены в `.runtime/prism-one-client-backup`.
The Prism profile uses the wrapper `python3 /path/to/minecraft-builder-mcp/scripts/camera-wrapper.py`. It reads the private camera token from Paper's configuration and passes it only to the Java process through its environment. The secret is not placed in `instance.cfg` or the command line. The original `instance.cfg` and `options.txt` are backed up in `.runtime/prism-one-client-backup`.
После подключения, из игры:
After connecting, run in the game:
```text
/gamemode spectator
/ai camera save test
```
Сохранять ракурс нужно внутри выбранной области. Из корня проекта:
Save the viewpoint inside the selected region. From the project root:
```bash
python3 scripts/live-camera-test.py --delay 8
```
Вернуться в окно Minecraft, закрыть меню/чат и не двигаться до завершения. Скрипт сохраняет новый PNG и очищенные метаданные. Затем можно вручную выполнить `/gamemode creative`.
Return to Minecraft, close menus/chat, and remain still until completion. The script saves a new PNG and sanitized metadata. You can then run `/gamemode creative` manually.
`bridge/test/live-camera.mjs` отдельно проверяет MCP ImageContent. Он требует доверенные переменные `MCB_AGENT_TOKEN`, `MCB_PLAYER_ID`, `MCB_PROJECT_ID`, JSON-позу `MCB_CAPTURE_POSE` и необязательный `MCB_AFTER_OPERATION_ID`. Снимок перемещает настроенного наблюдателя; это явный интеграционный тест, он не входит в обычный `npm test`.
`bridge/test/live-camera.mjs` separately verifies MCP ImageContent. It requires the trusted variables `MCB_AGENT_TOKEN`, `MCB_PLAYER_ID`, `MCB_PROJECT_ID`, a JSON pose in `MCB_CAPTURE_POSE`, and optionally `MCB_AFTER_OPERATION_ID`. Capture moves the configured observer; this is an explicit integration test and is not included in ordinary `npm test`.
+37 -37
View File
@@ -1,73 +1,73 @@
# Протокол прототипа
# Prototype protocol
Версия: 1. Точный реализованный каталог инструментов доступен через MCP `tools/list`, а возможности установленного Paper — через `project_context`.
Version: 1. The exact implemented tool catalog is available through MCP `tools/list`, and the capabilities of the installed Paper plugin through `project_context`.
## Соединение с Paper
## Paper connection
Сервис слушает только loopback, по умолчанию `127.0.0.1:8765`. `GET /health` возвращает состояние и версию без приватных данных. `POST /v1/rpc` принимает JSON и заголовок `Authorization: Bearer <token>`.
The service listens on loopback only, at `127.0.0.1:8765` by default. `GET /health` returns status and version information without private data. `POST /v1/rpc` accepts JSON and an `Authorization: Bearer <token>` header.
Запрос: `{ "method": "project_context", "params": { "player_id": "UUID", "project_id": "default" }, "requestId": "correlation-id" }`.
Request: `{ "method": "project_context", "params": { "player_id": "UUID", "project_id": "default" }, "requestId": "correlation-id" }`.
Успех: `{ "ok": true, "result": { ... } }`. Ошибка: `{ "ok": false, "error": { "code": "...", "message": "..." } }`. Ошибка может сопровождаться HTTP 400/403; клиент обязан читать структурированное тело. Токены в результатах не возвращаются.
Success: `{ "ok": true, "result": { ... } }`. Error: `{ "ok": false, "error": { "code": "...", "message": "..." } }`. An error may come with HTTP 400/403; clients must read the structured body. Tokens are never returned in results.
Административный ключ обязателен для `chat_poll`, `chat_reply`, `recovery_review` и `recovery_abandon`. Ключ агента допускает инструменты мира в проекте связанного владельца, но не административное восстановление. `player_id/project_id` добавляются MCP-процессом из настроек, а не предлагаются модели. Плагин повторно проверяет владельца и его действующие права. Для изолированного тестового мира есть явно включаемый `allow-local-automation` и принципал `console`; административные операции восстановления также проходят проверку этой области полномочий.
The administrator key is required for `chat_poll`, `chat_reply`, `recovery_review`, and `recovery_abandon`. The agent key permits world tools within the bound owner's project, but not administrative recovery. The MCP process injects `player_id/project_id` from its configuration; the model is not asked to supply them. The plugin rechecks the owner and their current permissions. An isolated test world can explicitly enable `allow-local-automation` with the `console` principal; administrative recovery operations also pass through this scope check.
## Чтение и запись
## Reading and writing
`region_inspect` требует `min/max` как `{x,y,z}` и `detail: "summary" | "blocks"`. Координаты включительные, целочисленные. Лимит прототипа — 4096 позиций. Ответ содержит палитру с количеством, а для `blocks` — точные состояния. Данные берутся из загруженных чанков без неявной генерации мира.
`region_inspect` requires `min/max` as `{x,y,z}` and `detail: "summary" | "blocks"`. Coordinates are inclusive integers. The prototype limit is 4096 positions. The response contains a palette with counts and, for `blocks`, exact states. Data comes from loaded chunks without implicit world generation.
`build_prepare` принимает `recipe: {version: 1, operations: [...]}`, необязательный массив `dependencies` и необязательный `part_id` для точной маски части. Геометрия: `box(min,max,block,hollow?)`, `line(from,to,block)`, `cylinder(center,radius,height,block,hollow?)`, `repeat(count,offset,operations)`. Используется JSON-описание, не исполняемый JavaScript.
`build_prepare` accepts `recipe: {version: 1, operations: [...]}`, an optional `dependencies` array, and an optional `part_id` for an exact part mask. Geometry: `box(min,max,block,hollow?)`, `line(from,to,block)`, `cylinder(center,radius,height,block,hollow?)`, `repeat(count,offset,operations)`. This is a JSON description, not executable JavaScript.
Результат подготовки: `plan_id`, `plan_hash`, `changed_blocks`, `region`, `expires_at`. Полный план и исходные блоки остаются в журнале. `build_apply` принимает этот ID, хеш и постоянный для данного вызова `idempotency_key`. Повтор того же вызова возвращает ту же операцию. Для другого плана нужен другой ключ.
Preparation returns `plan_id`, `plan_hash`, `changed_blocks`, `region`, and `expires_at`. The full plan and original blocks stay in the journal. `build_apply` accepts this ID, hash, and an `idempotency_key` that remains constant for that logical call. Repeating the same call returns the same operation. A different plan requires a different key.
`operation_status(operation_id)` возвращает состояние, счётчики и ограниченные примеры конфликтов. `operation_cancel` останавливает следующие порции. `operation_undo_prepare` создаёт обратный план; он проходит обычный `build_apply` и проверки. Потеря ответа на применение не даёт права создать другой ключ и повторить запись: сначала проверить `project_context` или повторить исходный вызов с тем же ключом.
`operation_status(operation_id)` returns status, counters, and a bounded sample of conflicts. `operation_cancel` stops subsequent slices. `operation_undo_prepare` creates a reverse plan; it goes through the normal `build_apply` and checks. Losing the response to an apply request does not justify creating a different key and repeating the write: first check `project_context` or repeat the original call with the same key.
`part_define(name,operation_id)` регистрирует только фактически записанные блоки завершённой операции. `part_get(part_id)` возвращает имя, границы, количество и защиту. Границы не равны маске: `build_prepare(part_id)` проверяет каждый блок по точной маске. Расширение создаётся отдельной частью.
`part_define(name,operation_id)` registers only blocks actually written by a completed operation. `part_get(part_id)` returns the name, bounds, count, and protection settings. Bounds are not the mask: `build_prepare(part_id)` checks every block against the exact mask. Extensions are created as separate parts.
Перед записью проверяются реальные состояния целевых блоков и объявленных зависимостей; проверка повторяется после сохранения намерения. Несовпадение не перезаписывается автоматически. Для undo также учитываются известные последующие записи наших операций, даже когда значение блока снова совпадает с прежним результатом.
Before a write, the actual states of target blocks and declared dependencies are checked; the check runs again after the intent is persisted. A mismatch is never overwritten automatically. Undo also accounts for known subsequent writes by our operations, even when a block's value again matches the earlier result.
Плагин наблюдает неотменённые `BlockPlaceEvent` и `BlockBreakEvent` в настроенном мире. Такое событие лишает прежнюю операцию права на undo данного блока, включая случай «изменили и вернули обратно» (ABA). Эти уведомления хранятся только в памяти текущего процесса. После перезапуска и для внешних путей без наблюдаемого события остаётся проверка текущего содержимого; полная история действий других плагинов не обещается.
The plugin observes uncancelled `BlockPlaceEvent` and `BlockBreakEvent` events in the configured world. Such an event revokes the earlier operation's right to undo that block, including an edit followed by a change back to the original state (ABA). These notifications are held only in the current process's memory. After a restart, and for external paths without an observed event, current-content checks remain in place; a complete history of other plugins' actions is not promised.
Полный серверный журнал внешних изменений пока не реализован. `region_changes` отвечает `resync_required`; агент использует свежие ограниченные чтения. Это явное ограничение прототипа.
A full server-side journal of external changes is not implemented yet. `region_changes` returns `resync_required`; the agent uses fresh, bounded reads. This is an explicit prototype limitation.
## Восстановление после сбоя
## Crash recovery
Незавершённая операция после перезапуска получает `recovery_required` и запрещает начало новых записей. Автоматического повторения незавершённых порций нет. Административные RPC ниже не входят в MCP-инструменты агента и не являются откатом мира.
After a restart, an unfinished operation receives `recovery_required` and prevents new writes from starting. Unfinished slices are not replayed automatically. The administrative RPCs below are not exposed as agent MCP tools and do not roll back the world.
`recovery_review` принимает `operation_id`. Результат использует имена полей Java-записи: `operationId`, `planId`, `positions`, `matchesBefore`, `matchesAfter`, `foreignStates`, `currentDigest`, `sampledAtMillis`. Проверяемая маска объединяет фактически подтверждённые записи предыдущих порций и потенциальные записи незавершённой порции; пропуски без записи не включаются. Счётчики описывают совпадение текущих значений с `before/after`, а `currentDigest` — SHA-256 для этого снимка. Совпадение содержимого не доказывает авторство изменения.
`recovery_review` accepts `operation_id`. Its result uses the Java record's field names: `operationId`, `planId`, `positions`, `matchesBefore`, `matchesAfter`, `foreignStates`, `currentDigest`, `sampledAtMillis`. The reviewed mask combines confirmed writes from earlier slices with potential writes from the unfinished slice; skipped positions that were not written are excluded. The counters describe how current values match `before/after`, while `currentDigest` is the SHA-256 digest of this snapshot. Matching content does not prove who made a change.
`recovery_abandon` принимает `operation_id` и `expected_digest`, полученный из `currentDigest` последнего обзора. Сервер заново читает маску и отклоняет запрос, если её содержимое изменилось. При совпадении он оставляет все блоки мира на месте, переводит операцию в `failed` и сохраняет решение до успешного ответа. Ответ имеет обычную форму `operation_status`.
`recovery_abandon` accepts `operation_id` and `expected_digest`, taken from the latest review's `currentDigest`. The server rereads the mask and rejects the request if its contents have changed. If they match, it leaves all world blocks in place, changes the operation to `failed`, and persists the decision before returning success. The response has the usual `operation_status` shape.
Отказ от неопределённой истории навсегда запрещает undo этой операции и сохраняет аннулирование прежнего права на undo для блоков затронутой маски. Новые записи разрешаются только после постоянного сохранения решения по всем незавершённым операциям. Сбой до сохранения оставляет необходимость восстановления; потеря ответа требует проверки `operation_status`, а не предположения, что произошёл откат. Устаревший или неверный digest возвращается как RPC-ошибка `invalid_request` с причиной.
Abandoning uncertain history permanently disables undo for that operation and preserves the invalidation of earlier undo ownership for blocks in the affected mask. New writes are permitted only after the decisions for all unfinished operations have been durably saved. A failure before persistence leaves recovery required; a lost response requires checking `operation_status`, not assuming that a rollback occurred. A stale or incorrect digest is returned as an `invalid_request` RPC error with a reason.
Статус `applied` подтверждает наблюдавшийся результат записи и проверки в работающем сервере. Файлы чанков и журнал не образуют общую транзакцию; автоматической проверки сохранности всех ранее завершённых операций после аварии пока нет.
The `applied` status confirms the write and verification result observed by the running server. Chunk files and the journal do not form a shared transaction; automatic verification that all previously completed operations survived a crash is not implemented yet.
## Локальные схемы
## Local schematics
Реализованные имена RPC — `asset_list`, `schematic_export` и `schematic_import_prepare`. Отдельных маршрутов `schematic_list` и немедленного `schematic_import` нет. Наличие этих возможностей проверяется через `project_context`.
The implemented RPC names are `asset_list`, `schematic_export`, and `schematic_import_prepare`. There are no separate `schematic_list` or immediate `schematic_import` routes. Check `project_context` for these capabilities.
`asset_list` принимает необязательный `query` для поиска по имени без учёта регистра и возвращает `{ "assets": [...] }`. Каждый элемент содержит `assetId`, `name`, `width`, `height`, `length`, `blockCount`, `dataVersion`, `offset`, `sha256`, `bytes`. Каталог содержит до 64 файлов; каждый файл проверяется при чтении, поэтому повреждённая схема может привести к отказу всего запроса списка.
`asset_list` accepts an optional `query` for case-insensitive name search and returns `{ "assets": [...] }`. Each entry contains `assetId`, `name`, `width`, `height`, `length`, `blockCount`, `dataVersion`, `offset`, `sha256`, and `bytes`. The catalog holds up to 64 files; every file is validated when read, so a corrupt schematic may cause the entire list request to fail.
`schematic_export` принимает `name`, включительные `min/max` и необязательный `origin`. Имя содержит 1–64 печатных символа. `origin` задаёт точку привязки схемы; по умолчанию она равна `min`. Сервер читает плотный прямоугольный участок, включая воздух, в текущей области проекта и в пределах `max_plan_blocks` (не более 4096). Неподдерживаемые блоки и сущности, кроме игроков, приводят к отказу; игроки в схему не записываются. Результат — один объект с теми же полями метаданных, что у `asset_list`. Файл остаётся в подкаталоге `schematics` каталога данных плагина; RPC не возвращает его содержимое или произвольный путь.
`schematic_export` accepts `name`, inclusive `min/max`, and an optional `origin`. The name contains 1–64 printable characters. `origin` defines the schematic's anchor point and defaults to `min`. The server reads a dense rectangular region, including air, within the current project area and the `max_plan_blocks` limit (at most 4096). Unsupported blocks and entities other than players cause rejection; players are not written to the schematic. The result is one object with the same metadata fields as `asset_list`. The file remains in the `schematics` subdirectory of the plugin's data directory; the RPC returns neither its contents nor an arbitrary path.
`schematic_import_prepare` принимает `asset_id`, `target: {x,y,z}` и необязательный `rotation: 0 | 90 | 180 | 270` (по умолчанию 0). Поворот выполняется по часовой стрелке при взгляде сверху вокруг точки привязки `target`; сохранённый `offset` учитывается. Изменяются также поддерживаемые направления ступеней и оси брёвен/столбов. Результат — обычный `plan_id/plan_hash/changed_blocks/region/expires_at`; для записи нужен отдельный `build_apply`. Воздух схемы входит в план и может удалять существующие поддерживаемые блоки. Область, исходное содержимое, окружение, политика блоков и конфликты проверяются обычным путём подготовки и применения.
`schematic_import_prepare` accepts `asset_id`, `target: {x,y,z}`, and an optional `rotation: 0 | 90 | 180 | 270` (default 0). Rotation is clockwise when viewed from above, around the `target` anchor; the saved `offset` is taken into account. Supported stair directions and log/pillar axes are also transformed. The result is the usual `plan_id/plan_hash/changed_blocks/region/expires_at`; writing requires a separate `build_apply`. Air in the schematic is part of the plan and can remove existing supported blocks. The area, original contents, surroundings, block policy, and conflicts are checked through the normal preparation and application path.
Поддерживается ограниченное подмножество Sponge Schematic v2: gzip и NBT с палитрой ванильных строительных состояний. Лимиты — 4096 позиций, 1 МиБ сжатого файла и 4 МиБ распакованного NBT. Сущности, block entities, биомы, неизвестные поля верхнего уровня, требуемые модификации и другие версии формата отклоняются. `DataVersion` новее текущего сервера не принимается; преобразования через DataFixer нет. Полная совместимость со всеми схемами WorldEdit не заявляется.
A limited subset of Sponge Schematic v2 is supported: gzip and NBT with a palette of vanilla building block states. Limits are 4096 positions, a 1 MiB compressed file, and 4 MiB of decompressed NBT. Entities, block entities, biomes, unknown top-level fields, required mods, and other format versions are rejected. A `DataVersion` newer than the current server is not accepted; there is no DataFixer conversion. Full compatibility with every WorldEdit schematic is not claimed.
Внешний `.schem` можно заранее поместить локально в каталог схем под именем `[A-Za-z0-9][A-Za-z0-9_-]{0,63}.schem`, после чего его основание используется как `asset_id`. Произвольные пути, сетевые URL и символические ссылки не принимаются. Загрузки файла через RPC в прототипе нет.
An external `.schem` can be placed in the local schematic directory in advance with a name matching `[A-Za-z0-9][A-Za-z0-9_-]{0,63}.schem`; its filename stem then serves as `asset_id`. Arbitrary paths, network URLs, and symbolic links are not accepted. The prototype does not support file uploads through RPC.
## Чат
## Chat
`chat_poll` принимает стабильный на время жизни Bridge `client_id`. Ответ — `messages` с полями `id`, `playerId`, `projectId`, `text`, `type`, сведениями о положении и блоке под прицелом при наличии. `type` — `prompt` либо `cancel`. Ключ администратора обязателен.
`chat_poll` accepts a `client_id` that remains stable throughout the Bridge process's lifetime. The response is `messages` with `id`, `playerId`, `projectId`, `text`, `type`, and position and targeted-block information when available. `type` is either `prompt` or `cancel`. The administrator key is required.
`chat_reply` принимает `id`, `playerId`, `text`, `done`, необязательный `error`. Ответ маршрутизируется только инициатору исходного запроса. На смену Bridge-процесса незавершённые запросы не проигрываются автоматически: плагин останавливает изменения и просит проверить мир. `/ai stop` приостанавливает новые записи независимо от того, успел ли завершиться ACP-ход.
`chat_reply` accepts `id`, `playerId`, `text`, `done`, and an optional `error`. The response is routed only to the initiator of the original request. When the Bridge process changes, unfinished requests are not replayed automatically: the plugin stops changes and asks the user to inspect the world. `/ai stop` pauses new writes regardless of whether the ACP turn has finished.
## Камера
## Camera
`camera_capture` принимает `camera_id` либо `pose: {x,y,z,yaw,pitch,fov?,width?,height?}`. Позиция соответствует ногам наблюдателя; Worker отдельно возвращает координаты глаз. `after_operation_id` проверяет завершение серверной операции, но не гарантирует получения её всех пакетов клиентом.
`camera_capture` accepts `camera_id` or `pose: {x,y,z,yaw,pitch,fov?,width?,height?}`. The position refers to the observer's feet; the Worker returns eye coordinates separately. `after_operation_id` checks that the server operation has completed, but does not guarantee that the client has received all of its packets.
Paper сериализует запросы, перемещает настроенного spectator-наблюдателя и отправляет запрос локальному Camera Worker на `127.0.0.1:8766` с отдельным ключом. Pending-ответ содержит `captureId`; для проверки вызывается `camera_capture` с `capture_id`. Готовый результат содержит `imageBase64` и `mimeType`, которые Bridge превращает в MCP image content, не в текстовую base64-строку.
Paper serializes requests, moves the configured spectator observer, and sends a request to the local Camera Worker at `127.0.0.1:8766` with a separate key. A pending response contains `captureId`; poll by calling `camera_capture` with `capture_id`. A completed result contains `imageBase64` and `mimeType`, which the Bridge converts into MCP image content rather than a textual base64 string.
Снимок имеет эвристическую оценку готовности чанков/кадров. `serverRevisionVerified: false` сохраняется до реализации строгого клиентского подтверждения. Отсутствие камеры, таймаут и невозможность получить свежий кадр не считаются визуальным успехом.
Captures include a heuristic assessment of chunk/frame readiness. `serverRevisionVerified: false` remains in place until strict client acknowledgement is implemented. A missing camera, a timeout, or failure to obtain a fresh frame never counts as visual success.
Подробности Worker: [camera-mod/README.md](../camera-mod/README.md). Потоки и журнал: [world-core/README.md](../world-core/README.md). ACP и изоляция: [bridge/README.md](../bridge/README.md).
Worker details: [camera-mod/README.md](../camera-mod/README.md). Threading and journal: [world-core/README.md](../world-core/README.md). ACP and isolation: [bridge/README.md](../bridge/README.md).
+19 -19
View File
@@ -1,24 +1,24 @@
# Готический зал
# Gothic Hall
Воспроизводимая постройка по [визуальному референсу](../references/gothic-hall-v1.png): большой зал с галереями, меньший двухэтажный корпус, соединительный переход и колокольня. Геометрию создают модули в `scripts/builds/gothic_hall/`, применение выполняет `scripts/build-gothic-hall.py` через проверяемые операции Paper-плагина.
A reproducible build based on the [visual reference](../references/gothic-hall-v1.png): a large hall with galleries, a smaller two-story wing, a connecting passage, and a bell tower. Modules in `scripts/builds/gothic_hall/` generate the geometry; `scripts/build-gothic-hall.py` applies it through the Paper plugin's checked operations.
Это адаптация референса доступной палитрой: каменный кирпич, андезит, диорит, тёмный сланец, древесина и затемнённое стекло. Шейдеры не используются. Детальная меблировка и ландшафт пока не выполнены; имеются терраса, лестницы, простые скамьи и помост. Колокол собран из блоков, без сущности колокола.
This report records the original baseline before subsequent decorative polishing. It adapts the reference to the available palette: stone bricks, andesite, diorite, dark deepslate, wood, and tinted glass. No shaders were used. Detailed furnishing and landscaping were not part of this baseline; it includes a terrace, stairs, simple benches, and a raised platform. The bell is built from blocks, without a bell entity.
Постройка применена в живом мире: **29 354 блока, 87 пакетов**, итоговая проверка сохранена в `.runtime/gothic-hall/verification.json`.
The baseline was applied in the live world: **29,354 blocks in 87 batches**, with verification saved in `.runtime/gothic-hall/verification.json`.
![Постройка в Minecraft без шейдеров](gothic-hall-built.png)
![Original Minecraft build without shaders](gothic-hall-built.png)
Настоящий снимок Fabric-камеры от 12 сентября 2026 года, после финальной отделки. PNG сохранён без обработки; [метаданные снимка](gothic-hall-built.capture.json). Ракурс: `(0, -20, -63)`, yaw `25°`, pitch `16°`, FOV `85°`. Дальность тестового сервера — пять чанков, поэтому дальние края скрываются в тумане. Готовность кадра проверяется по клиенту; совпадение блоков с чертежом проверено отдельно чтением мира.
A real Fabric camera capture from September 12, 2026, after the initial finishing pass. The PNG is unprocessed; [capture metadata](gothic-hall-built.capture.json). Viewpoint: `(0, -20, -63)`, yaw `25°`, pitch `16°`, FOV `85°`. The test server's view distance was five chunks for this original capture, so distant edges disappear into fog. The current local server has since been updated to 12 chunks for the polishing pass. Frame readiness is checked on the client; agreement between the blocks and the blueprint was verified separately by reading the world.
Начало локальных координат — **origin = (-50, -60, -40)**. Мировая координата получается прибавлением origin к локальной. Все диапазоны ниже включают обе границы; главные фасады обращены на север, в сторону `−Z`.
The local coordinate origin is **origin = (-50, -60, -40)**. Add this origin to a local coordinate to obtain its world coordinate. All ranges below are inclusive; the main facades face north, toward `−Z`.
- Терраса: локально `X=1..63, Z=1..62, Y=0`, размер **63 × 62**. В мире: `X=-49..13, Z=-39..22, Y=-60`.
- Большой зал: основной корпус `X=7..31, Z=13..56`, размер **25 × 44**; с декором занимает `X=3..35, Z=8..57, Y=0..48`. Основной пол на `Y=6`, галереи на `Y=16`, конёк на `Y=43`. Главный вход около мировой точки **(-31, -53, -31)**.
- Боковой корпус: основное пятно `X=38..57, Z=16..41`, размер **20 × 26**; с выступами `X=36..59, Z=13..43, Y=0..28`. Полы на `Y=0/8`, конёк на `Y=28`. Вход около **(-3, -59, -26)**.
- Колокольня: с выступами `X=34..46, Z=42..56, Y=0..60`, размер **13 × 15**, 61 уровень блоков. Вершина в мире на `Y=0`; вход около **(-10, -58, 2)**.
- Соединительный переход: `X=31..40, Z=33..43, Y=0..16`; проход в полосе `Z=36..39` поднимается с пола большого зала `Y=6` к полу бокового корпуса `Y=8`.
- Terrace: local `X=1..63, Z=1..62, Y=0`, size **63 × 62**. World coordinates: `X=-49..13, Z=-39..22, Y=-60`.
- Large hall: main body `X=7..31, Z=13..56`, size **25 × 44**; with decoration it occupies `X=3..35, Z=8..57, Y=0..48`. Main floor at `Y=6`, galleries at `Y=16`, roof ridge at `Y=43`. Main entrance near world position **(-31, -53, -31)**.
- Side wing: main footprint `X=38..57, Z=16..41`, size **20 × 26**; including projections, `X=36..59, Z=13..43, Y=0..28`. Floors at `Y=0/8`, roof ridge at `Y=28`. Entrance near **(-3, -59, -26)**.
- Bell tower: including projections, `X=34..46, Z=42..56, Y=0..60`, size **13 × 15**, with 61 block levels. Its top is at world `Y=0`; entrance near **(-10, -58, 2)**.
- Connecting passage: `X=31..40, Z=33..43, Y=0..16`; the walkway in `Z=36..39` rises from the hall floor at `Y=6` to the wing floor at `Y=8`.
Команды выполняются из корня репозитория при запущенном Paper-сервере, подключённом владельце проекта и загруженных чанках стройплощадки. Скрипт читает область проекта и отдельный агентский токен из приватного `.runtime/server/plugins/MinecraftBuilderMCP/config.yml`.
Run commands from the repository root with Paper running, the project owner connected, and the building site's chunks loaded. The script reads project scope and the separate agent token from the private `.runtime/server/plugins/MinecraftBuilderMCP/config.yml`.
```bash
python3 scripts/build-gothic-hall.py plan
@@ -26,13 +26,13 @@ python3 scripts/build-gothic-hall.py apply
python3 scripts/build-gothic-hall.py verify
```
`plan` сохраняет `.runtime/gothic-hall/manifest.json`, проверяет палитру, границы проекта и точность сжатия геометрии в рецепты. Мир эта команда не меняет. `apply` перед каждым новым пакетом проверяет, что его область пуста, затем выполняет `build_prepare` и `build_apply`. Состояния блоков в сохранённом плане также должны ожидать воздух. `verify` сравнивает записанные блоки с результатом в мире и сохраняет отчёт; пустые пространства вне записанной маски она не проверяет.
`plan` saves `.runtime/gothic-hall/manifest.json` and checks the palette, project bounds, and exactness of geometry compression into recipes. It does not change the world. Before each new batch, `apply` checks that the target region is empty, then calls `build_prepare` and `build_apply`. Original block states in the saved plan must also be air. `verify` compares recorded blocks with the live world and saves a report; it does not check empty spaces outside the recorded mask.
Журнал возобновления — `.runtime/gothic-hall/ledger.json`. В нём сохраняются хеш чертежа, планы, ключи идемпотентности, идентификаторы операций и их статусы. Повторный `apply` продолжает по этому журналу, используя существующие операции; завершённые пакеты заново не строятся. Также проверяются идентификатор мира и его эпоха.
The resume ledger is `.runtime/gothic-hall/ledger.json`. It stores the blueprint hash, plans, idempotency keys, operation IDs, and their statuses. Rerunning `apply` resumes from this ledger using existing operations; completed batches are not rebuilt. The world ID and epoch are also checked.
Занятая область, ручное изменение ожидаемого блока, незавершённая или конфликтующая операция останавливают применение. `verify` сообщает расхождения, сохраняя ручные правки. При остановке нужно проверить указанную операцию и её серверный журнал; удалять ledger или автоматически создавать новый план поверх существующей постройки нельзя. Серверные планы находятся в `plugins/MinecraftBuilderMCP/journal/plans/` и нужны этому скрипту для применения и проверки.
An occupied region, a manual change to an expected block, or an unfinished/conflicting operation stops application. `verify` reports mismatches while preserving manual edits. If application stops, inspect the reported operation and its server journal; do not delete the ledger or automatically create a new plan over the existing structure. Server plans live in `plugins/MinecraftBuilderMCP/journal/plans/` and are required by this script for application and verification.
Финальная отделка хранится отдельно от исходного чертежа: `scripts/finish-gothic-hall.py` заменяет 14 центральных плит наверший на целые каменные блоки и четыре блока перехода на ступени. Это убирает зазоры в шпилях и делает подъём между корпусами плавным. Используются отдельный план и `.runtime/gothic-hall/finish-ledger.json`.
The initial finishing pass is stored separately from the original blueprint: `scripts/finish-gothic-hall.py` replaces 14 central pinnacle slabs with full stone blocks and four passage blocks with stairs. This removes gaps in the spires and makes the ascent between the buildings smooth. It uses a separate plan and `.runtime/gothic-hall/finish-ledger.json`.
```bash
python3 scripts/finish-gothic-hall.py plan
@@ -40,6 +40,6 @@ python3 scripts/finish-gothic-hall.py apply
python3 scripts/finish-gothic-hall.py verify
```
После отделки следует использовать последнюю команду: она проверяет исходную постройку с учётом 18 замен. Исходная `build-gothic-hall.py verify` ожидает прежние состояния этих блоков и сообщит о расхождениях.
After that finishing pass, use the last command: it verifies the original building with the 18 replacements applied. The original `build-gothic-hall.py verify` expects those blocks' previous states and will report mismatches.
Отделка применена операцией `682bb5bb-a1fe-4359-b687-06f7b1ce1005`. Повторная проверка всех 29 354 блоков прошла; отчёт — `.runtime/gothic-hall/finish-verification.json`. Мир сохранён через `save-all flush`.
The finishing pass was applied as operation `682bb5bb-a1fe-4359-b687-06f7b1ce1005`. Reverification of all 29,354 blocks passed; the report is `.runtime/gothic-hall/finish-verification.json`. The world was saved with `save-all flush`.