Initial minecraft-builder-mcp prototype and Gothic hall build

This commit is contained in:
Emil
2026-09-12 23:22:20 +03:00
commit 6682668c16
103 changed files with 10064 additions and 0 deletions
+407
View File
@@ -0,0 +1,407 @@
# minecraft-builder-mcp — дизайн-документ
Версия документа: 0.1 · Дата: 12 сентября 2026 года
Статус: целевой дизайн. Первый прототип создан; фактические возможности, проверки и отличия от этого документа перечислены в [IMPLEMENTATION.md](IMPLEMENTATION.md). Разделы ниже описывают также ещё не реализованные требования.
## 1. Назначение
Создать строительную среду для Minecraft Java Edition, в которой человек и ИИ-агент совместно проектируют, строят и редактируют карты. Пользователь общается с Codex в игровом чате или во внешнем клиенте. Агент получает структурированные сведения о мире, применяет массовые изменения через MCP, смотрит реальные снимки и исправляет результат.
Основной сценарий: «Построй башню здесь» → обследование участка → строительство → снимки → уточнение пропорций. Пользователь может параллельно строить вручную, а затем попросить: «Сохрани мои окна, добавь два этажа и переделай крышу».
Результат — обычные ванильные блоки. Карта должна оставаться пригодной к использованию после удаления наших компонентов. История, рецепты и названия частей хранятся отдельно от игровых блоков.
## 2. Решения и рабочие предположения
Из обсуждения следуют требования: Paper как строительная среда с перспективой мини-игр; Codex через готовый `codex-acp`; Minecraft MCP для работы с миром; виртуальные камеры; массовые операции; именованные части; сохранение ручных правок; экономное использование контекста; отмена и перенос построек.
Для этого документа приняты следующие проектные решения, которые можно изменить до реализации:
- Первая версия рассчитана на одного владельца и небольшой круг доверенных строителей, один Paper-сервер и одну активную операцию записи на строительную область.
- Плагин на сервере является единственным компонентом нашей системы, который непосредственно изменяет мир.
- Камеры обслуживает отдельный клиент Minecraft с Fabric-модом. Обычному игроку клиентский мод для чата не требуется.
- Bridge написан на TypeScript; Paper-плагин и Fabric-мод — на Java. Точные версии инструментов фиксируются после проверки совместимости.
- Строительный язык первой версии — ограниченное декларативное описание геометрии и повторений. Произвольный Python/JavaScript внутри сервера не выполняется.
- Снимки, конфликты и история не имеют собственной модели внутри MCP. Их интерпретирует агент с поддержкой изображений.
- Пользовательская команда на строительство разрешает обычные изменения внутри выбранной области; подтверждение каждого пакета блоков не требуется. Настоящие конфликты и выход за полномочия обрабатываются отдельно.
## 3. Почему нужны клиентская и серверная части
Клиентский мод может управлять камерой, снимать изображение, читать присланные клиенту чанки и отправлять команды, разрешённые игроку. Этого достаточно для прототипа, который строит через серверные команды. Но такой клиент не является источником окончательного состояния мира и не обеспечивает согласованную проверку и запись блоков на сервере.
Серверный компонент нужен для достоверного чтения участка, проверки прав, сравнения состояний непосредственно перед записью, журналирования и применения изменений с ограничением нагрузки. Он не умеет сам отрисовывать игровой вид. Клиентское и серверное исполнение в Minecraft разделены; рендеринг выполняет клиент. [Разделение сторон в Fabric](https://wiki.fabricmc.net/tutorial%3Aside).
Целевая установка может целиком работать на одном компьютере: Paper, Bridge, Codex и клиент камеры. Выделенная машина и аренда хостинга не обязательны. Отдельный наблюдатель потребует собственной допустимой игровой сессии; нельзя предполагать, что одна учётная запись позволит одновременно держать игрока и камеру на одном сервере. При отсутствии второй сессии возможен режим камеры в клиенте пользователя с временным переключением вида; это отдельный компромисс интерфейса.
Одиночная игра содержит встроенный сервер. В дальнейшем можно добавить Fabric-модуль для его серверной стороны, сохранив MCP-контракты. Это устраняет отдельный процесс Paper, но требует другого адаптера мира. Одного мода, исполняющегося только на логической клиентской стороне, для полных гарантий недостаточно.
## 4. Платформа и совместимость
Кандидат для первого прототипа — 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/).
До реализации основной функциональности необходимо зафиксировать точные версии Paper, WorldEdit, Fabric Loader/API, Codex, `codex-acp`, MCP/ACP SDK и Node.js. Обновление зависимостей не должно происходить автоматически при каждом запуске. Версии и хеши сборок войдут в будущий файл совместимости.
WorldEdit используется для выделений и формата `.schem`; возможность использовать его как механизм записи проверяется отдельно. Его `EditSession` поддерживает пакетирование и историю, однако это не заменяет нашу проверку конфликтов, постоянный журнал и управление временем исполнения. Буферизация не должна переносить фактическую запись за пределы проверенного серверного шага. [WorldEdit Edit Sessions](https://worldedit.enginehub.org/en/latest/api/concepts/edit-sessions/).
Начальный гарантируемый набор — ванильные строительные блоки без инвентарей и пользовательского NBT, включая протестированные состояния брёвен, ступеней и плит. Допускается воздух как результат удаления. Двери и другие составные конструкции подключаются только после реализации неделимых групп изменений. Гравитационные блоки, жидкости, редстоун, сущности и block entities не входят в первоначальную гарантию редактирования и отмены.
Ограничение действует и на исходное содержимое: операция не может молча затереть сундук или другой неподдерживаемый блок. Предварительная проверка обнаруживает это до применения и возвращает понятную причину.
## 5. Границы первой версии
В v0.1 входят:
- Команды чата, отдельная сессия проекта, поток коротких сообщений о ходе работы и остановка.
- Выделенная строительная область и локальный осмотр мира.
- Компактные описания форм, повторения, палитры и воспроизводимый `seed`.
- Предварительный план, подсчёт изменений и применение порциями.
- Именованные части с точными наборами принадлежащих им блоков.
- Проверка изменений после чтения, остановка на конфликте и отмена с проверками.
- Постоянный журнал операций и обнаружение незавершённой записи после перезапуска.
- Одна обслуживающая камера, несколько сохранённых ракурсов и выдача изображений через MCP.
- Импорт и экспорт `.schem` в пределах поддерживаемого набора данных.
За пределами v0.1: публичный сервис для любых игроков, несколько одновременно пишущих агентов в одной области, Folia, полноценные мини-игры, произвольный доступ к серверной консоли, генерация 3D сторонними сервисами, автоматическая вокселизация мешей, универсальная физическая симуляция, произвольные скрипты с доступом к ОС и интеллектуальное перенесение любой ручной правки при смене геометрии.
Система помогает строить карты для мини-игр, но не реализует правила самих мини-игр. Автоматическая оценка красоты не является гарантией качества.
## 6. Компоненты и связи
Путь запроса: игровой чат → Paper-плагин → Bridge как ACP-клиент → `codex-acp` → Codex. Путь изменения: Codex → Minecraft MCP в Bridge → Paper-плагин → мир. Путь изображения: Codex → Minecraft MCP → Camera Worker → Fabric-клиент → изображение.
### Paper-плагин
Отвечает за команды, личности игроков, области, полномочия, снимки состояния блоков, валидацию планов, расписание применения и постоянную историю. Плагин проверяет ограничения независимо от того, что обещали агент и Bridge.
### Bridge
Запускает закреплённую версию `codex-acp`, реализует ACP-клиент и предоставляет инструменты Minecraft MCP. Хранит связь проекта с диалогом, форматирует сообщения для игрового чата и ограничивает объём данных, передаваемых модели. Не становится альтернативным источником истины о блоках.
`codex-acp` уже реализует преобразование ACP в операции Codex App Server, поддерживает изображения и подключение MCP-серверов. Поэтому отдельный ACP-адаптер Codex в проекте не пишется. Возможности конкретной закреплённой версии проверяются при установлении соединения. [Репозиторий codex-acp](https://github.com/agentclientprotocol/codex-acp).
### Camera Worker
Управляет очередью снимков и подключённым Fabric-клиентом. Хранит ракурсы, проверяет загрузку сцены и возвращает изображения с метаданными. Отказ камеры не уничтожает историю и не мешает чтению блоков; задача явно получает статус «визуально не проверено».
### Хранилища
Плагин хранит SQLite для метаданных и индексирования, а крупные снимки и изменения — в сжатых файлах с контрольными суммами. Он единственный писатель своей базы. Bridge отдельно хранит ACP-сессии и компактные сводки; Camera Worker — изображения. Общая база, которую одновременно напрямую меняют Java и Node.js, не используется.
Локальные соединения по умолчанию привязаны к loopback и защищены отдельными секретами компонентов. Для удалённой установки предполагается SSH-туннель или проверенное защищённое соединение; публичный доступ к интерфейсу изменения мира не нужен.
## 7. Сессии и игровой интерфейс
Основные команды, проектируемые для 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` и явные упоминания передаются только после проверки отправителя. Ответ по умолчанию виден инициатору; общий строительный канал можно добавить настройкой.
На проект назначается очередь запросов. В v0.1 один активный ход агента на проект; новые сообщения очередятся, а изменение задания во время работы требует согласованного прерывания. UUID игрока, UUID мира и идентификатор проекта берутся с сервера. Модель не может подменить их текстом запроса.
Bridge хранит идентификатор ACP-сессии, но проект не зависит от вечной доступности этого диалога. При невозможности возобновления создаётся новая сессия и передаются сводка проекта, текущая операция и ссылки на данные. Подключение к текущему диалогу настольного Codex автоматически не предполагается. Жизненный цикл сверяется с [ACP Session Setup](https://agentclientprotocol.com/protocol/v1/session-setup) и [ACP Prompt Turn](https://agentclientprotocol.com/protocol/v1/prompt-turn).
Чат показывает этапы и результат, а не каждую установку блока. Сообщения ограничены по длине и частоте. В сообщении о конфликте пользователь видит часть здания, место и последствия выбора; технические идентификаторы доступны в деталях.
## 8. Модель данных
**Project:** стабильный ID, владелец, участники, world UUID, world epoch, разрешённые области, политика блоков, настройки качества и краткая сводка замысла. Epoch меняется при восстановлении или замене мира, чтобы старые планы нельзя было применить к другой копии.
**Region:** измерение, включительные целочисленные границы `min/max`, ограничения чтения и записи. Координаты блоков хранятся целыми; камеры — вещественными. Высота и граница мира берутся из сервера. Локальные координаты рецептов имеют явно заданную точку привязки и преобразование в координаты мира.
**Part:** ID, имя, родитель, теги, точная маска блоков, ограничивающий объём, точка привязки, ревизия, режим защиты, ссылка на рецепт. Ограничивающий прямоугольник нужен для поиска и не означает владения всем его содержимым. В v0.1 редактируемые дочерние маски не пересекаются; родитель объединяет их.
**Recipe:** версия языка, версия генератора, параметры, палитра, seed, подчасти и преобразования. Одинаковые входы и версии должны порождать одинаковый план. Повороты преобразуют и координаты, и направленные состояния блоков. Неподдерживаемые преобразования отклоняются.
**Snapshot:** ID, мир и epoch, маска, канонические состояния блоков, ревизии секций и хеши. Снимок, собранный за несколько тиков, не объявляется глобально атомарным: изменившиеся во время сборки секции перечитываются или снимок помечается нестабильным.
**Plan:** неизменяемый ID и хеш содержимого, инициатор, область, базовый снимок, read set зависимостей, write set с `expected/desired`, группы взаимосвязанных блоков, срок действия и статистика. Read set включает опоры и свободные проходы, если от них зависит решение. План хранится на сервере; модели возвращается сводка.
**Operation:** ID, idempotency key, plan ID, состояние, номера порций, число подтверждённых записей, конфликты, автор, временные метки и связь с операцией отмены. Точное исходное и полученное содержимое хранится в постоянном журнале.
**Camera:** имя, мир, позиция, yaw/pitch, FOV, разрешение, профиль отображения. **Capture:** ID изображения, camera ID, время, связанная операция, сведения о загрузке и статус свежести. Снимок относится к моменту наблюдения, а не является атомарным изображением состояния всего сервера.
## 9. Строительный язык и рабочий цикл
В v0.1 агент передаёт JSON-программу: параметры, палитру и последовательность операций `box`, `line`, `cylinder`, `arch`, `repeat`, `transform`, `replace` и `paste`. Это проектируемые примитивы, а не существующие инструменты. Для `replace` обязательны маска области и фильтр исходных состояний.
Повторения ограничены счётчиком; разрешены только определённые числовые выражения и ссылки на параметры. Нет `eval`, бесконечных циклов, загрузки модулей, сети и файловых путей. Исполнитель имеет лимиты глубины, операций, памяти, времени и итогового числа блоков. Поддержка произвольного кода в будущем требует отдельного изолированного процесса с ограничениями ОС, а не запрета нескольких строк в скрипте.
Последовательность работы:
1. Агент узнаёт возможности сервера, активный проект, участок и ракурсы.
2. Запрашивает сводку рельефа и существующих частей; при необходимости — локальные блоки и снимок.
3. Формирует рецепт или точечную правку конкретной части.
4. Плагин создаёт снимок зависимостей, рассчитывает план и проверяет ограничения без записи в мир.
5. Агент получает объём, материалы, пересечения и предупреждения о непроверенных свойствах.
6. Допустимый план применяется порциями. Для обычной разрешённой постройки повторное подтверждение не требуется.
7. После применения выполняются структурные проверки и снимки выбранных ракурсов.
8. Исправление создаёт новую операцию. Число самостоятельных повторов ограничено; при отсутствии улучшения агент сообщает, что не удалось решить.
Рецепт не является единственным источником текущей геометрии. После ручного изменения агент обязан опираться на актуальный мир. В v0.1 нельзя просто повторно сгенерировать целую часть поверх текущего содержимого.
Качество постройки задаётся кратким замыслом проекта: назначение, масштаб относительно игрока, силуэт, палитра, основные материалы, входы, внутренние помещения и опорные ракурсы. Для крупной задачи агент сначала делает план объёмов, затем конструкцию, потом детали. Эти этапы остаются отдельными операциями, чтобы удачный силуэт не терялся при неудачной детализации. Пустой интерьер считается допустимым только тогда, когда он соответствует заданию.
Структурная проверка v0.1 подтверждает заявленные размеры, границы, состояния блоков и фактическое завершение плана. Смысловые свойства вроде удобства навигации, баланса арены и красоты фасада оцениваются отдельно и не выдаются за результат простого сравнения блоков.
## 10. Ручные изменения и конфликты
Сравнение выполняет серверный код. Модель не получает полный список блоков для самостоятельного вычисления разницы.
Для обычной записи используются базовое состояние `B`, текущее `C` и желаемое `D`:
- `C = B`: запись `D` допустима, если неизменны зависимости и соблюдены права.
- `C = D`: блок уже соответствует результату; запись не требуется и не включается в новую историю как наша работа.
- Иначе: конфликт. Состояние не перезаписывается автоматически.
В v0.1 при обнаружении ручного расхождения внутри перестраиваемой части автоматическая повторная генерация этой части останавливается. Агент может подготовить локальный план, который явно сохраняет текущую геометрию, либо строить другую, незатронутую часть.
Для v0.2 предлагается трёхстороннее объединение: сравниваются предыдущий сгенерированный результат `G0`, текущий мир `C` и новый результат `G1`. Если `G1 = G0`, ручная правка сохраняется; если `C = G0`, можно принять новую геометрию; если `C = G1`, запись не нужна; остальные пересечения требуют решения. Это объединение по координатам, а не понимание смысла окна или лестницы.
Пример: ручное окно в неизменяемой стене сохраняется при добавлении верхних этажей. Если новый этаж сдвигает всю стену, система не знает автоматически, куда перенести окно. В v0.1 такая перестройка останавливается и предлагается локальный новый план. Автоматическое перенесение поправок в координатах рецепта относится к следующей версии.
При заранее найденном конфликте план не начинает запись. Если конфликт возник во время выполнения, операция останавливается перед следующей затронутой группой и возвращает частичный результат. Она не продолжает молча строить остальные фрагменты: это может оставить конструкцию геометрически неверной.
Варианты разрешения: сохранить текущий мир и перепланировать; исключить защищённую часть; по явному решению владельца заменить конкретный конфликтующий фрагмент. Новый выбор создаёт новый план от свежего состояния. Глобального режима «игнорировать все конфликты» в инструментах агента нет.
События игроков, природных изменений и интеграция WorldEdit ускоряют обновление ревизий. Однако не все сторонние плагины обязаны вызывать одинаковые события. Поэтому хеши и ревизии служат ускорением, а проверка живых блоков непосредственно перед записью остаётся обязательной. Неизвестный источник изменения называется «внешнее изменение», а не приписывается игроку.
Серверная проверка защищает текущее содержимое. Если неподконтрольный плагин изменил блок и вернул его обратно между проверками, одно сравнение содержимого не восстановит эту историю. Полная авторская история всех возможных изменений мира не обещается.
## 11. Применение, остановка и восстановление
Состояния операции: `prepared` → `queued` → `applying` → `applied`. Ветви завершения: `conflict`, `cancelled`, `failed`, `recovery_required`. Каждое состояние сопровождается количеством реально подтверждённых блоков: даже `cancelled` может означать частично изменённый мир. Визуальная проверка имеет отдельный статус `pending/passed/needs_changes/unavailable`; снимок не определяет завершённость записи.
Подготовка геометрии, сжатие, работа с файлами, сеть и запросы к модели выполняются вне игрового потока. Чтение и изменение живого мира выполняются через допустимые серверные API в серверном потоке. Такой подход соответствует ограничениям [Paper Scheduler](https://docs.papermc.io/paper/dev/scheduler/).
Алгоритм порции:
1. Сформировать ограниченную группу изменений и зависимости от её окружения. Общий диспетчер плагина сериализует пересекающиеся операции по UUID мира и области, в том числе между разными проектами. Блокировка одного проекта не считается достаточной защитой.
2. В серверном потоке прочитать фактическое исходное состояние и подготовить запись намерения с `before/after`, ID группы и контрольной суммой.
3. Сохранить намерение в постоянный журнал вне серверного потока и дождаться подтверждения сохранения. До этого мир не меняется.
4. Вернуться в серверный поток; повторно проверить полномочия, epoch, ограничения, ожидаемые состояния и зависимости. При изменениях остановиться до записи этой группы.
5. В том же серверном шаге без уступки управления применить допустимую небольшую группу, проверить результат и зарегистрировать фактически изменённые блоки. Запись намерения со статусом пропуска или ошибки также сохраняется.
6. Зафиксировать завершение группы и только затем продолжить следующую. Обновить сводку операции и инвалидировать затронутые кэши.
План должен объявлять зависимости. Если часть зависит от ранее обработанных блоков, последующие проверки учитывают уже подтверждённые значения самой операции. Изменение важной опоры после её обработки приостанавливает дальнейшие зависимые шаги. Полная согласованность всего здания на протяжении многих тиков без блокировки всех внешних писателей не гарантируется; после записи нужна итоговая проверка.
Обычная ручная правка не вклинивается между проверкой и записью одной серверной порции. Но даже порция не является ACID-транзакцией Minecraft: исключение, вложенные события или физика могут дать частичное изменение. Исполнитель записывает фактический результат, а операция останавливается. Для составных объектов задаются маленькие неделимые логические группы и отдельные правила проверки. Поддержка таких групп не означает атомарности при падении процесса.
`/ai stop` имеет два независимых действия: ACP-отмена хода модели и серверный флаг отмены операции. Остановка модели сама по себе не отменяет уже запущенную запись. Плагин проверяет флаг перед каждой порцией; выполненные изменения остаются в истории. Потеря Bridge запрещает запуск новых порций после короткого таймаута соединения; выполненная порция не повторяется вслепую.
Все изменяющие запросы имеют idempotency key, связанный с проектом и хешем содержимого. Повтор с тем же ключом и тем же планом возвращает существующую операцию; тот же ключ с другим содержимым отклоняется. Повтор после сетевого таймаута начинается с запроса состояния операции.
После сбоя плагин обнаруживает незавершённые группы и переходит в `recovery_required`. Сохранение файлов мира и журнала не является одной общей транзакцией. Поэтому при запуске выполняется сверка живого мира с `before/after`: старое значение, новое значение либо постороннее состояние. Ни неизвестное состояние, ни неоднозначная история не перезаписываются автоматически. Возобновление или отмена строятся как новый проверенный план; запись блоков по одному лишь последнему статусу журнала запрещена.
Отмена создаёт обратную операцию только для фактически записанных нами блоков. Она возвращает `before`, если текущее состояние совпадает с подтверждённым `after` и нет известной более поздней записи другого действия. Для известного последующего изменения возвращается конфликт, даже если итоговое значение случайно совпало. Для неизвестных внешних действий остаётся ограничение проверки по содержимому из раздела 10.
Производные эффекты — течение воды, падение песка, изменения инвентарей, рост растений, обновления редстоуна — не восстанавливаются простым обратным списком блоков. В v0.1 такие сценарии исключены из гарантируемой строительной области. Журнал не заменяет резервную копию мира. Поддержка полноценной симуляции побочных эффектов потребует отдельного дизайна.
Проверка учитывает поддерживаемое окружение, а не только заменяемые блоки: удаление камня под песком или рядом с водой тоже может запустить побочный эффект. Для первой версии используется контролируемая строительная область; обнаруженное неподдерживаемое окружение останавливает подготовку. Абсолютная изоляция от произвольных плагинов и физики соседнего мира не обещается.
## 12. Экономия контекста
Модель получает сведения, необходимые для решения. Полные снимки, списки блоков, история и вычисление разницы находятся на стороне системы. Неизменённые данные не отправляются заново без причины.
Уровни чтения:
1. Сводка проекта: назначение карты, палитра, области, части, активная задача, ограничения и последняя проверка.
2. Сводка участка: высоты поверхности с заданным шагом, материалы, занятые объёмы и ссылки на части. Неизвестные свойства отмечаются явно. Система не обещает автоматически распознавать здания в произвольном старом мире.
3. Изменения с курсора: количество блоков, затронутые части и ограничивающие объёмы; подробности доступны страницами.
4. Небольшой точный фрагмент: палитра состояний и сжатое представление координат либо срез. Распаковка миллионов блоков в текст не допускается.
5. Изображение нужного ракурса: сначала общий вид, затем детали проблемного участка.
Сводка о правке формируется детерминированно: например, «34 блока изменены, 6 пересекаются с планом». Формулировка «игрок добавил окно» возможна только как вывод модели или подтверждённая метка, а не как достоверный результат простого diff.
Курсоры изменений включают world epoch, область, позицию журнала и версию схемы. После очистки журнала, потери наблюдения или замены мира ответ — `resync_required`, а не пустой список изменений. Bridge запрашивает новую локальную сводку. Сторонние изменения, не попавшие в события, ищутся повторной проверкой выбранных секций; дельты не объявляются полным журналом всего сервера.
Обычный ответ инструмента стремится укладываться в 2–4 тысячи токенов; точные ограничения задаются также числом элементов и байтов. При превышении возвращаются счётчик, курсор и признак усечения. Сжатые бинарные блоки и base64-изображения не вставляются в текст: снимок возвращается как изображение MCP, крупные данные остаются артефактами с ID.
Начальный бюджет одной визуальной проверки — 2 общих ракурса, при необходимости до 4 дополнительных. Серии кадров не отправляются постоянно. Начальный лимит самостоятельных циклов исправления — 3; это настраиваемая политика, а не ограничение возможностей модели.
Нельзя обещать фиксированную цену задачи: она зависит от модели, тарифа, истории, числа изображений и повторов. Bridge учитывает фактически доступные сведения об использовании и размеры ответов. Процент экономии относительно передачи всего мира нужно измерить на тестовых задачах.
## 13. Виртуальные камеры
Камера — сохранённый ракурс, а не обязательная сущность или блок в мире. Один Camera Worker последовательно обслуживает несколько ракурсов. Одновременные независимые виды не входят в v0.1.
Для съёмки клиент наблюдателя перемещается к нужному месту, чтобы сервер прислал соответствующие чанки. Недостаточно сместить только матрицу камеры далеко от игрока: клиент может не иметь данных окружающего мира. Перемещение ограничено разрешёнными областями и измерениями; учётная запись камеры не получает права редактирования.
Процедура съёмки:
1. Дождаться подтверждения завершения нужной операции на сервере.
2. Установить мир, позицию, ориентацию, FOV и профиль отображения.
3. Дождаться клиентской загрузки обязательных чанков и доступных сигналов завершения перестройки геометрии, затем нескольких кадров стабилизации.
4. Снять кадр без HUD и посторонних интерфейсов, вернуть изображение и метаданные.
5. Проверить, не менялась ли наблюдаемая область во время съёмки. При обнаруженных изменениях пометить изображение как потенциально устаревшее и предложить повтор.
Подтверждение сервера ещё не означает, что клиент уже отобразил все изменения. Точный критерий готовности рендера нужно проверить прототипом на выбранной версии Fabric. При таймауте возвращается `capture_not_ready`; старый кадр не выдаётся за новый. Проверка ревизий не гарантирует отсутствия неотслеживаемых внешних изменений.
Начальный профиль — стандартный ресурспак, без шейдеров, одинаковые FOV и разрешение для сравнения. Время суток и погода фиксируются только явно выбранным режимом проверки; ради красивого скриншота глобальный мир самовольно не меняется. Ракурсы внутри помещений проверяются на попадание камеры в непрозрачный блок.
Автоматический обзор предлагает вход, противоположную сторону, диагональ сверху и заданные внутренние точки. Положение рассчитывается по границам части и уточняется по препятствиям. Пользователь может сохранить свои ракурсы. Пиксельное различие снимков не является метрикой красоты: его используют только как вспомогательный сигнал.
Клиент требует графического рендеринга. Запуск без видимого окна не означает отсутствие GPU/графического контекста и не обещается до проверки. Работа рендера в Fabric меняется между версиями, поэтому мод камеры изолируется от остальных компонентов. [Рендеринг Fabric](https://docs.fabricmc.net/develop/rendering/basic-concepts).
## 14. Предлагаемые MCP-инструменты
Ниже — контракт проекта, а не перечень уже реализованных функций. Каталог разделяется на чтение, подготовку и изменение. Полномочия связаны с подключением, проектом и инициатором; передача `project_id` сама по себе не даёт доступа.
- `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)` — проверить файл и создать план вставки.
Создание проекта, расширение разрешённой области, выдача прав и снятие защиты относятся к пользовательскому/административному управлению. Агент не может сам расширить свои полномочия вызовом инструмента.
Общий ответ содержит `schema_version`, `request_id`, `status`, идентификатор мира/epoch, краткую сводку, `warnings`, `truncated` и курсор при необходимости. Чтение указывает момент и полноту наблюдения; изменение всегда возвращает operation ID. Большая операция асинхронна и не должна требовать одного MCP-вызова, открытого на всё время строительства.
Структурированные ошибки: `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.
Минимальный протокол между Bridge и плагином версионируется отдельно от MCP/ACP. Каждый запрос содержит correlation ID; команды выполняются от проверенного принципала с ограниченными возможностями, а не от имени произвольного UUID из тела запроса. Ключи и токены не попадают в видимые модели ответы.
## 15. Хранение, импорт и перенос
Планируемая структура репозитория: `bridge/`, `paper-plugin/`, `camera-mod/`, `protocol/`, `fixtures/`, `docs/`. В этом документе она описана как будущая; исходный код ещё не создан.
Постоянные данные хранятся вне исходного кода и вне игровых блоков:
- На сервере: проекты, области, части, планы, журнал, снимки, рецепты, версии схемы и настройки доступа.
- У Bridge: связь диалогов с проектами, локальная сводка, состояние подключений.
- У камеры: ракурсы, профили и изображения с ID операций.
- В библиотеке: `.schem`, превью и метаданные происхождения, версии, размеров, точки привязки и лицензии.
Потеря Bridge не теряет историю блоков. Потеря базы плагина не удаляет постройки, но лишает систему достоверных рецептов и отмены. Отсутствие базы не даёт права повторно проиграть старые планы.
Очистка журнала сохраняет данные активных операций, восстановления и явно закреплённых контрольных точек. Истёкшая история делает соответствующую отмену недоступной; об этом сообщается прямо. Квота диска проверяется до начала записи, а при невозможности сохранить журнал новые изменения останавливаются. Конкретные сроки хранения выбираются после измерения объёма.
Импорт работает с локальным asset ID, не с произвольным путём или URL модели. Проверяются формат, распакованный объём, число блоков, версия, разрешённые состояния и данные block entities/сущностей. Неподдерживаемое содержимое отклоняется с отчётом, а не молча теряется. Схематика сначала превращается в план и проходит тот же путь конфликтов, что обычное строительство. Форматы загрузки и сохранения предоставляет [WorldEdit Clipboard](https://worldedit.enginehub.org/en/latest/usage/clipboard/).
Для переноса здания экспортируется `.schem`; для переноса карты сохраняется согласованная резервная копия мира и проверяются измерения и настройки. Метаданные редактора можно приложить отдельным архивом. Перенос на другую серверную основу проверяется на копии и той же версии Minecraft; обратная совместимость со старыми версиями не обещается. Раскладка измерений зависит от серверной основы. [Миграция Paper](https://docs.papermc.io/paper/migration/).
## 16. Полномочия и эксплуатационные ограничения
Агент получает доступ только к выбранной строительной области и разрешённому набору инструментов. По умолчанию нет серверной консоли, выдачи OP, изменения плагинов, управления аккаунтами, внешней сети и чтения произвольных файлов через Minecraft MCP.
Codex запускается в отдельном рабочем каталоге с минимальными правами. Его собственные shell/file-инструменты не должны обходить серверные ограничения или читать секреты Bridge. Конкретный механизм изоляции процесса и доступные режимы закреплённого Codex проверяются в первом прототипе. Подключение MCP само по себе не ограничивает остальные инструменты агента.
Если Codex/ACP требует разрешение, Bridge связывает запрос с реальным инициатором и показывает конкретное действие. Чужое сообщение в чате не считается разрешением. Отмена и истечение срока закрывают ожидающий запрос. Обычная запись в заранее разрешённой области не должна порождать лишние подтверждения, но это не отменяет ограничения профиля Codex.
Текст табличек, названия предметов, импортированные метаданные и чужие сообщения рассматриваются как данные мира. Они не могут менять полномочия, системные инструкции или назначение проекта.
Один серверный план проверяет права и при подготовке, и перед исполнением порций. Отзыв доступа, изменение области или world epoch прекращает дальнейшую запись. При занятости участок ставится в очередь либо возвращает `busy`; скрытой конкуренции между нашими писателями нет.
## 17. Первоначальные бюджеты и наблюдаемость
Следующие числа — стартовые настройки прототипа, а не измеренные показатели производительности:
- До 100 000 изменяемых блоков в одном плане; более крупная стройка делится на осмысленные части.
- До 2 000 000 исследуемых позиций в одной операции подготовки; большая область требует грубого обзора и последующего уточнения.
- Порция записи — не более 512 блоков и целевой предел 5 мс работы нашего исполнителя на тик. Проверка времени идёт между маленькими логическими группами; одна дорогая операция API может превысить цель.
- При перегрузке или росте времени тика размер порции уменьшается, новые порции приостанавливаются. Скорость «блоков в секунду» не фиксируется до замеров.
- Точный текстовый ответ — до 4 096 блоков; страница событий — до 100 элементов; превышение обрабатывается усечением с курсором, а не скрытой потерей данных.
- Кадр по умолчанию — 1280×720; таймаут готовности 20 секунд; не более одной активной съёмки на Worker.
- План действует 10 минут, но проверяется перед применением независимо от возраста. По истечении строится новый план.
- Сигнал остановки принимается сразу; целевой срок прекращения новых порций — до 1 секунды при здоровом сервере и соединении. При зависшем игровом потоке это не гарантия реального времени.
Измеряются длительности подготовки и порций, время тика с задачей и без неё, объём журнала, размер ответов модели, число снимков и повторов, конфликты, отставание камеры и время остановки. Корреляция строится по project/request/operation/capture ID.
Токены и стоимость отображаются только по доступным фактическим данным провайдера; отсутствие данных не равно нулю. Не сохраняются скрытые рассуждения модели. Диагностические логи не содержат секретов и по умолчанию не копируют полный игровой чат.
## 18. Этапы реализации и критерии готовности
### Этап 0 — проверка совместимости
Поднять тестовый мир на копии, закрепить версии, проверить ACP-сессию через `codex-acp`, вызов простого MCP-чтения и получение моделью одного изображения. Проверить подключение камеры к Paper, допустимую отдельную сессию наблюдателя и изоляцию Codex.
Готовность: сообщение из игры доходит до агента; агент получает данные тестового блока и свежий снимок; версии и ограничения записаны. При отсутствии совместимого мода/WorldEdit пересматривается версия платформы до начала строительства реальной карты.
### Этап 1 — безопасная запись без агента
Реализовать области, канонические состояния, подготовку плана, порции, idempotency, журнал, конфликт, отмену и восстановление. Проверять прямым тестовым клиентом: работа базового движка не зависит от качества ответов модели.
Готовность: сервер сохраняет ручную правку между подготовкой и применением; повтор запроса не дублирует работу; отмена не перезаписывает более позднюю правку; остановка и перезапуск дают честное состояние частичного результата.
### Этап 2 — строительный API и чат
Добавить примитивы, палитры, повторения, части, MCP-инструменты, очередь ACP и компактные сводки. Строительство маленького здания должно требовать геометрической программы, а не списка отдельных вызовов установки блоков.
Готовность: из чата создаётся башня с именованной крышей; правка крыши оставляет стену и вручную добавленное окно; конфликт лестницы с ручным окном возвращает точное пересечение.
### Этап 3 — визуальный цикл
Добавить сохранённые камеры, готовность чанков/рендера, метаданные свежести и связку кадров с операциями. Агент выполняет ограниченное число осмысленных правок по снимкам.
Готовность: повторный кадр показывает завершённую правку; незагруженная сцена выдаёт ошибку; пользовательский вид при работе отдельной камеры не переключается. Визуально плохой результат может быть признан плохим, даже если техническая запись успешна.
### Этап 4 — перенос и выпуск v0.1
Добавить `.schem`, локальную библиотеку, копирование проекта и процедуру резервирования. Проверить работу без компонентов редактора на копии мира.
Готовность: эталонная постройка проходит экспорт/импорт с совпадением поддерживаемых состояний и ориентаций; неподдерживаемые данные не теряются молча; инструкция запуска воспроизводима на чистом окружении.
## 19. Приёмочные сценарии
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. **Перенос.** Открыть копию мира без нашего плагина и камеры. Постройка остаётся; потеря функций редактора не меняет блоки.
Алгоритмы разницы, ограничений, преобразований и idempotency проверяются модульно; потоки, физика, журнал и камера — на настоящем тестовом сервере/клиенте. Моки не доказывают корректность поведения Minecraft. Эти проверки запланированы, но ещё не выполнены.
## 20. Что заимствуем из Blender MCP
Из [Blender MCP](https://github.com/ahujasid/blender-mcp) берём сочетание осмотра сцены, работы с именованными объектами, компактного программного построения, изображений и библиотеки ассетов. В Minecraft это превращается в осмотр региона, маски частей, геометрический язык, камеры и `.schem`.
Собственные дополнения проекта: согласование с ручными правками, серверные порции, журнал до записи, восстановление после сбоя, курсоры дельт и проверка поддерживаемых состояний. Наличие этих функций у Blender MCP не утверждается. Произвольное выполнение Python и сторонние сервисы генерации 3D не копируются в первую версию.
## 21. Открытые вопросы и последующие версии
Вопросы не блокируют завершение этого документа; они определяют работы этапа 0 и решения перед соответствующей функцией:
- Какие точные версии WorldEdit и Fabric совместимы с выбранной веткой 26.2? Если нет общей рабочей комбинации, какую поддерживаемую версию выбрать до строительства карты?
- Где запускается камера и есть ли отдельная игровая сессия для неё? Рабочий вариант — отдельный локальный клиент; запасной — камера в клиенте пользователя.
- Можно ли получить надёжный сигнал готовности геометрии на выбранной версии клиента? Если нет, какой проверяемый критерий свежести достаточен и какие ограничения показывать?
- Использовать ли WorldEdit для фактической записи либо только для форматов и выделений? Решение определяется контролем момента записи, побочных эффектов и времени порции.
- Какие блоки и соседние обновления проходят тесты гарантированной отмены? Расширение списка требует тестов, а не только добавления ID.
- Какое оборудование и размер проектов считать целевыми? До замеров значения раздела 17 остаются бюджетами прототипа.
v0.2 может добавить трёхстороннее объединение рецептов с ручными поправками, составные блоки, проверку проходов и маршрутов, библиотеку параметрических деталей и более удобное сравнение ракурсов. Для неизвестных построек возможна ручная регистрация частей, позже — предложенная моделью сегментация с проверкой.
Дальнейшие направления: Fabric-адаптер встроенного сервера для одиночной игры; командное строительство в независимых областях; несколько камер; инструменты проверки мини-игровых карт; изолированные строительные скрипты общего назначения. Они не должны задерживать проверку базового цикла «запрос → план → запись → наблюдение → правка».
## 22. Итоговые критерии проекта
Успех первой версии означает, что пользователь может построить и уточнить небольшое здание из игрового чата, агент видит результат, ручная правка не затирается молча, отмена имеет честные ограничения, контекст не заполняется полным миром, а карту можно использовать без редактора.
Этот документ фиксирует архитектуру и проверяемые требования. Он не подтверждает готовность прототипа, производительность, совместимость всех зависимостей или качество архитектурных решений модели.
+57
View File
@@ -0,0 +1,57 @@
# Состояние реализации
Первый прототип собран и проверен на настоящем локальном Paper 26.2, включая графический клиент камеры в Prism и передачу изображения через MCP. Он ещё не закрывает всю v0.1 из [дизайна](DESIGN.md): первый авторизованный ход Codex через ACP остаётся непроверенным.
## Реализованные компоненты
`world-core` содержит независимый от Bukkit редактор. Декларативный рецепт превращается в неизменяемый план с исходными и желаемыми состояниями, явными зависимостями чтения и сроком действия. Перед записью выполняется проверка; непосредственно при записи состояния сверяются повторно. Дисковые намерения сохраняются до изменения мира, результаты — после порции. Файловый ввод-вывод вынесен с серверного потока. Отмена останавливает следующие порции; уже записанное остаётся в истории.
`paper-plugin` привязывает это ядро к серверному потоку, проверяет владельца, мир, эпоху, область и защищённые части. HTTP доступен только на loopback, с отдельными ключами администратора и агента. Плагин регистрирует `/ai`, хранит небольшую очередь чата, пересылает ответы только инициатору и управляет телепортацией наблюдателя. Журнал и метаданные находятся в каталоге плагина, игровые блоки остаются ванильными.
`bridge` предоставляет 14 инструментов MCP по stdio, принимает события чата Paper и запускает закреплённый `codex-acp`. Диалоги разделены по игроку и проекту, очередь сериализована, остановка распространяется на ACP. Идентификатор сессии и компактная сводка сохраняются. Агент получает отдельный MCP-токен; ключ администратора остаётся у Bridge. Большие ответы ограничены, изображения передаются как MCP image content.
`camera-mod` содержит локальный HTTP Worker и захват framebuffer Minecraft 26.2. Камера ждёт spectator, нужную позицию и измерение, доступность соседних чанков и стабилизацию кадров. Настройки HUD/FOV восстанавливаются после снимка или ошибки. На настоящем клиенте Prism проверены Mixin, серверная телепортация и валидные PNG с нескольких ракурсов. Владелец и наблюдатель использовали один UUID.
## Подтверждённые проверки
Текущая сборка: **100 автоматических тестов без ошибок** — 52 в ядре, 17 в Paper-модуле, 20 в Bridge и 11 в модуле камеры. Оба JAR собраны; результаты Java находятся в XML-отчётах Maven/Gradle, общий лог этой проверки — `.runtime/build-final.log`.
Автоматические Java-тесты проверяют геометрию, ограничения, идемпотентность, зависимости чтения, конфликты, прерывание порции, отмену, undo, журналирование, ошибки диска, восстановление и отдельные HTTP/NBT-контракты. Тесты Bridge используют настоящий MCP stdio и имитатор ACP для диалогов, разрешений, отмены и возобновления. Камера имеет проверки HTTP-аутентификации и валидации, без запуска графического клиента.
На настоящем Paper, в отдельном созданном тестовом мире, успешно выполнены:
- Изменение блока после подготовки плана: операция завершается конфликтом, чужой блок сохраняется.
- Изменение явной зависимости: применение останавливается до записи.
- Постройка, повтор с тем же ключом и проверяемая отмена; при более поздней внешней правке 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).
Реальный `codex-acp` прошёл `initialize` в отдельном профиле без входа: ACP v1 и поддержка загрузки сессии подтверждены. Это ещё не проверка хода модели или вызова инструментов после авторизации. Тесты не вызывали модель и не расходовали её токены.
## Существенные границы
**Ручные изменения.** Сравнение ожидаемого и текущего состояния защищает от отличающегося блока непосредственно перед записью. Известные события установки/ломания игроком дополнительно инвалидируют владение блока для undo, даже если игрок вернул прежний материал. Полного перехвата изменений других плагинов, команд, физики и всех переходов A→B→A нет; ревизии известных внешних событий пока не сохраняются между запусками. Нельзя считать этот прототип универсальной системой слияния любых параллельных правок.
**Авария.** JSON-журнал с fsync заменяет запланированную SQLite. Мир Minecraft и наш журнал не образуют одну транзакцию. Неоднозначная операция после сбоя блокирует новые записи. Доступен явный административный обзор и отказ от продолжения по свежему digest, без изменения мира и с отключением неоднозначного undo. Автоматического replay/rollback нет. Полный журнал загружается при старте и пока не имеет архивирования.
**Область и производительность.** Один владелец, проект и мир; не более 4096 блоков и 512 явных зависимостей на план. Запись — до 128 блоков с целевым бюджетом до 5 мс на порцию; стоимость проверки и JVM не позволяют заявлять жёсткую гарантию времени тика. Полная подготовка ограниченного плана пока выполняется на серверном потоке. Долговременные нагрузочные проверки на большом сервере не проводились.
**Контекст.** Контекст проекта содержит краткие метаданные, до 20 операций и до 64 частей; точные блоки читаются отдельно. `region_changes` пока возвращает `resync_required`. Поэтому агент повторно читает выбранные участки; обещание «читает только дельты» ещё не реализовано. Диалог ACP имеет сохранение и сводку, но расход модели здесь не измерен.
**Блоки и схематики.** Разрешён ограниченный набор из 61 ванильного материала, включая часть ступеней и плит; точный список возвращает `project_context`. Waterlogged, контейнеры, двери, redstone и другие сложные блоки не поддерживаются. Проверка окружающих блоков намеренно ограничивает использование возле неподдерживаемой среды. Sponge v2 `.schem` реализован без зависимости от WorldEdit: до 4096 блоков, до 64 файлов, повороты кратно 90°, без сущностей, block entities и биомов, без преобразования между версиями игры. Неподдерживаемый контент отвергается, а не удаляется при экспорте.
**Строительный язык.** Есть box, line, cylinder и repeat. Арки, произвольные трансформации, декоративные палитры, исполнение JavaScript/Python и автоматическое согласование рецептов с ручными правками пока отсутствуют. Зарегистрированная часть содержит точную маску фактически записанных блоков, а не весь её bounding box.
**Камера.** Нужен настроенный spectator-клиент; в проверенном сценарии это тот же игрок, что и владелец проекта. Во время снимка он не может продолжать обычное строительство. Автоматического возврата режима и исходной позиции нет. Готовность кадра эвристическая: `serverRevisionVerified: false`. Доступность соседних чанков и стабильность рендера не доказывают получение всех серверных обновлений. Реальная стройка и снимки проверены; сторонние шейдеры, отключение посреди кадра и все варианты зависания окна ещё не проверены.
**ACP.** Выделены отдельные HOME/CODEX_HOME, отключены лишние интеграции, shell и передача административного токена. Это не изоляция на уровне ОС. Закреплённый адаптер переводит режим `read-only` в `workspace-write`; временные пути могут оставаться доступными, а закреплённый CLI оставляет флаг `unified_exec` включённым при отключённом `shell_tool`. Дополнительные запросы разрешений пока отклоняются. Поведение разрешений динамического Minecraft MCP требует проверки первого настоящего хода. Подробности и диагностика — в [Bridge README](../bridge/README.md).
## Следующий приёмочный этап
1. Пользователь входит в выделенный Codex-профиль, подключается к Paper и привязывает владельца. Проверяем маленькую постройку из игрового `/ai`, поток ответа, использование MCP и отмену.
2. Расширяем проверенный сценарий Prism с одним клиентом: проверяем отключение/зависание посреди снимка и удобное переключение между строительством и камерой.
3. Проходим цикл «построил → посмотрел → исправил» и только после этого уточняем готовность релиза, лимиты, дельты контекста и расширение геометрии.
+48
View File
@@ -0,0 +1,48 @@
# Проверка с одним клиентом Prism
Проверка выполнена в существующем профиле **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`.
Пользователь выбрал автономный профиль для локального теста. В этой рабочей установке `.runtime/server/server.properties` содержит `online-mode=false`, `server-ip=127.0.0.1`, `server-port=25575`; слушающий адрес не расширялся. Это изменение тестовой конфигурации, обычная первоначальная подготовка `dev-server.py` по-прежнему включает проверку аккаунта.
В приватном конфиге плагина `owner-uuid` и `camera-player-uuid` совпадают. Игроку выданы права оператора на этом тестовом сервере; `allow-local-automation` остаётся выключенным, все вызовы выполнялись с областью владельца. Для фотографий режим временно менялся на spectator. После проверки игрок возвращён в creative на платформе перед башней; автоматического переключения внутри плагина пока нет.
## Что проверено
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.
Все изображения — исходные данные Minecraft framebuffer. Они не генерировались нейросетью и не ретушировались. `serverRevisionVerified: false` остаётся честным ограничением: клиентская готовность пока эвристическая. Первый ход модели через `codex-acp` этим тестом не проверялся.
Локальные результаты:
- `.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.
Башня оставлена для осмотра около `12, 95, 12`, на платформе `x/z=4..20`, `y=94`. Она пересекает область автоматических серверных тестов. Перед их повторным запуском нужен отдельный чистый тестовый мир или проверяемая отмена этой операции; тесты сами не удаляют занятую область.
## Повторение снимка
В Prism у профиля настроен wrapper `python3 /путь/к/minecraft-builder-mcp/scripts/camera-wrapper.py`. Он читает приватный ключ камеры из Paper config и передаёт только процессу Java через окружение. Секрет не помещается в `instance.cfg` или командную строку. Исходный `instance.cfg` и `options.txt` сохранены в `.runtime/prism-one-client-backup`.
После подключения, из игры:
```text
/gamemode spectator
/ai camera save test
```
Сохранять ракурс нужно внутри выбранной области. Из корня проекта:
```bash
python3 scripts/live-camera-test.py --delay 8
```
Вернуться в окно Minecraft, закрыть меню/чат и не двигаться до завершения. Скрипт сохраняет новый PNG и очищенные метаданные. Затем можно вручную выполнить `/gamemode creative`.
`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`.
+73
View File
@@ -0,0 +1,73 @@
# Протокол прототипа
Версия: 1. Точный реализованный каталог инструментов доступен через MCP `tools/list`, а возможности установленного Paper — через `project_context`.
## Соединение с Paper
Сервис слушает только loopback, по умолчанию `127.0.0.1:8765`. `GET /health` возвращает состояние и версию без приватных данных. `POST /v1/rpc` принимает JSON и заголовок `Authorization: Bearer <token>`.
Запрос: `{ "method": "project_context", "params": { "player_id": "UUID", "project_id": "default" }, "requestId": "correlation-id" }`.
Успех: `{ "ok": true, "result": { ... } }`. Ошибка: `{ "ok": false, "error": { "code": "...", "message": "..." } }`. Ошибка может сопровождаться HTTP 400/403; клиент обязан читать структурированное тело. Токены в результатах не возвращаются.
Административный ключ обязателен для `chat_poll`, `chat_reply`, `recovery_review` и `recovery_abandon`. Ключ агента допускает инструменты мира в проекте связанного владельца, но не административное восстановление. `player_id/project_id` добавляются MCP-процессом из настроек, а не предлагаются модели. Плагин повторно проверяет владельца и его действующие права. Для изолированного тестового мира есть явно включаемый `allow-local-automation` и принципал `console`; административные операции восстановления также проходят проверку этой области полномочий.
## Чтение и запись
`region_inspect` требует `min/max` как `{x,y,z}` и `detail: "summary" | "blocks"`. Координаты включительные, целочисленные. Лимит прототипа — 4096 позиций. Ответ содержит палитру с количеством, а для `blocks` — точные состояния. Данные берутся из загруженных чанков без неявной генерации мира.
`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.
Результат подготовки: `plan_id`, `plan_hash`, `changed_blocks`, `region`, `expires_at`. Полный план и исходные блоки остаются в журнале. `build_apply` принимает этот ID, хеш и постоянный для данного вызова `idempotency_key`. Повтор того же вызова возвращает ту же операцию. Для другого плана нужен другой ключ.
`operation_status(operation_id)` возвращает состояние, счётчики и ограниченные примеры конфликтов. `operation_cancel` останавливает следующие порции. `operation_undo_prepare` создаёт обратный план; он проходит обычный `build_apply` и проверки. Потеря ответа на применение не даёт права создать другой ключ и повторить запись: сначала проверить `project_context` или повторить исходный вызов с тем же ключом.
`part_define(name,operation_id)` регистрирует только фактически записанные блоки завершённой операции. `part_get(part_id)` возвращает имя, границы, количество и защиту. Границы не равны маске: `build_prepare(part_id)` проверяет каждый блок по точной маске. Расширение создаётся отдельной частью.
Перед записью проверяются реальные состояния целевых блоков и объявленных зависимостей; проверка повторяется после сохранения намерения. Несовпадение не перезаписывается автоматически. Для undo также учитываются известные последующие записи наших операций, даже когда значение блока снова совпадает с прежним результатом.
Плагин наблюдает неотменённые `BlockPlaceEvent` и `BlockBreakEvent` в настроенном мире. Такое событие лишает прежнюю операцию права на undo данного блока, включая случай «изменили и вернули обратно» (ABA). Эти уведомления хранятся только в памяти текущего процесса. После перезапуска и для внешних путей без наблюдаемого события остаётся проверка текущего содержимого; полная история действий других плагинов не обещается.
Полный серверный журнал внешних изменений пока не реализован. `region_changes` отвечает `resync_required`; агент использует свежие ограниченные чтения. Это явное ограничение прототипа.
## Восстановление после сбоя
Незавершённая операция после перезапуска получает `recovery_required` и запрещает начало новых записей. Автоматического повторения незавершённых порций нет. Административные RPC ниже не входят в MCP-инструменты агента и не являются откатом мира.
`recovery_review` принимает `operation_id`. Результат использует имена полей Java-записи: `operationId`, `planId`, `positions`, `matchesBefore`, `matchesAfter`, `foreignStates`, `currentDigest`, `sampledAtMillis`. Проверяемая маска объединяет фактически подтверждённые записи предыдущих порций и потенциальные записи незавершённой порции; пропуски без записи не включаются. Счётчики описывают совпадение текущих значений с `before/after`, а `currentDigest` — SHA-256 для этого снимка. Совпадение содержимого не доказывает авторство изменения.
`recovery_abandon` принимает `operation_id` и `expected_digest`, полученный из `currentDigest` последнего обзора. Сервер заново читает маску и отклоняет запрос, если её содержимое изменилось. При совпадении он оставляет все блоки мира на месте, переводит операцию в `failed` и сохраняет решение до успешного ответа. Ответ имеет обычную форму `operation_status`.
Отказ от неопределённой истории навсегда запрещает undo этой операции и сохраняет аннулирование прежнего права на undo для блоков затронутой маски. Новые записи разрешаются только после постоянного сохранения решения по всем незавершённым операциям. Сбой до сохранения оставляет необходимость восстановления; потеря ответа требует проверки `operation_status`, а не предположения, что произошёл откат. Устаревший или неверный digest возвращается как RPC-ошибка `invalid_request` с причиной.
Статус `applied` подтверждает наблюдавшийся результат записи и проверки в работающем сервере. Файлы чанков и журнал не образуют общую транзакцию; автоматической проверки сохранности всех ранее завершённых операций после аварии пока нет.
## Локальные схемы
Реализованные имена RPC — `asset_list`, `schematic_export` и `schematic_import_prepare`. Отдельных маршрутов `schematic_list` и немедленного `schematic_import` нет. Наличие этих возможностей проверяется через `project_context`.
`asset_list` принимает необязательный `query` для поиска по имени без учёта регистра и возвращает `{ "assets": [...] }`. Каждый элемент содержит `assetId`, `name`, `width`, `height`, `length`, `blockCount`, `dataVersion`, `offset`, `sha256`, `bytes`. Каталог содержит до 64 файлов; каждый файл проверяется при чтении, поэтому повреждённая схема может привести к отказу всего запроса списка.
`schematic_export` принимает `name`, включительные `min/max` и необязательный `origin`. Имя содержит 1–64 печатных символа. `origin` задаёт точку привязки схемы; по умолчанию она равна `min`. Сервер читает плотный прямоугольный участок, включая воздух, в текущей области проекта и в пределах `max_plan_blocks` (не более 4096). Неподдерживаемые блоки и сущности, кроме игроков, приводят к отказу; игроки в схему не записываются. Результат — один объект с теми же полями метаданных, что у `asset_list`. Файл остаётся в подкаталоге `schematics` каталога данных плагина; RPC не возвращает его содержимое или произвольный путь.
`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`. Воздух схемы входит в план и может удалять существующие поддерживаемые блоки. Область, исходное содержимое, окружение, политика блоков и конфликты проверяются обычным путём подготовки и применения.
Поддерживается ограниченное подмножество Sponge Schematic v2: gzip и NBT с палитрой ванильных строительных состояний. Лимиты — 4096 позиций, 1 МиБ сжатого файла и 4 МиБ распакованного NBT. Сущности, block entities, биомы, неизвестные поля верхнего уровня, требуемые модификации и другие версии формата отклоняются. `DataVersion` новее текущего сервера не принимается; преобразования через DataFixer нет. Полная совместимость со всеми схемами WorldEdit не заявляется.
Внешний `.schem` можно заранее поместить локально в каталог схем под именем `[A-Za-z0-9][A-Za-z0-9_-]{0,63}.schem`, после чего его основание используется как `asset_id`. Произвольные пути, сетевые URL и символические ссылки не принимаются. Загрузки файла через RPC в прототипе нет.
## Чат
`chat_poll` принимает стабильный на время жизни Bridge `client_id`. Ответ — `messages` с полями `id`, `playerId`, `projectId`, `text`, `type`, сведениями о положении и блоке под прицелом при наличии. `type` — `prompt` либо `cancel`. Ключ администратора обязателен.
`chat_reply` принимает `id`, `playerId`, `text`, `done`, необязательный `error`. Ответ маршрутизируется только инициатору исходного запроса. На смену Bridge-процесса незавершённые запросы не проигрываются автоматически: плагин останавливает изменения и просит проверить мир. `/ai stop` приостанавливает новые записи независимо от того, успел ли завершиться ACP-ход.
## Камера
`camera_capture` принимает `camera_id` либо `pose: {x,y,z,yaw,pitch,fov?,width?,height?}`. Позиция соответствует ногам наблюдателя; Worker отдельно возвращает координаты глаз. `after_operation_id` проверяет завершение серверной операции, но не гарантирует получения её всех пакетов клиентом.
Paper сериализует запросы, перемещает настроенного spectator-наблюдателя и отправляет запрос локальному Camera Worker на `127.0.0.1:8766` с отдельным ключом. Pending-ответ содержит `captureId`; для проверки вызывается `camera_capture` с `capture_id`. Готовый результат содержит `imageBase64` и `mimeType`, которые Bridge превращает в MCP image content, не в текстовую base64-строку.
Снимок имеет эвристическую оценку готовности чанков/кадров. `serverRevisionVerified: false` сохраняется до реализации строгого клиентского подтверждения. Отсутствие камеры, таймаут и невозможность получить свежий кадр не считаются визуальным успехом.
Подробности Worker: [camera-mod/README.md](../camera-mod/README.md). Потоки и журнал: [world-core/README.md](../world-core/README.md). ACP и изоляция: [bridge/README.md](../bridge/README.md).
+45
View File
@@ -0,0 +1,45 @@
# Готический зал
Воспроизводимая постройка по [визуальному референсу](../references/gothic-hall-v1.png): большой зал с галереями, меньший двухэтажный корпус, соединительный переход и колокольня. Геометрию создают модули в `scripts/builds/gothic_hall/`, применение выполняет `scripts/build-gothic-hall.py` через проверяемые операции Paper-плагина.
Это адаптация референса доступной палитрой: каменный кирпич, андезит, диорит, тёмный сланец, древесина и затемнённое стекло. Шейдеры не используются. Детальная меблировка и ландшафт пока не выполнены; имеются терраса, лестницы, простые скамьи и помост. Колокол собран из блоков, без сущности колокола.
Постройка применена в живом мире: **29 354 блока, 87 пакетов**, итоговая проверка сохранена в `.runtime/gothic-hall/verification.json`.
![Постройка в Minecraft без шейдеров](gothic-hall-built.png)
Настоящий снимок Fabric-камеры от 12 сентября 2026 года, после финальной отделки. PNG сохранён без обработки; [метаданные снимка](gothic-hall-built.capture.json). Ракурс: `(0, -20, -63)`, yaw `25°`, pitch `16°`, FOV `85°`. Дальность тестового сервера — пять чанков, поэтому дальние края скрываются в тумане. Готовность кадра проверяется по клиенту; совпадение блоков с чертежом проверено отдельно чтением мира.
Начало локальных координат — **origin = (-50, -60, -40)**. Мировая координата получается прибавлением origin к локальной. Все диапазоны ниже включают обе границы; главные фасады обращены на север, в сторону `−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`.
Команды выполняются из корня репозитория при запущенном Paper-сервере, подключённом владельце проекта и загруженных чанках стройплощадки. Скрипт читает область проекта и отдельный агентский токен из приватного `.runtime/server/plugins/MinecraftBuilderMCP/config.yml`.
```bash
python3 scripts/build-gothic-hall.py plan
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` сравнивает записанные блоки с результатом в мире и сохраняет отчёт; пустые пространства вне записанной маски она не проверяет.
Журнал возобновления — `.runtime/gothic-hall/ledger.json`. В нём сохраняются хеш чертежа, планы, ключи идемпотентности, идентификаторы операций и их статусы. Повторный `apply` продолжает по этому журналу, используя существующие операции; завершённые пакеты заново не строятся. Также проверяются идентификатор мира и его эпоха.
Занятая область, ручное изменение ожидаемого блока, незавершённая или конфликтующая операция останавливают применение. `verify` сообщает расхождения, сохраняя ручные правки. При остановке нужно проверить указанную операцию и её серверный журнал; удалять ledger или автоматически создавать новый план поверх существующей постройки нельзя. Серверные планы находятся в `plugins/MinecraftBuilderMCP/journal/plans/` и нужны этому скрипту для применения и проверки.
Финальная отделка хранится отдельно от исходного чертежа: `scripts/finish-gothic-hall.py` заменяет 14 центральных плит наверший на целые каменные блоки и четыре блока перехода на ступени. Это убирает зазоры в шпилях и делает подъём между корпусами плавным. Используются отдельный план и `.runtime/gothic-hall/finish-ledger.json`.
```bash
python3 scripts/finish-gothic-hall.py plan
python3 scripts/finish-gothic-hall.py apply
python3 scripts/finish-gothic-hall.py verify
```
После отделки следует использовать последнюю команду: она проверяет исходную постройку с учётом 18 замен. Исходная `build-gothic-hall.py verify` ожидает прежние состояния этих блоков и сообщит о расхождениях.
Отделка применена операцией `682bb5bb-a1fe-4359-b687-06f7b1ce1005`. Повторная проверка всех 29 354 блоков прошла; отчёт — `.runtime/gothic-hall/finish-verification.json`. Мир сохранён через `save-all flush`.
@@ -0,0 +1,29 @@
{
"capturedAt": "2026-09-12T20:10:04.926155338Z",
"dimension": "minecraft:overworld",
"x": 0.0,
"y": -20.0,
"z": -63.0,
"eyeY": -18.380000114440918,
"yaw": 25.0,
"pitch": 16.0,
"fov": 85,
"readiness": "local_chunks_and_render_queue_stable",
"serverRevisionVerified": false,
"loadedChunkRadius": 1,
"stabilizationTicks": 21,
"stabilizationFrames": 3,
"afterOperationId": "682bb5bb-a1fe-4359-b687-06f7b1ce1005",
"status": "completed",
"mimeType": "image/png",
"width": 1280,
"height": 720,
"sourceWidth": 1280,
"sourceHeight": 720,
"captureId": "aa1dbef8-47f1-4985-b505-0bcc79e604b7",
"imageSha256": "b1dfd2fd671c20d7a0e4fd225843695a522f93a194cea18bfa313297e303774a",
"imageBytes": 670102,
"elapsedSeconds": 1.367,
"transport": "authenticated Paper HTTP camera_capture",
"testMode": "one owner/spectator client"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 654 KiB

+44
View File
@@ -0,0 +1,44 @@
{
"schemaVersion": 1,
"projectVersion": "0.1.0-SNAPSHOT",
"status": "prototype; graphical camera and MCP ImageContent verified; authenticated ACP model turn pending",
"testedPlatform": "Linux x86_64",
"minecraft": "26.2",
"paper": {
"build": 123,
"api": "26.2.build.123-stable",
"serverSha256": "7b7b3b43c009103e1971a0576c26f655a7dd9b56a0a2a4438e352c03a7fecd08"
},
"java": "25.0.2",
"maven": "3.9.11",
"nodeTested": "22.22.3",
"fabric": {
"loader": "0.19.5",
"api": "0.160.0+26.2",
"loom": "1.17.20",
"gradle": "9.5.1"
},
"bridge": {
"codexAcp": "1.11.0",
"codex": "0.153.4",
"acpSdk": "1.4.0",
"mcpSdk": "1.30.0",
"typescript": "7.0.2",
"zod": "4.6.2"
},
"schematic": {
"format": "Sponge v2",
"worldEditRuntimeRequired": false,
"maxBlocks": 4096,
"entities": false,
"blockEntities": false
},
"dependencySources": [
"../pom.xml",
"../bridge/package-lock.json",
"../camera-mod/gradle.properties",
"../camera-mod/gradle/wrapper/gradle-wrapper.properties",
"../scripts/bootstrap-tools.py",
"../scripts/dev-server.py"
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

+16
View File
@@ -0,0 +1,16 @@
Generated using the built-in image_gen tool.
Concept reference for minecraft-builder-mcp; not an in-game screenshot or a dimensioned construction plan.
Use case: stylized-concept.
Asset type: architectural reference for a substantial building we will later construct in Minecraft Java.
Primary request: one impressive but realistically buildable Gothic civic guildhall / town hall, significantly larger and more sophisticated than a small watchtower.
Subject: a coherent single building with a long three-storey great hall, a steep dark gabled roof, a prominent square bell tower with a tall pointed roof, a lower connected side wing and an entrance stair. Approximately 65 by 45 Minecraft blocks in footprint, highest tower around 55 blocks; communicate substantial scale through believable block sizes. Strong readable silhouette and balanced architectural hierarchy. The front has a deep pointed-arch entrance and a restrained series of tall, narrow RECESSED windows with stone jambs and lintels. Glass sits inside thick masonry: absolutely no protruding glass boxes. A few recessed paired lancet windows on the great hall. Buttresses, structural masonry, layered cornices and roofs made of explicit block steps; purposeful details with some calm wall areas. The attached wing and tower must visibly connect to usable interior volumes.
Style/medium: beautiful high-quality Minecraft voxel architectural concept render, faithful cubic full-block, stair and slab construction at consistent voxel scale, crisp recognisable vanilla-like pixel textures. All edges obey the Minecraft grid. Not a smooth realistic European building with a token pixel filter.
Materials: predominantly grey stone bricks with restrained polished andesite and light stone trim, dark deepslate stair/slab roofs, dark oak and spruce for doors and inset timber features, dark glass deep in the walls. Restrained palette; strong depth and masonry shadows, no random patchwork.
Scene: the complete building stands on a small paved terrace at ground level, with minimal grass terrain and a quiet pale sky. Sparse setting keeps the architecture fully readable.
Composition: a single landscape image, elevated front three-quarter architectural view showing the entrance, long side facade, roof structure and tower; the full building and entire highest roof are inside the frame with breathing room. Moderate perspective, no fisheye. Building fills most of the composition.
Lighting: clear soft daylight with warm sunlight, readable shadow detail; avoid night, fog or overexposure.
Avoid: people, mobs, UI, HUD, captions, labels, text, watermarks, logos, floating islands, mountains obscuring the building, sprawling cities, enormous fantasy spires, excessive clutter or unbuildable smooth curves.
Generate a brand-new standalone reference, not an edit or screenshot of an existing build.