150 lines
30 KiB
Markdown
150 lines
30 KiB
Markdown
# Приёмка 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.
|