feat(runtime): bound static preview graph roots
Docs Deploy / Build and Deploy MkDocs (push) Successful in 39s
Test / Lint (push) Failing after 2m4s
Test / Test (push) Skipped
Test / Render parity (push) Skipped

This commit is contained in:
2026-07-18 09:45:57 +04:00
parent 0eaa56c10b
commit 2772c39e41
4 changed files with 35 additions and 32 deletions
+1 -1
View File
@@ -27,7 +27,7 @@ Open source проект с реализацией компонентов игр
- [apps/fparkan-cli](apps/fparkan-cli) — CLI для архивов, графов и acceptance-отчетов. - [apps/fparkan-cli](apps/fparkan-cli) — CLI для архивов, графов и acceptance-отчетов.
- [apps/fparkan-viewer](apps/fparkan-viewer) — inspection-only CLI для archive/model/texture/map без live Vulkan draw path. - [apps/fparkan-viewer](apps/fparkan-viewer) — inspection-only CLI для archive/model/texture/map без live Vulkan draw path.
- [apps/fparkan-headless](apps/fparkan-headless) — headless runtime composition root. - [apps/fparkan-headless](apps/fparkan-headless) — headless runtime composition root.
- [apps/fparkan-game](apps/fparkan-game) — mission composition root: по умолчанию выдаёт planning report; opt-in `--backend static-vulkan` использует bounded preview loader и открывает native Vulkan окно для первой mesh-backed MSH-модели. - [apps/fparkan-game](apps/fparkan-game) — mission composition root: по умолчанию выдаёт planning report; opt-in `--backend static-vulkan` использует first-root preview loader и открывает native Vulkan окно для первой MSH-модели выбранного root.
## Текущий статус рендера ## Текущий статус рендера
+11 -7
View File
@@ -191,7 +191,7 @@ enum MissionAssetScope {
/// Prepare every reachable asset; required by normal runtime loading. /// Prepare every reachable asset; required by normal runtime loading.
#[default] #[default]
Full, Full,
/// Prepare one root at a time until a mesh-backed preview model is found. /// Prepare only the first mission root for a static preview.
FirstMeshPreview, FirstMeshPreview,
} }
@@ -476,9 +476,9 @@ pub fn load_mission(
/// Loads a mission using the bounded static-preview asset scope. /// Loads a mission using the bounded static-preview asset scope.
/// ///
/// This mode preserves map, TMA, graph, construction and registration work, /// This mode preserves map, TMA, graph, construction and registration work,
/// but prepares only the first root that supplies a mesh-backed model. It is /// but visits only the first mission root. It is intended solely for the
/// intended solely for the opt-in static Vulkan preview and must not be used /// opt-in static Vulkan preview and must not be used for normal gameplay,
/// for normal gameplay, where all reachable assets remain required. /// where all reachable assets remain required.
/// ///
/// # Errors /// # Errors
/// ///
@@ -630,8 +630,12 @@ fn load_mission_with_options_and_progress(
.iter() .iter()
.map(|object| resource_name(&object.resource_name.raw)) .map(|object| resource_name(&object.resource_name.raw))
.collect(); .collect();
let scoped_graph_roots = match options.asset_scope {
MissionAssetScope::Full => graph_roots.as_slice(),
MissionAssetScope::FirstMeshPreview => graph_roots.get(..1).unwrap_or_default(),
};
let (mut prototype_graph, resolved_prototypes, mut prototype_report) = let (mut prototype_graph, resolved_prototypes, mut prototype_report) =
build_prototype_graph_report(&repository, vfs.as_ref(), &graph_roots); build_prototype_graph_report(&repository, vfs.as_ref(), scoped_graph_roots);
extend_graph_report_with_visual_dependencies( extend_graph_report_with_visual_dependencies(
&repository, &repository,
&mut prototype_report, &mut prototype_report,
@@ -649,7 +653,7 @@ fn load_mission_with_options_and_progress(
&prototype_graph.root_prototype_request_spans, &prototype_graph.root_prototype_request_spans,
&resolved_prototypes, &resolved_prototypes,
), ),
MissionAssetScope::FirstMeshPreview => prepare_first_mesh_preview_assets( MissionAssetScope::FirstMeshPreview => prepare_first_preview_assets(
&asset_manager, &asset_manager,
&prototype_graph.root_prototype_request_spans, &prototype_graph.root_prototype_request_spans,
&resolved_prototypes, &resolved_prototypes,
@@ -769,7 +773,7 @@ fn record_load_phase(
} }
} }
fn prepare_first_mesh_preview_assets<R: ResourceRepository>( fn prepare_first_preview_assets<R: ResourceRepository>(
asset_manager: &AssetManager<R>, asset_manager: &AssetManager<R>,
root_spans: &[std::ops::Range<usize>], root_spans: &[std::ops::Range<usize>],
prototypes: &[fparkan_prototype::EffectivePrototype], prototypes: &[fparkan_prototype::EffectivePrototype],
+8 -8
View File
@@ -13,7 +13,7 @@
| `RecordingBackend` | No | No | Optional CPU-side IDs only | `covered-planning` | Stable command capture for backend-neutral tests | Native window, Vulkan, GPU resource lifetime, pixels | | `RecordingBackend` | No | No | Optional CPU-side IDs only | `covered-planning` | Stable command capture for backend-neutral tests | Native window, Vulkan, GPU resource lifetime, pixels |
| `NullBackend` | No | No | Optional CPU-side IDs only | Usually `covered` for validation-only rows | Command stream framing and bounds validation | Capture stability, GPU execution, pixels | | `NullBackend` | No | No | Optional CPU-side IDs only | Usually `covered` for validation-only rows | Command stream framing and bounds validation | Capture stability, GPU execution, pixels |
| `VulkanAssetRenderer` | Yes | Yes | Yes | `covered-gpu` | Static original asset rendering: MSH/Texm/WEAR/MAT0/terrain through Vulkan | Animation/FX parity unless explicitly wired | | `VulkanAssetRenderer` | Yes | Yes | Yes | `covered-gpu` | Static original asset rendering: MSH/Texm/WEAR/MAT0/terrain through Vulkan | Animation/FX parity unless explicitly wired |
| `fparkan-game --backend static-vulkan` | Implemented; native run not yet accepted on a full corpus mission | Implemented static MSH draw | First prepared MSH from loaded mission assets | Not yet `covered-gpu` | Opt-in mission-to-native-window bootstrap, static MSH projection and synchronized teardown telemetry | Full mission scene, texture/material binding, placed transforms/orientation, camera, gameplay, original-runtime parity | | `fparkan-game --backend static-vulkan` | Yes, GOG `Autodemo.00` | Yes, static MSH draw | First MSH from first mission root | `covered-gpu` only for the narrow static-preview bridge | Opt-in mission-to-native-window bootstrap, static MSH projection and synchronized teardown telemetry | Full mission scene, texture/material binding, placed transforms/orientation, camera, gameplay, original-runtime parity |
| Future rendered `fparkan-game` mode | Yes | Yes | Yes | `covered-gpu` plus original-evidence IDs | Mission-driven render snapshot execution and pixel capture | Original-runtime parity for animation/FX/x87 without dedicated captures | | Future rendered `fparkan-game` mode | Yes | Yes | Yes | `covered-gpu` plus original-evidence IDs | Mission-driven render snapshot execution and pixel capture | Original-runtime parity for animation/FX/x87 without dedicated captures |
## Rules ## Rules
@@ -36,13 +36,13 @@
synthetic window descriptor и `VulkanPlanningBackend`. Opt-in `--backend static-vulkan` synthetic window descriptor и `VulkanPlanningBackend`. Opt-in `--backend static-vulkan`
уже создаёт native `winit` window и передаёт первую подготовленную MSH модели миссии в уже создаёт native `winit` window и передаёт первую подготовленную MSH модели миссии в
`VulkanSmokeRenderer` с пустым списком materials (явный white-fallback). Режим использует `VulkanSmokeRenderer` с пустым списком materials (явный white-fallback). Режим использует
отдельный bounded preview loader: normal `load_mission` по-прежнему готовит все reachable отдельный first-root preview loader: normal `load_mission` по-прежнему готовит все reachable
assets, тогда как preview останавливает asset preparation после первого root с mesh-backed assets и весь graph, тогда как preview строит graph и готовит assets только для первого
model. `--load-progress <file>` writes the last entered loader phase synchronously for timeout mission root. `--load-progress <file>` writes the last entered loader phase synchronously for
diagnosis. This is not rendered acceptance: fresh GOG `MISSIONS/Autodemo.00/data.tma` test timeout diagnosis. Fresh GOG `MISSIONS/Autodemo.00/data.tma` run passed in 38.7 seconds with
with this scope still did not reach a window in the local 120-second runner; its checkpoint one presented frame, native 1280×720 swapchain (2 images), 7,372,800-byte readback hash
was `Graph`, therefore no live report, pixel artifact or validation evidence exists for the `10681850560830502773`, and validation warnings/errors `0/0`. This is `covered-gpu` evidence
game path. for that narrow static-preview bridge only, not full-scene or original-renderer parity.
- `apps/fparkan-viewer` сейчас inspection-only CLI и не открывает live Vulkan - `apps/fparkan-viewer` сейчас inspection-only CLI и не открывает live Vulkan
asset viewer. asset viewer.
- Следующий реальный milestone для rendered acceptance: `VulkanAssetRenderer` - Следующий реальный milestone для rendered acceptance: `VulkanAssetRenderer`
+15 -16
View File
@@ -937,8 +937,8 @@ from a runtime slot or draw order.
### Opt-in mission static-Vulkan bridge ### Opt-in mission static-Vulkan bridge
`fparkan-game --backend static-vulkan` is an explicit native-window experiment, `fparkan-game --backend static-vulkan` is an explicit native-window experiment,
not the default planning path. After mission loading it selects the first not the default planning path. It visits only the first mission root, selects
prepared MSH model, sends it through the existing static XZ clip-space its prepared MSH model, sends it through the existing static XZ clip-space
projection and renders a requested number of frames through projection and renders a requested number of frames through
`VulkanSmokeRenderer`; teardown rejects validation warnings/errors and reports `VulkanSmokeRenderer`; teardown rejects validation warnings/errors and reports
swapchain/readback telemetry. It deliberately supplies no material textures, swapchain/readback telemetry. It deliberately supplies no material textures,
@@ -946,21 +946,20 @@ so the renderer's documented white fallback is used.
This is a narrow bootstrap from mission assets to a live Vulkan renderer. It This is a narrow bootstrap from mission assets to a live Vulkan renderer. It
does not render every placed object, apply TMA transforms or orientation, bind does not render every placed object, apply TMA transforms or orientation, bind
WEAR/MAT0/TEXM material data, or establish a game camera. A GOG WEAR/MAT0/TEXM material data, or establish a game camera. Fresh GOG
`MISSIONS/Autodemo.00/data.tma` attempt exceeded the local 120-second runner `MISSIONS/Autodemo.00/data.tma` evidence now proves the narrow GPU bridge: one
limit before the window/report, so this mode has implementation and unit/lint presented frame completed in 38.7 seconds with a native 1280×720 two-image
evidence only, not a corpus GPU acceptance claim. swapchain, 7,372,800-byte synchronized readback (FNV-1a
`10681850560830502773`) and validation warnings/errors `0/0`. This is not a
full-scene or original-renderer pixel-parity claim.
The preview now asks `load_mission_static_preview` for assets. Normal mission The preview now asks `load_mission_static_preview` for both graph and assets.
loading remains full and transactional; the preview scope walks root spans in Normal mission loading remains full and transactional; preview graph traversal
TMA order and stops asset preparation after the first mesh-backed model. It is and asset preparation are restricted to the first TMA root. It is therefore not
therefore not a hidden relaxation of gameplay validation. A second GOG a hidden relaxation of gameplay validation. The preceding all-root preview
`Autodemo.00` attempt with this narrower asset scope still exceeded 120 seconds probe timed out at `Graph`; this reduction is what allowed the successful GOG
before opening a window. The diagnostic `--load-progress <file>` checkpoint native run. If that first root has no usable MSH, static preview fails explicitly
reported `Graph`, which proves the remaining startup cost is in prototype graph rather than expanding later roots or pretending to render the entire mission.
construction/visual-dependency expansion rather than terrain decode, asset
preparation, window creation or the Vulkan draw loop. The timeout probe does
not distinguish individual graph suboperations; no renderer acceptance follows.
`Land.msh` использует отдельный geometry-only bridge: validated `TerrainFace28` `Land.msh` использует отдельный geometry-only bridge: validated `TerrainFace28`
сохраняет source triangle order, а его positions и packed UV0 попадают в тот же сохраняет source triangle order, а его positions и packed UV0 попадают в тот же