docs: present Shacraft Core and its documentation in English

This commit is contained in:
Emil
2026-09-14 17:58:30 +03:00
parent b6ba064339
commit 26748912c6
18 changed files with 643 additions and 620 deletions
+35 -35
View File
@@ -1,14 +1,14 @@
# Каталог, формы и единые пакеты MVP
# MVP catalog, geometry, and unified packages
Встроенный каталог фактически извлечён из **Minecraft Java 26.2**, `DataVersion = 4903`: **1 196 блоков, 32 366 состояний, 158 типов сущностей**. Проверка сравнивает полные множества состояний, числовые ID источника, состояния по умолчанию, свойства и типы сущностей с отдельной проекцией официальных отчётов. Дополнительно зарегистрирован собственный `shacraft:trampoline`: всего 1 197 блоков и 32 367 состояний.
The built-in catalog was extracted from **Minecraft Java 26.2**, `DataVersion = 4903`: **1,196 blocks, 32,366 states, and 158 entity types**. Validation compares the complete sets of states, source numeric IDs, default states, properties, and entity types against a separate projection of the official reports. The project's own `shacraft:trampoline` is also registered, bringing the total to 1,197 blocks and 32,367 states.
Числовой `minecraft_id` — только идентификатор источника. Сервер отдельно регистрирует канонические строки в `WorldStore`; внутренний `BlockId` зависит от истории конкретного хранилища. Нельзя использовать `minecraft_id` в операциях редактирования мира. Для собственного состояния значение `minecraft_id = u32::MAX` означает отсутствие ID Minecraft.
The numeric `minecraft_id` identifies a state in the source only. The server registers canonical strings separately in `WorldStore`; its internal `BlockId` depends on the history of that particular store. Do not use `minecraft_id` in world editing operations. For a custom state, `minecraft_id = u32::MAX` means that no Minecraft ID exists.
## Происхождение и воспроизведение
## Provenance and reproduction
Источник: [официальный server.jar Java 26.2](https://piston-data.mojang.com/v1/objects/823e2250d24b3ddac457a60c92a6a941943fcd6a/server.jar). SHA-1 `823e2250d24b3ddac457a60c92a6a941943fcd6a`, размер 60 894 273 байта. Полные SHA-256, версия Java, команды и контрольные суммы отчётов находятся в `crates/shacraft-content/data/provenance.json`.
Source: [official Java 26.2 server.jar](https://piston-data.mojang.com/v1/objects/823e2250d24b3ddac457a60c92a6a941943fcd6a/server.jar). SHA-1: `823e2250d24b3ddac457a60c92a6a941943fcd6a`; size: 60,894,273 bytes. Full SHA-256 hashes, the Java version, commands, and report checksums are recorded in `crates/shacraft-content/data/provenance.json`.
Генератор проверяет закреплённые размер и SHA-1 перед использованием JAR:
The generator checks the pinned size and SHA-1 before using the JAR:
```sh
python3 scripts/catalog_generate.py --java /path/to/java25/bin/java
@@ -17,55 +17,55 @@ cargo test -p shacraft-content
cargo run -p shacraft-content --example catalog_report
```
Нужен установленный JDK 25 или новее, включая `javac`. Проверенный локальный runtime: Microsoft OpenJDK 25.0.1+8-LTS. Скрипт не меняет системную Java. `--reuse-reports` позволяет повторно упаковать уже полученные локальные отчёты; полное воспроизведение выполняют без него. Gzip имеет фиксированный `mtime=0`; содержимое каталога детерминировано. В provenance меняется время запуска.
An installed JDK 25 or later, including `javac`, is required. The verified local runtime is Microsoft OpenJDK 25.0.1+8-LTS. The script does not change the system Java installation. `--reuse-reports` repackages previously generated local reports; omit it for a full reproduction. Gzip uses a fixed `mtime=0`, and the catalog content is deterministic. The run timestamp changes in the provenance record.
Фактически проверена точка входа:
The following entry point was verified:
```sh
java -Xmx1G -DbundlerMainClass=net.minecraft.data.Main -jar server.jar --reports --output generated
```
`catalog_extract.java` — собственная небольшая программа, вызывающая публичные API реестров и коллизий 26.2. Она не содержит декомпилированного кода. Генератор данных и измерения не запускают игровой сервер, не создают `eula=true`, не принимают соглашений. JAR, распакованные библиотеки, отчёты и Java-классы остаются в игнорируемом `artifacts/catalog-cache`; в дистрибутив входят только минимальные фактические данные совместимости и авторский код.
`catalog_extract.java` is a small original program that calls the public registry and collision APIs in 26.2. It contains no decompiled code. The data generation and measurements run without launching the Minecraft game/server, creating an `eula=true` file, or accepting its server startup prompt. The JAR, extracted libraries, reports, and Java classes remain in the ignored `artifacts/catalog-cache` directory; the distribution contains only minimal factual compatibility data and original code.
## Что проверено у форм
## Geometry verification
Для **каждого из 32 366 состояний** получен `getCollisionShape` официального исполняемого API. Измерение не использует текстуры или визуальные модели. Все измерения завершились без ошибок; после дедупликации осталось 326 различных наборов прямоугольных объёмов.
`getCollisionShape` was obtained from the official executable API for **each of the 32,366 states**. Measurement uses no textures or visual models. All measurements completed without errors, yielding 326 distinct sets of axis-aligned boxes after deduplication.
Базовый контекст измерения — `BlockPos.ZERO`, соседи `air`, отсутствие сущности (`CollisionContext.empty()`). Дополнительно сравнены каменные соседи и `CollisionContext.positionContext(+10/-10)`: различия обнаружены у 32 состояний scaffolding. Помимо них явно помечены классы с зависимостью от сущности/блочной сущности/динамического состояния: powder snow, shulker box, moving piston и big dripleaf. Поэтому покрытие коллизий разделено:
The baseline measurement context uses `BlockPos.ZERO`, neighboring `air`, and no entity (`CollisionContext.empty()`). Additional comparisons used stone neighbors and `CollisionContext.positionContext(+10/-10)`; these revealed differences in 32 scaffolding states. Classes that depend on entities, block entities, or dynamic state are also explicitly marked: powder snow, shulker box, moving piston, and big dripleaf. Collision coverage is therefore divided into:
- 32 187 состояний: `measured-empty-context` — измерена форма в описанном контексте.
- 179 состояний: `approximate-context` — геометрия базового контекста доступна, полной эквивалентности динамических условий нет.
- 1 собственное состояние: `authored-exact`.
- 32,187 states: `measured-empty-context` — geometry measured in the context described above.
- 179 states: `approximate-context` — baseline geometry is available, but dynamic conditions are not fully equivalent.
- 1 custom state: `authored-exact`.
Первое значение **не утверждает эквивалентность во всех произвольных контекстах**. Положение игрока, специальные экипировки, поршневые блочные сущности, открывание shulker box, обновление связей соседей, AI, редстоун и течения жидкостей не следуют из каталога. Сервер реализует собственную симуляцию и явно ограниченные модули.
The first label **does not claim equivalence in every arbitrary context**. Player position, special equipment, piston block entities, opening shulker boxes, updates to connections with neighbors, AI, redstone, and fluid flow cannot be inferred from the catalog. The server provides its own simulation and modules with explicit boundaries.
Отдельные регрессионные проверки подтверждают верхнюю/нижнюю плиту, объём и направления лестниц, открывание двери, пустую коллизию воды, коллизию забора высотой 1.5, контекстную пометку scaffolding/powder snow, валидность границ всех форм. Геометрия коллизий может выходить за клетку: нельзя безусловно ограничивать Y диапазоном `[0,1]`.
Separate regression checks cover top/bottom slabs, stair volumes and orientations, door opening, empty water collision, the 1.5-block fence collision height, context labels for scaffolding/powder snow, and valid bounds for every shape. Collision geometry can extend outside a block cell; Y must not be unconditionally clamped to `[0,1]`.
## Авторское отображение
## Original rendering
`render` и `collision` — разные наборы `Aabb { min, max }`, координаты относительно блока. Рендерер использует собственные процедурные формы и палитру Shacraft. Встроенные PNG, звуковой WAV и GLSL написаны/сгенерированы в этом репозитории; оригинальных ресурсов Minecraft нет.
`render` and `collision` are separate sets of `Aabb { min, max }`, with coordinates relative to the block. The renderer uses Shacraft's own procedural geometry and palette. The bundled PNG files, WAV audio, and GLSL were authored or generated in this repository; no original Minecraft assets are included.
Семейства плит, лестниц, дверей, люков, панелей, сундуков и многих сложных твёрдых блоков используют измеренные объёмы как основу самостоятельной геометрии. Для заборов, стен, открытых калиток, знаков, рельсов, жидкостей, растений, кнопок, рычагов, ковров и других нетвёрдых форм предусмотрены отдельные параметрические шаблоны. Забор рисуется до Y=1, при этом коллизия достигает Y=1.5. У наклонного рельса ступенчатая геометрия; изогнутый рельс — угловая аппроксимация из прямоугольников. Это читаемый авторский стиль, а не копия визуальной точности Minecraft.
Slabs, stairs, doors, trapdoors, panes, chests, and many complex solid block families use measured volumes as a basis for original geometry. Fences, walls, open fence gates, signs, rails, liquids, plants, buttons, levers, carpets, and other non-solid forms have separate parametric templates. A fence is drawn up to Y=1 while its collision reaches Y=1.5. Ascending rails have stepped geometry; curved rails use an angular approximation made of rectangles. This is a readable original style, not a visually exact reproduction of Minecraft.
Покрытие: 32 317 состояний `authored-procedural` и 50 `intentionally-invisible` (включая воздух, технический light/barrier/structure void и moving piston без исходной динамической блочной сущности). Универсальных визуальных кубов-заглушек для неизвестных семейств встроенного каталога сейчас нет. При этом каждая декоративная деталь, текст надписей, анимация, waterlogged-жидкость внутри модели и световая симуляция не воспроизводятся автоматически по факту наличия состояния.
Coverage: 32,317 `authored-procedural` states and 50 `intentionally-invisible` states, including air, technical light/barrier/structure void blocks, and moving pistons without their original dynamic block entities. No built-in catalog families currently fall back to a generic visual cube. The existence of a state does not automatically reproduce every decorative detail, sign text, animation, waterlogged fluid inside a model, or lighting simulation.
Для 158 типов сущностей извлечены начальные width/height/eye height, fixed dimensions, категория, summonable/serializable/fire immune, tracking/update interval и все доступные базовые числовые attributes. Эти свойства находятся в `EntityDefinition.properties`. Модели относительно ног — авторские семейства biped, quadruped, aquatic, winged, boat, cart, dragon, arthropod и другие. Служебные marker/interaction/area effect cloud/lightning bolt намеренно невидимы. Display-сущности имеют явно указанную зависимость от свойств экземпляра. Размеры возраста/позы/масштаба и произвольный NBT сохраняются слоем экземпляров; каталог хранит размеры по умолчанию. Наличие модели не означает наличие ванильного AI.
For 158 entity types, the extracted data includes initial width/height/eye height, fixed dimensions, category, summonable/serializable/fire immune flags, tracking/update interval, and all available base numeric attributes. These properties are stored in `EntityDefinition.properties`. Models are positioned relative to the feet and use original biped, quadruped, aquatic, winged, boat, cart, dragon, arthropod, and other families. Technical marker/interaction/area effect cloud/lightning bolt entities are intentionally invisible. Display entities explicitly declare their dependence on instance properties. Age/pose/scale dimensions and arbitrary NBT are preserved by the instance layer; the catalog stores default dimensions. Having a model does not imply vanilla AI support.
## Rust API
- `Catalog::load_builtin() -> Result<Catalog>`: полный встроенный каталог и trampoline.
- `Catalog::load_builtin() -> Result<Catalog>`: the complete built-in catalog and trampoline.
- `catalog.state(canonical_or_block_name)`, `catalog.entity(name)`, `catalog.default_state(name)`.
- `catalog.palette()`: 12 удобных канонических состояний для тестового клиента.
- `catalog.sampler()`: 1 197 образцов по умолчанию в сетке 32 столбца с шагом 3; отдельные клетки относительно пола Y=0, X/Z в пределах ±64. Создание пола и запись в мир — ответственность сервера.
- `catalog.summary()`: количества, раздельное покрытие, версия и ограничения.
- `canonical_state(name, properties)`: сортировка ключей и ограниченная валидация без потери неизвестных свойств.
- Все публичные определения реализуют `Clone`, `Serialize`, `Deserialize`. После десериализации целого `Catalog` следует вызвать `rebuild_indexes()` перед поиском.
- `catalog.palette()`: 12 convenient canonical states for the test client.
- `catalog.sampler()`: 1,197 default samples in a 32-column grid with spacing 3; individual cells are positioned relative to a floor at Y=0, with X/Z within ±64. The server is responsible for creating the floor and writing blocks to the world.
- `catalog.summary()`: counts, separate coverage categories, version, and limitations.
- `canonical_state(name, properties)`: key sorting and limited validation without losing unknown properties.
- All public definitions implement `Clone`, `Serialize`, and `Deserialize`. After deserializing a complete `Catalog`, call `rebuild_indexes()` before performing lookups.
Хранение бинарного встроенного каталога занимает около 246 KiB gzip; при загрузке он распаковывается и создаёт строки/геометрию и индексы. Размер файла не равен RAM каталога. Полные строки 32 тысяч состояний и реестр `WorldStore` нужно учитывать отдельно в RSS измерениях процесса.
The built-in binary catalog occupies about 246 KiB as gzip. Loading decompresses it and creates strings, geometry, and indexes. File size is not the catalog's RAM usage. The complete strings for 32 thousand states and the `WorldStore` registry must be accounted for separately in process RSS measurements.
## Единый формат пакета v1
## Unified package format v1
Каждый подкаталог `packages/` содержит `manifest.json`:
Each subdirectory of `packages/` contains a `manifest.json`:
```json
{
@@ -82,10 +82,10 @@ java -Xmx1G -DbundlerMainClass=net.minecraft.data.Main -jar server.jar --reports
}
```
Пример иллюстрирует схему; действительные размеры и хеши берутся из сгенерированных манифестов. Версии зависимостей точные. `load_packages(root)` проверяет весь граф до выдачи ресурсов: схему, уникальность, зависимости, совпадение версий, циклы, допустимые capabilities, пути, размеры и SHA-256 всех объявленных ресурсов. Один ресурс ограничен 16 MiB, весь пакет — 64 MiB; symlink и traversal в ресурсных путях отвергаются. `read_resource` повторно проверяет хеш и размер при чтении.
This example illustrates the schema; actual sizes and hashes come from the generated manifests. Dependency versions are exact. `load_packages(root)` validates the entire graph before exposing resources: schema, uniqueness, dependencies, matching versions, cycles, allowed capabilities, paths, sizes, and SHA-256 hashes of all declared resources. A resource is limited to 16 MiB and an entire package to 64 MiB; symlinks and traversal in resource paths are rejected. `read_resource` checks the hash and size again when reading.
Scopes: `common` — общие определения; `client` — ресурсы клиента; `server` — внутренние данные и код сервера. `PackageManifest::client_manifest()` исключает серверные ресурсы и capabilities. `Package::public_resource(path)` отказывает для server scope; HTTP-маршрут обязан использовать именно этот метод. Статический сервер не должен раздавать весь каталог `packages/` напрямую.
Scopes: `common` contains shared definitions; `client` contains client assets; `server` contains internal server data and code. `PackageManifest::client_manifest()` excludes server resources and capabilities. `Package::public_resource(path)` denies access to server-scope resources; the HTTP route must use this method. The static server must not serve the entire `packages/` directory directly.
`shacraft.base` включает описание каталога, собственный 64×64 текстурный шум и клиентский стиль. `shacraft.trampoline` включает общее определение блока, 32×32 текстуру сетки, клиентский визуальный эффект, короткий авторский звук, необязательную функцию GLSL и **исполняемый серверный WebAssembly-модуль**. Его экспорт `on_jump() -> f32` возвращает скорость 10 блоков/с; импортов, памяти и внешних системных вызовов нет. WAT-исходник находится рядом. Сервер исполняет бинарный модуль в ограниченной среде; контракт предусматривает лимит топлива 10 000, памяти 1 страницу, проверку диапазона результата. Клиент использует встроенный эффект `bounce` по данным пакета, не произвольный JavaScript из сети. Произвольная среда клиентского кода и полноценная модовая экосистема не объявляются реализованными.
`shacraft.base` includes the catalog description, an original 64×64 noise texture, and client styling. `shacraft.trampoline` includes a shared block definition, a 32×32 grid texture, a client visual effect, a short original sound, an optional GLSL function, and an **executable server WebAssembly module**. Its `on_jump() -> f32` export returns a velocity of 10 blocks/s; the module has no imports, memory, or external system calls. The WAT source is included alongside it. The server executes the binary module in a restricted environment; the contract specifies a fuel limit of 10,000, a memory limit of 1 page, and range validation of the result. The client uses the built-in `bounce` effect according to package data, rather than arbitrary JavaScript from the network. An arbitrary client code runtime and a complete mod ecosystem are not claimed as implemented.
`python3 scripts/catalog_assets.py` детерминированно пересоздаёт все авторские ресурсы и хеши. Ресурсы пакетов доступны на условиях `MIT OR Apache-2.0`, как собственный код проекта. Генерация ничего не скачивает.
`python3 scripts/catalog_assets.py` deterministically regenerates all original assets and hashes. Package assets are available under `MIT OR Apache-2.0`, like the project's original code. Generation downloads nothing.