8.0 KiB
Единые пакеты расширений
packages/<directory>/manifest.json объявляет точные версии, лицензии, зависимости, возможности и ресурсы. При запуске сервер проверяет весь граф зависимостей, размеры, SHA-256, пути и отсутствие symlink. Отсутствующая версия, цикл, неизвестная возможность или изменённый ресурс останавливают запуск. Публикуются только client и common; файлы server не имеют публичного маршрута. Ресурс повторно проверяется при HTTP-чтении.
Примеры — packages/base и packages/trampoline. Все изображения, звук и модели авторские. Данные каталога происходят из официальных отчётов и измерения публичного API Java 26.2; ванильные текстуры и модели в пакеты не входят.
Манифест schema 1 содержит:
id,versionиз трёх числовых частей,license;dependencies:[{id,version}]с точными версиями;capabilities, напримерblocks.define,client.texture,server.on_jump;resources:[{path,scope,role,sha256,size}].
Один ресурс не больше 16 МиБ; пакет не больше 64 МиБ, до 128 ресурсов, до 128 записей в каталоге пакетов. Это ограничения сервера; браузер дополнительно ограничивает суммарно проверяемые публичные ресурсы 128 МиБ на подключение. Определения блоков имеют роль definitions, ресурс с этой ролью требует schema 1. Сервер допускает до 4096 дополнительных определений. Блок задаёт state как новый идентификатор namespace:path без свойств (строчные ASCII-буквы, цифры, _, ., -, дополнительно / в path), color:[r,g,b], collision:[{min,max}] и необязательный render аналогичной формы. Необязательный opacity — число 0…1. Если render не указан, используется существующая авторская форма того же состояния или коллизия нового блока. Максимум 64 бокса на каждый набор; допустимый локальный диапазон координат −2…3. Дубликаты определений и переопределение minecraft:* отвергаются. Runtime ID назначает сохраняемый реестр; Game::open расширяет каталог проверенными определениями до регистрации в WorldStore. Обычный пакетный блок без behavior хранится и участвует в физике; behavior.server_hook: on_jump связывает его с активным WASM-провайдером.
{
"schema": 1,
"blocks": [{
"state": "example:spring",
"color": [97,205,151],
"collision": [{"min":[0,0,0],"max":[1,1,1]}],
"render": [{"min":[0,0,0],"max":[1,1,1]}],
"behavior": {"server_hook":"on_jump"}
}]
}
Исполнение модуля
В MVP нужен ровно один активный провайдер серверного hook on_jump; отсутствие провайдера или два модуля с этой ролью останавливают запуск. Серверный .wasm объявляется ресурсом role: "wasm-on-jump", scope: "server"; необходима capability server.on_jump. Экспорт on_jump: () -> f32 возвращает импульс прыжка в блоках/с. Сервер вызывает его только при прыжке игрока с блока, который связан с hook через проверенное определение пакета.
Исполнение идёт в Wasmi: без импортов, файлов, сети и системных вызовов; до 10 000 единиц fuel на вызов, одна память до 64 КиБ, одна таблица до 128 элементов, один экземпляр. Бинарный модуль не больше 64 КиБ. Результат должен быть конечным числом 0…20; trap или недопустимое значение фиксируется метрикой и даёт обычный прыжок. Выполняемый пример возвращает 10. Тесты проверяют реальный вызов, бесконечный цикл, превышение памяти, попытку импорта и NaN. Отдельный тест создаёт пакет example:spring, проверяет его SHA-256, добавляет новый блок в каталог, регистрирует и сохраняет runtime ID, связывает блок с модулем и получает импульс 12 от собственного бинарного WASM. Дубликаты, Minecraft override, недопустимая геометрия, opacity/идентификатор и изменение ресурса после загрузки отвергаются.
Это ограниченный действующий API расширения, а не обещание произвольной совместимости с Forge/Fabric или доступа WASM к полному состоянию мира. Для нового hook необходима явная версия контракта. Spleef в этом MVP реализован серверным режимом Rust с сохраняемыми правилами.
Клиентские ресурсы
/api/manifest возвращает публичный список с URL, точной версией, размерами и SHA-256. Браузер скачивает файлы, проверяет размер и хеш до входа, затем кладёт в CacheStorage по хешу. При повторном подключении содержимое кэша тоже проверяется. Ошибка хеша удаляет повреждённую запись и запрещает вход. Неподходящий manifest_hash сервер отвергает. Публичный хеш не подтверждает, что клиентское приложение не модифицировано.
Базовый пакет даёт пиксельную текстуру; trampoline — собственную текстуру, GLSL-функцию окраски, настройку стиля и короткий синтезированный звук. Они применяются собственным WebGL2-рендерером. В ядре и сервере отсутствует графический движок. Пакет не загружает произвольный привилегированный JavaScript.
Для изменения пакета пересчитайте размер и SHA-256 каждого изменённого ресурса, увеличьте версию и обновите точные зависимости. scripts/catalog_assets.py воспроизводимо генерирует встроенные авторские ресурсы и манифесты. Формат ориентирован на будущий лаунчер: лаунчер сможет получить тот же manifest и кэшировать по (id,version,sha256); интеграция конкретного лаунчера в этот репозиторий не входит.