# Приёмка Shacraft Core Статус: план проверок; ни один пункт пока не считается выполненным. Основа — исходный запрос пользователя и текущий `docs/CONTRACT.md`. Последний описывает первый рабочий протокол, но пока не покрывает весь согласованный MVP. Shacraft Core — самостоятельный открытый движок на Rust. Shacraft-сервер и Spleef проверяют его пригодность на практике. Экономия серверной RAM — основное архитектурное требование. Полный базовый каталог Minecraft 26.2 означает контент, состояния и формы, а не требование воспроизвести архитектуру Minecraft или весь ванильный игровой процесс. ## Как фиксировать результат Для каждой проверки сохранять: идентификатор, ревизию исходников, версии инструментов, команду или сценарий, используемые данные, фактический результат и путь к доказательству. Статусы: `не проверено`, `пройдено`, `не пройдено`, `заблокировано` с конкретной причиной. Сборка сама по себе не подтверждает рабочую сетевую игру или корректность импорта. Проверки ниже делятся на два рубежа. Первый позволяет получить работающую основу и быстро обнаруживать ошибки интеграции. Его прохождение не означает завершение полного MVP и не уменьшает исходный объём. ## Рубеж A — минимальный сквозной этап ### A-CORE: хранение и независимые миры - Ядро собирается и используется из отдельного Rust-процесса без HTTP, рендера, браузера и запуска сервера Minecraft. - Созданы шаблон и два независимых мира на его основе. Изменение блока в первом мире не изменяет шаблон и второй мир. Замена исходного шаблона не меняет уже закреплённую неизменяемую версию. - Удаление наследуемого блока записывает воздух в наложение, а не возвращает блок шаблона при повторном чтении. Проверить положительные и отрицательные координаты и границы секций. - `world.edit` принимает пакет изменений целиком или отклоняет его целиком. Устаревшая ревизия, неизвестный блок и недопустимые координаты не оставляют частичных изменений. - Повтор операции с тем же `operation_id` и тем же содержимым возвращает `replayed: true`, не увеличивает ревизию и не применяет изменение повторно. Повтор идентификатора с другим содержимым должен иметь документированное безопасное поведение; до его определения проверка не закрывается. - `world.undo` восстанавливает предыдущее содержимое выбранной операции; конфликт с последующими правками обрабатывается по явно описанной политике. Проверить возвращение в наследуемое состояние и удаление наложений. - `world.reset` восстанавливает выбранную версию шаблона и не повреждает другие миры. Изменение ревизии и судьба журнала операций документированы и проверены. - `read_region` возвращает правильные ненулевые блоки в включённых границах. Область ровно в 262144 ячейки принимается, превышение лимита и переполнение арифметики границ отклоняются до большой аллокации. ### A-E2E: два клиента, MCP и перезапуск Воспроизводимый сценарий выполняется на одной локальной установке из чистого каталога данных: 1. Запустить сервер на `127.0.0.1:4000`, проверить `/api/health`, открыть два независимых браузерных сеанса и подключить MCP отдельным процессом. 2. Оба клиента входят в один мир. Каждый видит геометрию и другого игрока; движение, поворот, прыжок и столкновения работают в общей системе координат из контракта. 3. Первый клиент ломает и ставит доступный блок. Второй получает изменение без перезагрузки. Повторное подключение получает то же состояние и актуальную ревизию. 4. MCP читает область, находит блок через каталог, выполняет изменение с `expected_revision` и `operation_id`. Оба клиента видят правку. Повтор той же операции идемпотентен; намеренно устаревшая ревизия возвращает понятную ошибку. 5. MCP выполняет undo, и оба клиента видят восстановление. MCP получает снимок камеры; PNG открывается и показывает ожидаемый участок мира, а не пустое изображение. 6. Создать второй мир из шаблона, переключить туда одного клиента и изменить блок. Второй клиент, оставшийся в исходном мире, не получает чужие правки или состояния игроков. 7. Записать проверяемые позиции, значения блоков, имена миров, закреплённые шаблоны, идентификаторы блоков и ревизии. Завершить сервер, запустить с тем же каталогом данных и подключить клиентов и MCP заново. Всё записанное совпадает; подтверждённые durable-операции не потеряны. 8. Повторить восстановление после принудительного завершения процесса в контролируемом тесте. Повреждённый или незавершённый хвост записи не делает ранее подтверждённый мир нечитаемым. Если гарантия подтверждения отличается от гарантии `flush`, это заранее отражено в контракте. Доказательство: журнал действий и ответов протокола, результаты сверки до/после рестарта, снимок двух клиентов. Скрипт протокола дополняет визуальную проверку браузера, но не заменяет её. ### A-SERVER: сервер определяет состояние игры - Нельзя войти в произвольный неизвестный мир, передать нечисловые/неограниченные координаты или использовать недопустимый `BlockId` и привести к сбою процесса. - Клиент передаёт ввод; координаты, скорость, столкновения и результат действий определяет сервер. Поддельный пакет с готовой позицией не телепортирует игрока. - Сервер проверяет дистанцию взаимодействия и доступность действия по состоянию игры. Игрок не ломает далёкие блоки и не редактирует мир, в котором не находится. - Частота пакетов и размер сообщений ограничены. Поток некорректных, слишком больших и слишком частых сообщений одного соединения не создаёт неограниченную очередь и не лишает второй клиент возможности играть. - Контрольный HTTP API отвергает отсутствующий и неверный токен. Токен не попадает в публичный manifest, клиентскую сборку, URL или обычные журналы. Файл токена создаётся с правами `0600`. - Несовместимые версия протокола и manifest приводят к документированному отказу или обновлению до входа. Совпадение заявленного хеша не трактуется как доказательство доверенности программы клиента. - После разрыва соединения игрок убирается из соответствующего мира; повторное подключение не создаёт бессрочного дубликата сущности. ### A-CLIENT: играбельный браузерный клиент - Клиент запускается по адресу сервера, получает manifest и каталог, отображает блоки, свободное пространство, формы начального набора и игроков. - Управление камерой, движение, прыжок, выбор блока, установка/удаление и переключение мира доступны без ручной отправки запросов в консоли разработчика. - Клиент показывает отказ входа, потерю соединения и ошибки действий понятным сообщением; зависшее состояние не выдаётся за подтверждённое сервером. - Геометрия обновляется после сетевых правок. Начальная загрузка, повторное соединение и смена мира не оставляют геометрию предыдущего мира. ### A-MCP: настоящий отдельный MCP - Отдельный процесс MCP успешно проходит `initialize`, объявляет инструменты и выполняет `tools/call` через клиент MCP. Наличие одного `/api/control` не закрывает этот критерий. - Доступны операции мира, поиск каталога, чтение, пакетная правка, undo, метрики, запуск арены, снимок камеры и объявленные в контракте операции сущностей. - Схемы аргументов, результаты и ошибки соответствуют фактическому поведению. Недоступный сервер и неверный токен дают ошибку инструмента без зависания MCP-процесса. - MCP использует тот же контроль ревизий, границ и допустимости данных, что и прочие административные обращения. Поиск ограничивает размер ответа, а чтение не выгружает целый большой мир в контекст. ### A-SPLEEF: один полный матч - В арене на общей карте участвуют два клиента. Есть ожидание/подготовка, начало, активная игра и завершение; сервер сообщает фазу и оставшееся время. - В активной игре разрешено ломать только допустимый слой арены. Установка блоков и правки вне области ограничены правилами режима. - Падение ниже настроенной границы исключает игрока на сервере. При одном оставшемся участнике объявляется один победитель; при одновременном выбывании и разрыве соединения результат определён правилами. - Завершение и повторный запуск восстанавливают карту и участников. Параллельная арена на том же шаблоне сохраняет собственное состояние. - Нельзя дважды запустить уже активный матч и получить несколько таймеров или повторное начисление результата. ### A-MEMORY: ограниченность памяти основы - При чтении числа различных секций, превышающего `cache_sections`, количество резидентных секций в кэше не превышает заданную ёмкость. Проверить также ёмкость 0 или её явно документированный отказ. - Два и более мира с общей неизменяемой основой не получают по полной копии данных карты в RAM. Метаданные миров и их изменения учитываются отдельно. - Выгрузка изменённой секции сохраняет её изменения; повторное чтение после вытеснения и после рестарта возвращает одинаковый результат. - История операций хранится на диске. Длинная последовательность правок не требует держать весь журнал и все снимки состояний в RAM. - Метрики позволяют увидеть хотя бы число миров, резидентных секций и заданную ёмкость кэша. RSS процесса измеряется снаружи; один счётчик кэша не выдаётся за расход памяти всего сервера. ## Рубеж B — полный согласованный MVP Все проверки рубежа A обязательны. Дополнительно должны быть завершены следующие части; начальная демонстрация с несколькими блоками их не заменяет. ### B-CONTENT: полный базовый каталог Minecraft 26.2 - Зафиксированы точная редакция/сборка 26.2, источник каталога и контрольные суммы входных данных. Полнота проверяется сравнением с этим набором, а не заранее придуманным количеством блоков. - Автоматическая сверка покрывает каждый базовый блок, допустимые состояния, формы рендера и столкновений, а также каждый базовый тип сущности целевого набора. - Канонические имена и свойства сохраняются без потери при регистрации, хранении, сетевой передаче и рестарте. Неизвестные состояния не заменяются воздухом молча. - Каталог сущностей включает данные, необходимые для отображения, размещения, хранения и обмена мирами; поведенческие возможности каждого типа явно отмечены. Заглушка для всех типов не считается полным каталогом с рабочими формами. - Отдельно проверяются отличающиеся от полного куба формы, ориентации, составные блоки, прозрачность и блоки с дополнительными данными. Клиент и сервер используют совместимые формы и свойства. - Ресурсы воспроизводимо собираются из объявленных источников. Отсутствующий ресурс приводит к диагностике с конкретным идентификатором, а отчёт содержит полный список пробелов. ### B-PACKAGES: единая система модулей и ресурсов - Один версионируемый формат пакета описывает модули, текстуры, шейдеры и прочие ресурсы, зависимости, совместимость и стороны исполнения. - Сервер формирует manifest с точными версиями и хешами; клиент автоматически получает требуемые клиентские части, проверяет целостность и повторно использует локальный кэш. - Проверены отсутствующий пакет, несовместимая версия, цикл зависимостей, повреждённая загрузка, прерывание/возобновление и изменение набора между подключениями. Частичная установка не активируется как полная. - Серверные файлы и секреты не попадают в клиентскую выдачу. Пакеты не могут писать за пределы каталога установки через относительные пути или архивные записи. - Расширение регистрирует новый контент через документированный интерфейс; его можно подключить без правки исходников ядра. Права исполнения, доступные API и ограничения ресурсов модуля определены и проверены. - Проект запускается независимо от Shacraft Launcher. Интерфейс будущей интеграции документирован. Реальное изменение/проверка существующего лаунчера относится к отдельному интеграционному этапу и не блокирует локальный выпуск движка. ### B-INTEROP: импорт и экспорт Minecraft ↔ Shacraft - Команды и форматы импорта/экспорта документированы. Есть небольшие эталонные миры целевой версии: несколько измерений, отрицательные координаты, состояния блоков, сущности, данные блок-сущностей и пользовательские данные. - Импортированный мир открывается сервером и клиентом; выборочная и полная автоматическая сверка эталонов подтверждает координаты, состояния и поддерживаемые данные. - Цикл `Minecraft → Shacraft → Minecraft` сохраняет поддерживаемые данные семантически. Сравниваются декодированные значения; побайтовое равенство сжатых файлов не требуется. - Исходные неизвестные или неподдерживаемые данные сохраняются для обратного экспорта, если их смысл нельзя корректно перенести. Экспорт не уничтожает их незаметно после редактирования других частей мира. - Изменения, сделанные через клиент и MCP, правильно отражаются в экспортированном мире. Отдельно проверяются удаление блока, новые состояния и сущности. - Отчёт перечисляет сохранённые, преобразованные, неподдерживаемые и потерянные данные с координатой/идентификатором и причиной. Отсутствие данных не маскируется успешным статусом. - Повреждённый файл, неполная область, неизвестная версия, слишком большая распакованная запись и отмена операции не портят источник и ранее существующий целевой мир. - Конвертер обрабатывает мир порциями; потребление RAM не растёт до размера всего мира. Эталон, превышающий бюджет кэша, конвертируется успешно. ### B-PERSISTENCE: устойчивое состояние сервера - На диске сохраняются миры, закреплённые версии шаблонов, реестр контента, правки, необходимые данные undo, конфигурация и правила арен, а также сохраняемые сущности. - Политика восстановления активного матча после рестарта определена: восстановление или безопасный сброс. Результат не оставляет навсегда активную арену и не дублирует победу. - Проверены прерывания в момент записи секций, метаданных и журнала. Восстановление выбирает целостную версию; данные, на которые уже получено durable-подтверждение, сохраняются согласно контракту. - Версия формата хранения проверяется при открытии. Несовместимая версия вызывает понятный отказ или проверяемую миграцию с возможностью восстановления исходных данных. ### B-MEMORY: доказанная экономия серверной RAM Benchmark запускается на фиксированном наборе данных и оборудовании. До измерения фиксируются лимиты, размер карты, количество миров и игроков, частота правок, объём активных областей и допустимый запас RSS; выбранные значения публикуются вместе с результатом. - Сравнить 1, 10 и 100 независимых миров одного большого шаблона: без игроков, с одинаковой активной областью и с различными активными областями. Допускается рост метаданных и изменённых данных; полная копия карты на мир отсутствует. - Для каждого варианта записать RSS/p95/пик, резидентные секции и их байты, размер наложений, число игроков, сетевые очереди, скорость/задержку тика и размер данных на диске. - После обхода областей размером больше кэша неактивные секции вытесняются. Повторные обходы и циклы создания/сброса миров не вызывают постоянного линейного роста удерживаемой памяти. - Медленный клиент, длинный журнал, частые снимки MCP и параллельные импорты не обходят лимиты через очереди, буферы ответов и вспомогательные кэши. - Целевые лимиты памяти и задержки тика соблюдаются на опубликованной нагрузке. Без заранее зафиксированного бюджета можно подтвердить ограниченность отдельных структур, но нельзя объявлять достигнутым конкретный масштаб сервера. ### B-DELIVERY: воспроизводимый открытый проект - В репозитории есть исходники самостоятельного Rust-ядра, отдельного сервера, клиента, MCP, конвертера, пакетов базового контента и примера режима; границы зависимостей проверяемы сборкой. - Чистая установка по README воспроизводит сборку, тесты и сценарий A-E2E. Конфигурация, порты, команды запуска, каталог данных и получение токена описаны явно. - Документированы API расширений, протокол, формат пакетов, хранение, гарантии сохранности и ограничения совместимости; выбранная открытая лицензия присутствует в репозитории. - Архив выпуска создан, повторно распакован в чистый каталог и проверен. В него не включены токены, локальные миры пользователя и зависимости, которые должны загружаться отдельно. - Итоговый отчёт ссылается на доказательства для каждого обязательного критерия. Непроверенные или заблокированные требования перечислены явно и не называются завершёнными. ## Что нужно уточнить в CONTRACT.md по ходу реализации Эти решения можно проработать без остановки первого сквозного этапа. До приёмки соответствующей части полного MVP они должны стать явными контрактами и тестами: - Версия протокола, идентификаторы ошибок, лимиты пакетов/координат/строк, восстановление клиента при пропуске ревизии и семантика `switch_world`. - Момент durable-подтверждения, replay с различными аргументами, конфликты undo, ревизия после reset, формат и срок хранения истории. - Источник точной версии каталога 26.2, схема форм и состояний, каталог/сохранение сущностей и дополнительных данных блоков. - Формат пакета, граф зависимостей, публикация ресурсов сервером, интерфейс и пределы исполнения модулей, интеграция лаунчера. - Настройки арены, допустимые действия, таймеры, ничья, отключение игрока и политика сохранения матча. - Форматы и команды импорта/экспорта, сохранение неподдерживаемых данных и машиночитаемый отчёт о потерях. - Общий бюджет RAM, лимиты помимо кэша секций, целевая нагрузка и параметры воспроизводимого benchmark.