Files
airdef/docs/ENGINE.md
T
chexit 19c53fda4c
build / mod (push) Failing after 19s
docs: record API27 readiness and reverse logistics verification
Document capability milestones, budget limits versus measurements, real-game no-audio observations, reverse pickup reservation and the Windows stale-URL fix.

Co-authored-by: Codex <codex@openai.com>
2026-11-03 10:22:53 +03:00

115 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Закреплённый движок AirDef
Движок: https://gitea.maoniao.team/chexit/horizon-airdef, ветка `airdef`.
AirDef хранит точный SHA как gitlink `horizon/`; новый push движка не меняет старые сборки мода.
История upstream и всех 44 прежних патчей сохранена в форке. Старые patch-файлы и HORIZON_COMMIT
доступны в истории AirDef и больше не являются вторым источником движка. Baseline описан в AIRDEF-FORK.md.
## Windows: обновление и запуск
```powershell
git fetch origin
git switch kimi-work
git pull --ff-only
python tools/airdef.py all
python tools/airdef.py play
```
Первое клонирование: `git clone --recurse-submodules https://gitea.maoniao.team/chexit/airdef.git`.
Обычный clone тоже поддерживается: `python tools/airdef.py fork` или команда submodule выше.
`all` инициализирует зависимость сам, включая переход со старой папки `horizon/`.
Для чистого checkout можно отдельно выполнить `git submodule update --init --recursive`. Нужны Git, Python и Rust согласно INSTALL.md.
Сборка клиента и мод устанавливаются в обычное место; ресурсы Minecraft готовятся отдельно по INSTALL.md.
При первом переходе со старого отдельного clone `horizon/` скрипт сохраняет его Git-историю и ветки,
переводит в сабмодуль и получает закреплённый SHA. Если там есть изменения при другом SHA,
обновление останавливается с объяснением: сначала закоммитьте/сохраните свои изменения.
Скрипт не выполняет reset --hard или clean. Чистый checkout может остаться detached HEAD — это нормально для зависимости.
## Изменение движка
1. В `horizon/` создать рабочую ветку от закреплённого SHA. Проверить изменение и push в репозиторий движка.
2. В AirDef выполнить `git add horizon`, проверить мод/игру, коммитить обновление gitlink отдельно.
3. Push AirDef выполняется после движка. Не коммитить Git URL с токенами.
4. Для возврата выбрать прежний commit AirDef и выполнить `git submodule update --init --recursive`.
Упаковщик собирается repo-local в `.horizon-cache/packer/<engine-identity>/`, глобальный
`cargo-horizon-mod` не используется. Изменения tracked-исходников движка входят в identity.
Рядом с airdef.hmod записывается build-identity.json: SHA AirDef, pin/identity движка,
SHA256 WIT и артефакта. API-диагностика остаётся в `python tools/airdef.py check`.
Нативные тесты не заменяют отдельную игровую проверку графики, звука и экспорта.
## Проверка настоящего WASM
`python tools/airdef.py test-wasm` собирает `.hmod` и запускает `tests/*.toml` в настоящем
runtime закреплённого движка. Используется временное storage; игровые миры не нужны.
Сценарий проверяет загрузку/регистрацию команды, два комплекса, налёт, tick/frame,
выход из мира и перезагрузку мода. Действуют лимиты runtime: 64 MiB linear memory,
300 млн fuel на tick, 10 млн на frame, 1 млрд на event, 2 млрд на init.
Это проверка ABI и fallback при отсутствии render replies; она не измеряет GPU,
не подтверждает акустику/MP4 и не заменяет максимальный боевой полигон.
В CI проверка assets входит в лёгкий build. Wasmtime tier вынесен в ручной workflow
`wasm-contract`, чтобы не компилировать тяжёлый runtime на каждом push слабого общего runner.
## Готовность объёмного дыма (API 26)
`render.smoke-status` разделяет доступность API, включённый режим, принятую отправку этого мода
и готовность smoke/fog пути последнего подготовленного основного кадра. Возвращаются поколение мира
и причина (`awaiting-frame`, `disabled`, `path-unavailable`, `ready`). AirDef убирает обычный дым
только когда выполнены все четыре условия; после смены мира старые сегменты и часы очищаются.
Это подтверждение выбранного пути рендера, а не завершения GPU или видимости каждого сегмента.
Сам `smoke-status` не подтверждает акустику и capture; их отдельные статусы добавлены в API 27 ниже.
## Акустика и владение захватом (API 27)
Текущий pin: `c89c78c47047fcfc0dfb0b8968600c650bf12d2b`. Новые
`render.acoustics-status` и `render.capture-owner-status` возвращают поколение,
`available`, `enabled`, `request-accepted`, `prepared` и причину. В игре всё это показывает
`/airdef capabilities`. Отсутствие запроса, выключение, ожидание backend и ошибка различаются.
Для акустики `prepared` означает выполненный шаг обработки с геометрией при доступном live/offline
микшере. Шаг может поставить worker job или принять результаты; это **не** подтверждение результата
для каждого источника, завершения worker, слышимого звука или точного отражения. В режиме no-audio
без offline-микшера готовность не наступает. AirDef подтверждает текущее глобальное предпочтение,
не меняя его, и сохраняет собственные дальние варианты звука до подтверждённой подготовки.
Для capture запрос принадлежит конкретному запуску мода и поколению мира. `prepared` соответствует
его стадиям Recording/Encoding/Done; состояние файла и ошибка по-прежнему читаются из `capture-status`.
AirDef не принимает чужие Recording/Done за свой экспорт. Ожидание первоначальной подготовки
ограничено 600 тиками. Остановка проверяет владельца; смена мира отменяет модовый захват и
сбрасывает готовность. Уже переданный writer файл на Encoding может всё же завершиться:
это запрос отмены, не гарантия удаления файла.
## Отдельный тяжёлый WASM tier
```sh
python3 tools/airdef.py test-budgets
python3 tools/test_budget_report.py
python3 tools/test_airdef_build.py
```
Сценарий `airdef-mod/tests/budgets/wasm_budget.toml` запускается в изолированном временном `tests/`,
поскольку CLI читает только непосредственные `tests/*.toml`. Обычный `test-wasm` остаётся лёгким.
Ручной workflow `.gitea/workflows/wasm-budget.yml` не добавляет нагрузку на каждый push.
Проверенный профиль: 64 комплекса, две перекрывающиеся волны по 80 целей на 4000 блоках,
602 вызова tick и 300 frame, 69 шагов. Это не полный лимит расстановки (2000) и не нагрузочный
тест GPU, mixer voices или всех физических world replies: sandbox не выполняет настоящий рендер/звук.
Отчёт `.horizon-cache/wasm-budget-report.json` содержит SHA/dirty/diff AirDef, pin/identity движка,
API/WIT/артефакт, проверку build identity, сценарий, Wasmtime и исходные memory/fuel limits.
`AIRDEF_BUDGET_REPORT` меняет путь отчёта. Stale identity запрещает запуск, ошибки сборки/тестов
записываются как failed и дают ненулевой exit code.
Лимиты берутся из исходников: memory 64 MiB; fuel init/tick/frame/event — 2B/300M/10M/1B.
**Фактический расход fuel и peak memory не измеряются этим отчётом.** Сохранённый успешный прогон:
[API27 budget report](measurements/api27-wasm-budget.json).
Проверены реальный WASM guest с переходами состояний/владельца/мира, сборка клиента и два коротких
offscreen-профиля Metal. При `HORIZON_ACOUSTICS=1` + `HORIZON_NO_AUDIO=1` в игре получено
enabled/request=true, prepared=false, awaiting-backend; HD smoke переходит в ready после подготовки
основного кадра. Это не замер производительности и не прослушивание.
Остаток #102: аналогичные статусы света/камер/источников звука, полные query/voice/peak budgets,
GPU/готовый MP4 и платформенная приёмка. Эти результаты текущими тестами не объявляются выполненными.