134 lines
8.2 KiB
Markdown
134 lines
8.2 KiB
Markdown
# Render-pack compatibility and failure handling v1
|
|
|
|
**Campaign phase id:** **TBD**
|
|
|
|
Compatibility is a declaration and activation result, not a promise inferred
|
|
from a GPU brand. The client keeps unsupported packs visible with one exact
|
|
reason, refuses to select an unavailable preset, and continues rendering the
|
|
authoritative acdream default (retail-faithful) path.
|
|
|
|
## Author responsibilities
|
|
|
|
- Declare every mandatory facility in `RequiredCapabilities`. Use
|
|
`OptionalCapabilities` only when the pack has a deterministic path that does
|
|
not need it.
|
|
- Gate each preset independently. Low must remain semantically correct; lower
|
|
shadow resolution or reach rather than silently removing trees, monsters,
|
|
players, buildings, alpha cutouts, or animated transforms.
|
|
- Keep resource estimates conservative and below the preset and 256 MiB SDK
|
|
ceilings. The host clamps dimensions and bytes before allocation. Its
|
|
optional-pack memory policy admits at most one eighth of the selected
|
|
adapter's probed device-local heap, capped at 256 MiB resident and 512 MiB
|
|
transient multisample storage; the lower value wins and is printed in an
|
|
unavailable-preset reason.
|
|
- Use only declared hooks, semantic inputs, resources, scene replays and base
|
|
pipeline variants. Pack code receives no arbitrary per-frame callback,
|
|
command buffer, gameplay owner, RHI object, or Vulkan handle.
|
|
- Treat registration as pure declaration publication. `OpenRead` must return a
|
|
new readable stream for the exact requested key and must not retain a world
|
|
generation or borrowed frame state.
|
|
- Ship SPIR-V words little-endian, four-byte aligned, no larger than 16 MiB per
|
|
asset, and compatible with the published v1 semantic binding ABI. Both the
|
|
SDK and client validate the binary stage, `main` entry point, descriptor
|
|
allowlist, exact uniform/push layouts, and read-only storage contract before
|
|
pipeline creation. Vertex and fragment keys are independent logical keys;
|
|
the selected candidate copies their blobs and never resolves them through
|
|
the host shader directory.
|
|
- Declare no more than 64 settings and keep their descriptor order stable. The
|
|
set-3/binding-8 shader mapping is positional: a persisted user override wins
|
|
the selected-preset override, which wins the declaration default. Boolean
|
|
becomes 0/1, Choice becomes its zero-based choice index, numeric strings use
|
|
invariant culture, and unused or defensively invalid slots are zero. The
|
|
selected descriptor validates every user string against kind, range, step,
|
|
and choices before activation.
|
|
|
|
## Client transaction
|
|
|
|
1. Discover the manifest and descriptor without opening assets or constructing
|
|
GPU objects.
|
|
2. Compare required capabilities and preset ceilings with the active physical
|
|
device's probed `maxImageDimension2D`, `maxImageArrayLayers`, device-local
|
|
heap bytes, and format/timestamp support. An unsupported pack remains
|
|
installed and its individual presets remain visible with exact
|
|
needed-versus-provided reasons.
|
|
3. After explicit selection, validate every referenced asset and shader
|
|
interface, then build every resource and pipeline in an isolated candidate.
|
|
4. Activate the complete candidate at a stable frame boundary. Until that
|
|
point retail keeps rendering.
|
|
5. If any step fails, retire the candidate through normal GPU-flight fences,
|
|
record one stable diagnostic, select `acdream default`, and do not retry
|
|
that pack again during the session.
|
|
|
|
No half-enabled graph is valid. A missing bloom shader does not leave shadows
|
|
active; a failed shadow pipeline does not leave a world-colour intermediate or
|
|
stale descriptor alive.
|
|
|
|
Auto is a logical selector rather than an allocated preset. It requires
|
|
asynchronous GPU timestamps, starts at Medium when Medium fits, otherwise
|
|
starts and stays at Low, and never promotes beyond the highest contiguous
|
|
compatible preset. If Low itself cannot fit, Auto fails safely to Retail and
|
|
reports the Low limit that failed.
|
|
|
|
Runtime Auto decisions use the active preset's declared inclusive-GPU p99,
|
|
pack-added CPU p99, and resident-GPU budgets. An over-budget Medium selection
|
|
can step down to Low; if Low then remains over any declared limit for 180
|
|
stable samples, the host atomically deactivates the complete pack, reports the
|
|
measured and budget values, and enters `FailedToRetail` without a retry loop.
|
|
This performance fallback is Auto-only. Explicit Low remains selectable when
|
|
only timestamp support is missing and is never silently reduced by removing
|
|
terrain, trees, buildings, monsters, players, alpha cutouts, or animated
|
|
casters. The built-in Low preset instead uses two 768 x 768 shadow maps and an
|
|
unfused six-pass, quarter-resolution separable post chain. An ordinary explicit
|
|
Low validation, candidate-build, or runtime failure still follows the complete
|
|
transactional fallback rules above.
|
|
|
|
## Diagnostic categories
|
|
|
|
| Category | Example user-facing reason | Recovery |
|
|
|---|---|---|
|
|
| Manifest | `plugin.json does not declare the renderPack kind` | Correct/reinstall the package |
|
|
| Managed ABI | `apiVersion 2 is unsupported; this SDK supports 1..1` | Use a compatible client or rebuild the pack |
|
|
| Pack ABI | `requires render-pack API 2; this client supports 1..1` | Same as above |
|
|
| Capability | `requires unsupported capability DirectionalShadowMaps` | Select a supported preset/device or retail |
|
|
| Declaration | `Pass 'blur' reads resource 'bloom-a' before it is written` | Correct the descriptor |
|
|
| User setting | `user override 'exposure' has invalid Float value '1,5'` | Correct/remove that stable setting-ID override; retail remains active |
|
|
| Asset | `asset 'bloom.frag.spv' is not valid SPIR-V` | Rebuild/reinstall the pack |
|
|
| Shader interface | `AtmosphericFrame block does not match v1` | Recompile against the v1 binding table |
|
|
| Resource ceiling | `preset 'high' exceeds the pack memory ceiling` | Reduce the preset declaration |
|
|
| Auto performance | `Low remained over its declared performance budget for 180 stable samples` | Complete pack falls back to Retail; select explicit Low only after reviewing the measured limits |
|
|
| Candidate build | `pipeline creation failed for 'directional-shadow-world-cutout'` | Driver/asset diagnosis; retail for this session |
|
|
| Runtime/device | `selected pack failed validation on the fresh device` | Retail on the fresh renderer for this session; no retry loop |
|
|
| Removal/update | `selected pack is no longer installed` | Retail, while retaining the notice |
|
|
|
|
Diagnostics and screenshot metadata record pack ID, pack version, preset ID,
|
|
compatibility result and fallback reason. Enhanced screenshots are not retail
|
|
parity evidence.
|
|
|
|
## Update and removal
|
|
|
|
Pack IDs remain stable across compatible updates; increment `PackVersion` and
|
|
manifest `version` together. A preset or setting ID that persists must keep its
|
|
meaning. User values are persisted as invariant strings under the selected
|
|
pack ID and setting ID, so declaration reordering cannot retarget a value. If
|
|
an update removes or changes a persisted setting incompatibly, selection fails
|
|
atomically to retail with the unknown/invalid override reason instead of
|
|
silently applying it elsewhere. If an update removes the selected preset, the client falls back to a
|
|
compatible declared preset only after explicit policy permits it; otherwise it
|
|
selects retail. Removing or unloading a pack first withdraws registrations,
|
|
then retires GPU-flight resources, then releases the collectible load context.
|
|
|
|
The built-in atmospheric pack's `sun-shadow-*` setting IDs predate the
|
|
selected-celestial source contract. They remain stable persisted identifiers;
|
|
their current labels and semantics apply to directional shadows from whichever
|
|
authored celestial source the renderer selects.
|
|
|
|
Reconnect, portal travel, resize and world-generation replacement do not
|
|
re-register managed packs. Renderer-owned resources are recreated or retired
|
|
within the same generation/fence rules; pack assets never own gameplay,
|
|
streaming, collision, or physics lifetime.
|
|
|
|
For v1, device recreation is not an in-place `VK_ERROR_DEVICE_LOST` recovery
|
|
path. The host tears down the complete old renderer, context, and device, then
|
|
constructs and probes a new context/device. The default retail renderer remains
|
|
authoritative while the selected pack is validated as a fresh candidate; a
|
|
failed candidate stays on retail without an automatic retry loop.
|