Report camera readiness in /airdef capabilities
Pin the engine at 6a53a626c (API 30) and show render.camera-status: the calling run's set-views cameras, whether the last noted frame was a world frame, the request's world generation, each camera's reason and the run's own main-view selection. As the other lines, this is a host milestone: availability, request, preparation and why, not a GPU frame or a visible picture. A unit test pins the line: readiness stays per camera and apart from the run's main-view selection. docs/ENGINE.md, the 4 November continuation and the status table now say what prepared means (a picture encoded into the camera's target, or a world frame drawn from it as this run's screen view, only for the run whose selection the screen used), the per-run/per-world resets, and what remains: GPU acceptance. Verified: python3 tools/airdef.py check (gitlink, packer, mod needs 30, fork 30, game 30); test-wasm 27 steps; airdef-mod 65 unit, 1 boundary and 5 scenarios; python3 -m unittest discover -s tools 28 tests. Co-Authored-By: Kimi Code <noreply@moonshot.cn>
This commit is contained in:
@@ -59,12 +59,42 @@ fn line(
|
||||
format!("{name}: API={available}, включено={enabled}, запрос={accepted}, подготовлено={prepared}, поколение={generation}, {why}")
|
||||
}
|
||||
|
||||
fn camera_line(s: &render::CameraState) -> String {
|
||||
let cameras: Vec<String> = s
|
||||
.cameras
|
||||
.iter()
|
||||
.map(|c| {
|
||||
let why = match c.reason {
|
||||
render::CameraReason::AwaitingFrame => "awaiting-frame",
|
||||
render::CameraReason::Ready => "ready",
|
||||
};
|
||||
format!("{}:{}", c.id, why)
|
||||
})
|
||||
.collect();
|
||||
let main = match s.main_view {
|
||||
Some(id) => id.to_string(),
|
||||
None => "нет".into(),
|
||||
};
|
||||
format!(
|
||||
"Камеры: API={}, включено={}, запрос={}, подготовлено={}, поколение={}, {}, main={}, [{}]",
|
||||
s.available,
|
||||
s.enabled,
|
||||
s.request_accepted,
|
||||
s.prepared,
|
||||
s.generation,
|
||||
reason(s.reason),
|
||||
main,
|
||||
cameras.join("; ")
|
||||
)
|
||||
}
|
||||
|
||||
pub fn diagnostics() -> String {
|
||||
let smoke = render::smoke_status();
|
||||
let acoustic = acoustics();
|
||||
let capture = render::capture_owner_status();
|
||||
let lights = render::point_lights_status();
|
||||
let sources = render::sound_sources_status();
|
||||
let cameras = render::camera_status();
|
||||
let smoke_reason = match smoke.reason {
|
||||
render::SmokeReason::AwaitingFrame => "awaiting-frame",
|
||||
render::SmokeReason::Disabled => "disabled",
|
||||
@@ -72,7 +102,7 @@ pub fn diagnostics() -> String {
|
||||
render::SmokeReason::Ready => "ready",
|
||||
};
|
||||
[
|
||||
"Возможности движка (API 29; подготовка не означает готовый GPU-кадр, слышимый звук или файл):".into(),
|
||||
"Возможности движка (API 30; подготовка не означает готовый GPU-кадр, слышимый звук или файл):".into(),
|
||||
line(
|
||||
"Дым",
|
||||
smoke.generation,
|
||||
@@ -109,6 +139,7 @@ pub fn diagnostics() -> String {
|
||||
sources.prepared,
|
||||
reason(sources.reason),
|
||||
),
|
||||
camera_line(&cameras),
|
||||
line(
|
||||
"Захват этого мода",
|
||||
capture.generation,
|
||||
@@ -164,4 +195,46 @@ mod tests {
|
||||
s.reason = CapabilityReason::Failed;
|
||||
assert!(capture_problem(&s).is_some());
|
||||
}
|
||||
fn camera(id: u32, prepared: bool) -> render::CameraReadiness {
|
||||
render::CameraReadiness {
|
||||
id,
|
||||
request_accepted: true,
|
||||
prepared,
|
||||
reason: if prepared {
|
||||
render::CameraReason::Ready
|
||||
} else {
|
||||
render::CameraReason::AwaitingFrame
|
||||
},
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn the_camera_line_separates_readiness_from_the_screens_selection() {
|
||||
let line = camera_line(&render::CameraState {
|
||||
generation: 5,
|
||||
available: true,
|
||||
enabled: true,
|
||||
request_accepted: true,
|
||||
prepared: true,
|
||||
reason: CapabilityReason::Ready,
|
||||
cameras: vec![camera(7, true), camera(8, false)],
|
||||
main_view: Some(7),
|
||||
});
|
||||
assert_eq!(
|
||||
line,
|
||||
"Камеры: API=true, включено=true, запрос=true, подготовлено=true, поколение=5, \
|
||||
ready, main=7, [7:ready; 8:awaiting-frame]"
|
||||
);
|
||||
// No accepted submission: no cameras, no main view, and the reason says so.
|
||||
let line = camera_line(&render::CameraState {
|
||||
generation: 5,
|
||||
available: true,
|
||||
enabled: false,
|
||||
request_accepted: false,
|
||||
prepared: false,
|
||||
reason: CapabilityReason::NotRequested,
|
||||
cameras: Vec::new(),
|
||||
main_view: None,
|
||||
});
|
||||
assert!(line.ends_with("not-requested, main=нет, []"), "{line}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,13 @@
|
||||
`/airdef capabilities` показывает оба состояния (`c1a595b`).
|
||||
`57f8b2853` также устраняет коллизию камер: texture targets, scheduler, HUD/canvas/corner и
|
||||
main-view адресуются `(run_serial, local_id)`. Проверены два настоящих гостя с одинаковым ID,
|
||||
поиск target и scheduler, компиляция клиента. Camera-ready API и GPU-проверка ещё не добавлены.
|
||||
поиск target и scheduler, компиляция клиента.
|
||||
`efe017ffb`/`278f356aa` добавляют API30 `camera-status`: `prepared` — закодированный в target
|
||||
кадр камеры или кадр мира с её main-view, причём milestone получает только тот запуск, чей выбор
|
||||
экран реально использовал (чужой тот же local ID и чужая картинка его не готовят). `enabled` —
|
||||
последний отмеченный кадр был кадром мира, не заголовком. Пустая `set-views` и смена мира
|
||||
очищают заявку/выбор/готовность, reload начинает заново; главный вид теряет picture target до
|
||||
нового кадра. Проверено настоящими Wasmtime-гостями; GPU-приёмка не выполнялась.
|
||||
- **#96:** engine `e44ad82a9`: opt-in `audio::tests::export_moving_mass_raid` проводит
|
||||
100 движущихся двигателей и 16 импульсных источников через настоящие `Audio::tick_acoustics`
|
||||
и `film_mix`: эхо/реверб, камера, инвалидация и смена epoch, новый capture без старого хвоста.
|
||||
@@ -82,7 +88,7 @@ GUI/MP4 и варианты комплексов (разные ракеты/пр
|
||||
command max 1013387/1000000000, ошибок 0, build identity совпал.
|
||||
|
||||
Не завершены: субъективное прослушивание, настоящий MP4 с акустикой, полный 10-минутный
|
||||
replay/export, расширенная модельная/ночная/FPS приёмка, camera-ready milestone и полные
|
||||
replay/export, расширенная модельная/ночная/FPS приёмка, GPU-приёмка camera-ready картинки и полные
|
||||
query/voice/peak-memory бюджеты. Старый допуск broadband RT60 35% не ужесточался до 15%.
|
||||
Попытка живого MP4 в этом проходе не дала проверенного файла и за приёмку не считается;
|
||||
изолированные процессы закрыты. Продолжать с текущего pin, не с временных пакетов агентов.
|
||||
|
||||
+18
-5
@@ -63,8 +63,8 @@ runtime закреплённого движка. Используется вре
|
||||
|
||||
## Акустика и владение захватом (API 27)
|
||||
|
||||
Текущий pin: `73b9d307048fc44d7f21fa3c829fc5a855d144a6` (API 29; поверх `57f8b2853` — очистка
|
||||
неудачного захвата). Акустические
|
||||
Текущий pin: `278f356aa604fa21c2d15d0081823bbe0f891df2` (API 30; поверх API29 — нормали моделей
|
||||
и очистка неудачного захвата). Акустические
|
||||
`render.acoustics-status` и `render.capture-owner-status` возвращают поколение,
|
||||
`available`, `enabled`, `request-accepted`, `prepared` и причину. В игре всё это показывает
|
||||
`/airdef capabilities`. Отсутствие запроса, выключение, ожидание backend и ошибка различаются.
|
||||
@@ -152,10 +152,23 @@ API28/29 добавляют отдельные `point-lights-status` и `sound-s
|
||||
после cache/main-view HD обработки, звук — после source-manager apply с live/offline output.
|
||||
Заявки привязаны к запуску мода и поколению мира; звук также к source epoch. Clear/reload/выход
|
||||
снимают подтверждение. Это не GPU fence, загрузка сэмпла, наличие голоса или слышимость.
|
||||
Камеры и их targets теперь изолированы по `(run_serial, local_id)` вместо глобального ID.
|
||||
Camera-ready API пока отсутствует; проверки хоста не заменяют GPU-приёмку.
|
||||
Камеры и их targets изолированы по `(run_serial, local_id)` вместо глобального ID.
|
||||
|
||||
Остаток #102: статус камер, полные query/voice/peak budgets,
|
||||
API30 добавляет `camera-status` для камер `set-views` вызывающего запуска: доступность API,
|
||||
включение пути картинок в последнем отмеченном кадре, принятие заявки поколения и поштучная
|
||||
готовность каждой камеры. `prepared` означает, что рендерер закодировал кадр камеры в её
|
||||
texture target, либо кадр мира отрендерен с неё как main-view **этого** запуска: если одинаковый
|
||||
local ID выбрали два мода, экран использует выбор первого, и milestone получает только он; чужая
|
||||
картинка с тем же ID чужую камеру не готовит. `enabled` — последний отмеченный кадр был кадром
|
||||
мира (не заголовок/загрузка). Это не регистрация target и не GPU fence: видимый пиксель,
|
||||
представление кадра и обход ротации per-frame бюджета не гарантируются. Пустая `set-views`
|
||||
снимает заявку и готовность; смена мира очищает заявку, выбор main-view и готовность (камеры
|
||||
другого мира не рисуются), перезагрузка мода начинает заново, а повторная отправка и камера,
|
||||
отданная в main-view, ждут нового кадра (у такой камеры нет своего picture target).
|
||||
Проверено двумя настоящими Wasmtime-гостями с одинаковым local ID, пустой заявкой, сменой мира
|
||||
и reload. `/airdef capabilities` показывает строку камер. Проверки хоста не заменяют GPU-приёмку.
|
||||
|
||||
Остаток #102: полные query/voice/peak budgets,
|
||||
GPU/готовый MP4 и платформенная приёмка. Эти результаты текущими тестами не объявляются выполненными.
|
||||
|
||||
## Измеренный fuel и массовые взрывы
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
|
||||
Новый проверенный объём: [продолжение пяти задач 4 ноября](CONTINUATION-2026-11-04.md).
|
||||
#87: typed battery/world/damage diagnostics и адаптеры текста; #91: общий content/sound catalog
|
||||
для Rust и Python; #102: измеренный fuel, API29 light/source milestones и изоляция камер;
|
||||
#96: массовый deterministic offline capture; #115: authored Lancet/Х-101 и кадры инстансов.
|
||||
Текущий engine pin — API29; старые номера/числа ниже описывают предыдущие этапы.
|
||||
для Rust и Python; #102: измеренный fuel, API29 light/source milestones, API30 camera-status
|
||||
и изоляция камер; #96: массовый deterministic offline capture; #115: authored Lancet/Х-101
|
||||
и кадры инстансов.
|
||||
Текущий engine pin — API30; старые номера/числа ниже описывают предыдущие этапы.
|
||||
Проблема нормалей модели #123 исправлена в engine `45b43f00d`; парные HD-кадры и ночная проверка Lancet записаны в галерее.
|
||||
|
||||
| Issue | Реализовано | Что остаётся для полной приёмки |
|
||||
@@ -19,7 +20,7 @@
|
||||
| #91 | Общий каталог доступности и потребители меню/инвентаря; явный RM48U-профиль; корректные подписи очередей; `catalog/specs.json` — единственный источник числовых строк, из него генерируются Rust-таблицы для мода и `airdef-core`, CI проверяет свежесть | Варианты комплексов (разные ракеты/профили по батареям) и игровая приёмка; каталог остаётся статичными данными, не динамическим ECS |
|
||||
| #92 | Authored overrides, проверка ссылок/PNG/границ, manifest, безопасная транзакционная генерация; registry/texture/icon modules | Дальнейшее ручное улучшение контента относится к #115 |
|
||||
| #96 | Акустические пути; измеренные синтетические occlusion/echo/reverb fixtures; лицензии и исходные notices в архивах; настоящий MP4 с акустикой: пары on/off, статусы ready, окклюзия/поглощение и диффузный wet-остаток в замкнутой геометрии | Прослушивание, игровой массовый звук/CPU, чистый хвост/RT60 в MP4; точность RT60 пока по допуску 35%, не 15% |
|
||||
| #102 | Pinned engine/API29, packer/build identity; smoke/acoustics/capture-owner/light/source milestones; fallback/владение; WASM27 и flat stress271; измеренный callback fuel; JSON provenance/failure tests; Metal/no-audio smoke; URL/Git-регрессия; owner-scoped camera targets | Старое69-шаговое утверждение о перекрытии отозвано; статус камер, полные query/voice/peak budgets, GPU/готовый MP4 и Windows-приёмка остаются |
|
||||
| #102 | Pinned engine/API30, packer/build identity; smoke/acoustics/capture-owner/light/source/owner-scoped camera milestones; fallback/владение; WASM27 и flat stress271; измеренный callback fuel; JSON provenance/failure tests; Metal/no-audio smoke; URL/Git-регрессия; camera-ready по закодированному кадру с per-run/per-world сбросом | Старое69-шаговое утверждение о перекрытии отозвано; GPU-приёмка картинки камер, полные query/voice/peak budgets, GPU/готовый MP4 и Windows-приёмка остаются |
|
||||
| #104 | Движок вынесен в `chexit/horizon-airdef`, ветка `airdef`; AirDef использует точный gitlink | Отдельная Windows-проверка миграции старого standalone checkout |
|
||||
| #107 | ПУ оценивается по наблюдениям: обратный курс не выдаёт точную ПУ | Повторная игровая проверка сценариев с маневрирующими целями |
|
||||
| #110 | Изменения чанков инвалидируют акустические снимки/кэш; включено в pin и проверено engine-тестами | Внешняя игровая приёмка на целевых машинах |
|
||||
|
||||
+1
-1
Submodule horizon updated: 73b9d30704...278f356aa6
Reference in New Issue
Block a user