30 KiB
Приёмка 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 и перезапуск
Воспроизводимый сценарий выполняется на одной локальной установке из чистого каталога данных:
- Запустить сервер на
127.0.0.1:4000, проверить/api/health, открыть два независимых браузерных сеанса и подключить MCP отдельным процессом. - Оба клиента входят в один мир. Каждый видит геометрию и другого игрока; движение, поворот, прыжок и столкновения работают в общей системе координат из контракта.
- Первый клиент ломает и ставит доступный блок. Второй получает изменение без перезагрузки. Повторное подключение получает то же состояние и актуальную ревизию.
- MCP читает область, находит блок через каталог, выполняет изменение с
expected_revisionиoperation_id. Оба клиента видят правку. Повтор той же операции идемпотентен; намеренно устаревшая ревизия возвращает понятную ошибку. - MCP выполняет undo, и оба клиента видят восстановление. MCP получает снимок камеры; PNG открывается и показывает ожидаемый участок мира, а не пустое изображение.
- Создать второй мир из шаблона, переключить туда одного клиента и изменить блок. Второй клиент, оставшийся в исходном мире, не получает чужие правки или состояния игроков.
- Записать проверяемые позиции, значения блоков, имена миров, закреплённые шаблоны, идентификаторы блоков и ревизии. Завершить сервер, запустить с тем же каталогом данных и подключить клиентов и MCP заново. Всё записанное совпадает; подтверждённые durable-операции не потеряны.
- Повторить восстановление после принудительного завершения процесса в контролируемом тесте. Повреждённый или незавершённый хвост записи не делает ранее подтверждённый мир нечитаемым. Если гарантия подтверждения отличается от гарантии
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.