docs: record API27 readiness and reverse logistics verification
build / mod (push) Failing after 19s
build / mod (push) Failing after 19s
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>
This commit is contained in:
@@ -30,6 +30,12 @@ python3 tools/airdef.py all # получить закреплённый дв
|
||||
python3 tools/airdef.py play # запустить (аргументы игры — после: --world "Имя мира")
|
||||
```
|
||||
|
||||
`all` синхронизирует URL сабмодуля из `.gitmodules`, включая обновление со старого upstream.
|
||||
Диагностика в игре: `/airdef capabilities` показывает доступность API, принятие запроса и
|
||||
подготовку дыма, акустики и захвата именно этого мода. Подготовка не означает готовый GPU-кадр или MP4.
|
||||
Для разработчика: `python3 tools/airdef.py test-wasm` — лёгкий ABI-тест;
|
||||
`python3 tools/airdef.py test-budgets` — отдельный тяжёлый сценарий с JSON-отчётом.
|
||||
|
||||
Для разработки: `./install.sh` перегенерирует модели (`tools/gen_models.py`, нужен Pillow) и звуки
|
||||
(`tools/gen_sounds.py`, нужны numpy и ffmpeg), собирает и ставит мод. Сгенерированные файлы лежат в репозитории,
|
||||
так что для обычной сборки нужен только Rust.
|
||||
@@ -105,7 +111,10 @@ P1-SUN также использует чужие данные. Пушкам (Г
|
||||
с ракетами ПВО. `/airdef ground-stock <склад> <количество>` задаёт конечный начальный запас
|
||||
sandbox-сценария, `/airdef ground-load <С-400>` загружает одну ракету рядом со складом либо
|
||||
создаёт заявку на доставку ТЗМ. Груз едет физически; снятая ракета ПВО возвращается на склад.
|
||||
Заявка и груз сохраняются в пути. `/airdef ground-unload <С-400>` выгружает ракету у склада.
|
||||
Заявка и груз сохраняются в пути. `/airdef ground-unload <С-400>` выгружает ракету у склада,
|
||||
а вдали создаёт заявку на обратный вывоз ТЗМ. Одна ракета резервируется от пуска до забора;
|
||||
`/airdef ground-cancel <С-400>` отменяет ещё ожидающую доставку или вывоз.
|
||||
После забора ракета находится в машине и едет на склад. Отмена заявки не возвращает уже вывезенный груз в ПУ.
|
||||
Без склада этот ударный боеприпас сам не появляется. Бук и остальные комплексы такого профиля пока не имеют.
|
||||
|
||||
**Перемещение.** **Пульт перемещения**: навестись на технику (выбрать), затем на точку на земле — она
|
||||
|
||||
+44
-4
@@ -6,7 +6,8 @@
|
||||
|
||||
## Текущее состояние: 3 ноября 2026
|
||||
|
||||
Код четырёх задач интегрирован и опубликован до `6e2d661`. Движок в этой серии не менялся.
|
||||
Код предыдущих четырёх задач интегрирован до `6e2d661`. Продолжение #102/обратного вывоза
|
||||
опубликовано до `aab3e78`; текущий движок — `c89c78c47047fcfc0dfb0b8968600c650bf12d2b`, API 27.
|
||||
README описывает доступное поведение; `IMPLEMENTATION-STATUS.md` отделяет реализацию от приёмки.
|
||||
Ни одно issue не закрыто. Участники: Codex (интеграция, #119, ревью, документация) и три
|
||||
GPT-6.1 Terra (энергетика, типизированная доставка, излучение). Новые числа — только игровые.
|
||||
@@ -23,6 +24,39 @@ GPT-6.1 Terra (энергетика, типизированная доставк
|
||||
`python3 tools/airdef.py all`, `python3 tools/airdef.py play`. `all` обновляет точный сабмодуль,
|
||||
собирает игру/мод и устанавливает пакет. На Windows обычно используется `python` вместо `python3`.
|
||||
|
||||
### Продолжение #102 и обратного вывоза RM48U
|
||||
|
||||
- `d3378b3`: `fork()` синхронизирует URL из `.gitmodules` даже на fast path совпавшего pin.
|
||||
Реальная Git-регрессия воспроизводит старый upstream URL и новый коммит, отсутствующий в локальном clone.
|
||||
Это исправляет наблюдавшееся на Windows `upload-pack: not our ref 86b1014…`; пользователь подтвердил
|
||||
ручное исправление через `git submodule sync --recursive` до публикации автоматизации.
|
||||
- `bb931ab`, `e9fbaba`, `b0085cb`: `ground-unload` вдали от склада резервирует одну RM48U и вызывает
|
||||
ТЗМ. `ground-cancel` отменяет ещё ожидающий вывоз/доставку; после забора груз продолжает путь на склад.
|
||||
Проверены физическое движение и полный save/restore до забора и после забора, без телепортации запаса.
|
||||
- `910f02c`: потеря зарезервированной ракеты вместе с ячейками сбрасывает заявку на вывоз.
|
||||
Иначе можно было создать сохранение, которое loader сам отвергал как несовместимое состояние.
|
||||
- Двигатель: `f4c1131d3`, затем `c89c78c47` опубликованы в `horizon-airdef:airdef` до обновления gitlink.
|
||||
API27 добавляет acoustics-status и capture-owner-status, scoped к запуску мода и поколению мира.
|
||||
Остановка capture проверяет владельца; смена мира снимает незапущенный запрос или посылает cancel.
|
||||
- `910f02c`: команда `/airdef capabilities`; дальний звуковой fallback сохраняется до подготовки
|
||||
акустического пути, экспорт принимает только своё подтверждённое состояние; Arming ждёт до 600 тиков.
|
||||
`prepared` — milestone хоста, не GPU fence, не результат каждой акустической трассы и не готовый MP4.
|
||||
- `4dddea2`, `8d5d0d1`: opt-in `test-budgets`, отдельный ручной workflow и JSON provenance;
|
||||
тесты ошибок сборки, stale identity и ненулевого runtime exit. Native success не заменяет actual WASM.
|
||||
- `aab3e78`: repo-local packer использует target-cache закреплённого движка; `CARGO_TARGET_DIR`
|
||||
не переопределяется для сборки самого мода и не уводит `.hmod` в чужое дерево.
|
||||
|
||||
Проверки объединённого состояния: core release **190 + 4 сценария**, 7 ignored;
|
||||
адаптер **60 + 1 boundary + 4 сценария**; лёгкий WASM **26 шагов**, тяжёлый **69 шагов**;
|
||||
Git-регрессия и три теста failure report прошли. Тяжёлый профиль: 64 ПВО + 160 целей,
|
||||
602 tick / 300 frame; JSON фиксирует clean `aab3e78`, pin API27 и совпадающий build identity.
|
||||
Полные данные: [budget report](measurements/api27-wasm-budget.json).
|
||||
|
||||
Дополнительно два свежих профиля игры на Metal/no-audio: smoke off не ready, HD smoke ready;
|
||||
при HORIZON_ACOUSTICS=1 + HORIZON_NO_AUDIO=1 акустика enabled/request=true, prepared=false,
|
||||
awaiting-backend. Выход через quit подтверждён. Это не прослушивание, не benchmark и не новый MP4.
|
||||
Правила API, пределы проверок и команды: [ENGINE.md](ENGINE.md).
|
||||
|
||||
## Исходная контрольная точка этой серии
|
||||
|
||||
Исходное состояние этой серии: `2689d93`; движок закреплён на
|
||||
@@ -158,8 +192,11 @@ SAMS=20 SIZE=12 cargo test --release --manifest-path airdef-core/Cargo.toml sim:
|
||||
с продолжением маршрута. GUI-доставка на сложном рельефе ещё не проверена.
|
||||
|
||||
Новых носителей вроде Бука не добавляли: один публичный игровой профиль не даёт основания
|
||||
приписывать его всем ЗРК. Обратный вывоз RM48U из удалённого носителя пока не автоматизирован:
|
||||
`ground-unload` требует склад рядом. Отдельной отмены ожидающей заявки в UI пока нет.
|
||||
приписывать его всем ЗРК. Обратный вывоз из удалённого носителя автоматизирован в продолжении выше.
|
||||
Новая команда `ground-cancel` отменяет ожидающую заявку, но не возвращает уже забранный груз в ПУ.
|
||||
ТЗМ вмещает два типизированных места RM48U/48Н6; прежние абстрактные generic reload-пакеты учитываются отдельно.
|
||||
Вывезенная ракета возвращается в конечный запас; ПВО восстанавливается при заборе только из реально
|
||||
имеющейся у ТЗМ ракеты 48Н6 и свободной ячейки. Резерв одной RM48U учитывается при выборе носителя удара.
|
||||
|
||||
### #121: излучение отдельно от сети
|
||||
|
||||
@@ -190,6 +227,8 @@ SAMS=20 SIZE=12 cargo test --release --manifest-path airdef-core/Cargo.toml sim:
|
||||
| 25–27 | mode, radar_role, spent_cells |
|
||||
| 28 | ground_request: 0/1, только С-400 |
|
||||
| 29 | radar_on: true/false, отсутствие означает true |
|
||||
| 30 | ground_return: true/false, резерв вывоза одной RM48U из С-400 |
|
||||
| 31 | return_cargo: true/false, возвращаемая RM48U на ТЗМ |
|
||||
|
||||
Две агентские ветки сначала заняли поле 28 одновременно; при интеграции излучение перенесено
|
||||
в 29, опубликованная совместимость заявки сохранена. Проверка полного roundtrip одновременно
|
||||
@@ -226,7 +265,8 @@ Unknown и поздний ответ без повторного урона/за
|
||||
5. Продолжить оставшиеся архитектурные #87/#88/#89/#91/#102 и художественный #115 по статусной таблице.
|
||||
|
||||
Это незавершённая платформенная/визуальная приёмка, а не отсутствие перечисленного выше кода.
|
||||
Текущий прогон не запускал GUI или новый MP4, не прослушивал звук и не проверял Windows/Linux.
|
||||
Прогон четырёх задач не запускал GUI/MP4. В продолжении API27 есть два коротких игровых smoke,
|
||||
но новый MP4, прослушивание и платформенная приёмка Windows/Linux по-прежнему не выполнены.
|
||||
|
||||
## Правила продолжения
|
||||
|
||||
|
||||
+53
-1
@@ -59,4 +59,56 @@ runtime закреплённого движка. Используется вре
|
||||
и причина (`awaiting-frame`, `disabled`, `path-unavailable`, `ready`). AirDef убирает обычный дым
|
||||
только когда выполнены все четыре условия; после смены мира старые сегменты и часы очищаются.
|
||||
Это подтверждение выбранного пути рендера, а не завершения GPU или видимости каждого сегмента.
|
||||
Для акустики и capture аналогичное подтверждение этим API не реализовано.
|
||||
Сам `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 и платформенная приёмка. Эти результаты текущими тестами не объявляются выполненными.
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
| #91 | Общий каталог доступности и потребители меню/инвентаря; явный RM48U-профиль; корректные подписи очередей | Единый источник всех чисел, звуков и Python-регистраций; проверка вариантов комплексов |
|
||||
| #92 | Authored overrides, проверка ссылок/PNG/границ, manifest, безопасная транзакционная генерация; registry/texture/icon modules | Дальнейшее ручное улучшение контента относится к #115 |
|
||||
| #96 | Акустические пути; измеренные синтетические occlusion/echo/reverb fixtures; лицензии и исходные notices в архивах | Прослушивание, игровой массовый звук/CPU, акустика реального MP4; точность RT60 пока по допуску 35%, не 15% |
|
||||
| #102 | Отдельный pinned engine, repo-local packer, build identity, настоящий WASM tier; API26 handshake дыма | Аналогичный статус для других возможностей, максимальные бюджеты и GPU/export tier |
|
||||
| #102 | Pinned engine/API27, repo-local packer/build identity; smoke/acoustics/capture-owner milestones; fallback и владение экспортом; 26 шагов лёгкого WASM и 69 тяжёлого; JSON provenance/failure tests; реальный Metal/no-audio smoke; автосинхронизация URL и Git-регрессия миграции | Статусы света/камер/sound sources, полные query/voice/peak budgets, GPU/готовый MP4 и Windows-приёмка |
|
||||
| #104 | Движок вынесен в `chexit/horizon-airdef`, ветка `airdef`; AirDef использует точный gitlink | Отдельная Windows-проверка миграции старого standalone checkout |
|
||||
| #107 | ПУ оценивается по наблюдениям: обратный курс не выдаёт точную ПУ | Повторная игровая проверка сценариев с маневрирующими целями |
|
||||
| #110 | Изменения чанков инвалидируют акустические снимки/кэш; включено в pin и проверено engine-тестами | Внешняя игровая приёмка на целевых машинах |
|
||||
@@ -20,7 +20,7 @@
|
||||
| #114 | Навигация учитывает footprint и окончательную authored-геометрию; остановка перед unread frontier; угловые пересечения | Массовая игровая проверка всех новых шасси на сложном рельефе |
|
||||
| #115 | Три пилота с кадрами до/после, спокойные материалы; authored-проход по боевым и вспомогательным машинам | Крупные планы и точность прототипов ещё промежуточные; остальные летательные аппараты/ракеты, анимации, дальние виды и FPS |
|
||||
| #116 | Streaming не освобождает busy-guard работающего acoustic worker; проверено engine-тестами | Внешняя игровая приёмка на целевых машинах |
|
||||
| #118 | Ручной пуск из физического С-400 с отдельным RM48U; четыре общие ячейки; конечный склад; доставка ТЗМ и возврат снятой ракеты ПВО; сохранение груза/заявки и продолжение реального маршрута; carrier, крышки, выброс, зажигание и разгон в записи; фантомное ПВО удалено | Визуальная приёмка всего пуска и доставки на сложном рельефе; другие носители не добавлены без подтверждённого профиля |
|
||||
| #118 | Физический С-400/RM48U, четыре общие ячейки, конечные запасы; доставка и обратный вывоз ТЗМ, резерв/отмена, возврат снятой ПВО; обе фазы вывозного маршрута сохраняются; carrier/крышки/выброс/зажигание/разгон в записи; фантомное ПВО удалено | Визуальная приёмка пуска и маршрутов на сложном рельефе; другие носители не добавлены без подтверждённого профиля |
|
||||
|
||||
Для #118 RM48U — явно условный Minecraft-профиль. Существование сочетания опирается на сообщение ведомства,
|
||||
а игровые параметры не выдаются за реальные. `ground-stock` — команда подготовки sandbox-сценария,
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"airdef": {
|
||||
"diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"dirty": false,
|
||||
"sha": "aab3e784b8a87d3af0741b8c47d3351cd68dc152"
|
||||
},
|
||||
"api_level": 27,
|
||||
"artifact_sha256": "faecb18f25210e694fb53a1f6f99afe4abc3060a68a0376555e8b1dc9114d612",
|
||||
"build_identity": {
|
||||
"checks": {
|
||||
"airdef_diff_sha256": true,
|
||||
"airdef_dirty": true,
|
||||
"airdef_sha": true,
|
||||
"artifact_sha256": true,
|
||||
"engine_identity": true,
|
||||
"engine_pin": true,
|
||||
"wit_sha256": true
|
||||
},
|
||||
"matches": true,
|
||||
"path": "airdef-mod/target/horizon-mod/build-identity.json"
|
||||
},
|
||||
"command": "test-budgets",
|
||||
"engine": {
|
||||
"identity": "c89c78c47047fcfc0dfb0b8968600c650bf12d2b",
|
||||
"pin": "c89c78c47047fcfc0dfb0b8968600c650bf12d2b"
|
||||
},
|
||||
"exit_code": 0,
|
||||
"output": " Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.34s\n Running `<checkout>/horizon/target/debug/cargo-horizon-mod horizon-mod test --hmod <checkout>/airdef-mod/target/horizon-mod/airdef.hmod budget`\nrunning 1 scripts against <checkout>/airdef-mod/target/horizon-mod/airdef.hmod\ntest tests/wasm_budget.toml ... ok (69 steps)\ntest result: ok. 1 passed\n",
|
||||
"runtime_limits": {
|
||||
"fuel_per_call": {
|
||||
"event": 1000000000,
|
||||
"frame": 10000000,
|
||||
"init": 2000000000,
|
||||
"tick": 300000000
|
||||
},
|
||||
"memory_bytes": 67108864,
|
||||
"metering": "source_configured; measured_per_scenario: unavailable",
|
||||
"source": "horizon/crates/horizon-mods/src/runtime.rs",
|
||||
"wasmtime_component_model": true,
|
||||
"wasmtime_fuel_metering": true
|
||||
},
|
||||
"scenario": "tests/budgets/wasm_budget.toml",
|
||||
"scenario_counts": {
|
||||
"air_defense_units": 64,
|
||||
"frames": 300,
|
||||
"layout_unit_limit": 2000,
|
||||
"max_units_per_raid": 80,
|
||||
"raid_units": 160,
|
||||
"raids": 2,
|
||||
"scripts": 1,
|
||||
"steps": 69,
|
||||
"ticks": 602
|
||||
},
|
||||
"scenario_sha256": "58490798d6e70910e188ffe8fd282fbf975fec5548287561b227fc53e06bf7e6",
|
||||
"schema": 1,
|
||||
"status": "passed",
|
||||
"wasmtime_version": "48.0.7",
|
||||
"wit_sha256": "14c57b73f144888e04e27b77a6dfa29098c6b0c27c0383bb96aedaccb4c0a1d4"
|
||||
}
|
||||
Reference in New Issue
Block a user