Checkpoint 5: complete asset freshness, schema migrations and editor diagnostics
This commit is contained in:
@@ -228,3 +228,36 @@ the Assets panel, scrolling keyboard focus into view, delivery of explicit gamep
|
||||
schema migrations, GPU pass labels, and wiring optional ImGui diagnostics. These
|
||||
remain under implementation and verification; the research map now links current
|
||||
implementation evidence instead of claiming the engine has not been started.
|
||||
|
||||
## Checkpoint 5 — close the final authoring and diagnostics gaps
|
||||
|
||||
- Asset freshness compares source, bundle payload, external buffer/image, recipe,
|
||||
importer and profile contents without publishing a generation. GUI and MCP expose
|
||||
the same state/reasons; selecting a stale imported row prepares Reimport. Cook and
|
||||
export reject stale referenced sources while keeping the previous successful result.
|
||||
- Gameplay schemas carry validated declarative migration steps. Inspector and MCP
|
||||
apply `component.migrate` as an explicit revision-checked Undo transaction. Opening
|
||||
old data remains possible without rules. Tests cover local components, instance-local
|
||||
additions, opening inherited sources, missing/manual rules and overflow rollback.
|
||||
The Manual explains the sparse-override limitation when field units change.
|
||||
- Keyboard focus scrolls long and nested Inspector/Assets lists into view at 1×/2×,
|
||||
preserves unfinished text and keeps invalid numeric edits visible. Template preview
|
||||
and conflicts are also invalidated when schema metadata changes without a scene edit.
|
||||
- Vulkan passes emit optional debug-utils labels. An optional `FASET_DEBUG_IMGUI=ON`
|
||||
Editor module shows real renderer diagnostics via F12; the Player remains independent.
|
||||
GPU tests cover textured/clipped ImGui geometry and event ownership for gestures
|
||||
crossing the panel in either direction. Offscreen clipboard operations are local
|
||||
to that renderer and never touch the desktop clipboard.
|
||||
- The Windows launcher fixture compares canonical filesystem identities, including
|
||||
hosted-runner short TEMP aliases, and now distinguishes selection/path failures.
|
||||
|
||||
Integrated Linux with optional diagnostics enabled: **34 passed, 1 skipped, 0 failed**
|
||||
of 35 tests. The skip remains native Wayland programmatic restore; XWayland passed.
|
||||
ASan/UBSan passed **18/18**, including process cleanup, metadata publication and
|
||||
migration transactions. Strict MkDocs and local Markdown file-link checks passed.
|
||||
|
||||
Windows run `35299805623` at `e0b9651` passed all **34** tests in its CPU/GPU/UI suite,
|
||||
including the launcher fix, and proceeded to real native Release exports. That run
|
||||
predates checkpoint 5's new authoring/diagnostic changes, whose Windows checks remain
|
||||
separate. The next full Windows build enables the optional diagnostic module too.
|
||||
No MVP tag is claimed at this checkpoint.
|
||||
|
||||
@@ -26,6 +26,18 @@ With MCP, call `faset_import`, then query `faset_job` using the returned job ID.
|
||||
`faset_job_cancel` requests cancellation. Cancelling an import does not Undo an
|
||||
authoring edit. See [MCP and CLI](mcp.md) for transport setup and errors.
|
||||
|
||||
The Assets panel marks an imported asset **Stale** when its source, external glTF
|
||||
buffer/image, Blender bundle, saved import settings, importer, or target profile
|
||||
differs from the active generation. Select the imported row, then **Import / Reimport**;
|
||||
the Console reports the changed input. **Refresh** checks immediately, and the panel
|
||||
also refreshes periodically. `faset_assets` exposes the same `freshness.state` and
|
||||
structured `freshness.reasons` to MCP clients. Checks compare contents, including
|
||||
files whose size and timestamp stayed unchanged. The last good cooked asset remains
|
||||
visible until reimport succeeds; checking freshness never publishes a generation.
|
||||
Cook and export refuse referenced stale or unavailable sources and explain which
|
||||
input needs reimport. A standalone exported game uses only its packaged cooked
|
||||
generation and never needs the original source files.
|
||||
|
||||
## Import an image
|
||||
|
||||
PNG and JPEG become image assets. Drag an imported image into a scene to create a
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Developer diagnostics
|
||||
|
||||
The optional Dear ImGui overlay shows renderer counters inside the Editor. The Editor's normal interface remains the retained Faset UI. Enable the diagnostic build explicitly:
|
||||
|
||||
```sh
|
||||
cmake --preset linux-debug -DFASET_DEBUG_IMGUI=ON
|
||||
cmake --build --preset linux-debug --parallel 4
|
||||
build/linux-debug/faset_editor --project examples/projects/collect-3d --gui
|
||||
```
|
||||
|
||||
On Windows, use `windows-debug` for both presets and `build/windows-debug/faset_editor.exe`. Press **F12** to show or hide the panel. Drag its title bar to move it; **Freeze counters** holds a completed-frame sample for inspection. Closing the panel does not stop rendering. Pointer gestures inside the overlay are kept out of the authoring UI.
|
||||
|
||||
The panel reports the previous completed frame: renderer wall time, GPU timestamp time where available, synchronous readback time, draw calls, packed vertices, culled meshes, textures, explicit Vulkan allocation sizes, actual validation availability/errors, and GPU pass-label count. Renderer wall time includes waiting for GPU work; it is not thread CPU usage. Memory excludes driver-internal allocations. The overlay itself adds drawing work, so hide it for a baseline performance measurement.
|
||||
|
||||
The Vulkan backend emits `VK_EXT_debug_utils` labels for `ShadowMap`, `ForwardAndUI`, `Readback`, and, when presenting, `Presentation`. A graphics capture tool that supports this extension can identify those command-buffer regions. Labels remain available without the Khronos validation layer when the extension is exposed; unsupported systems continue rendering and report labels unavailable. A submitted-label count confirms calls were emitted, not that an external capture tool was tested.
|
||||
|
||||
This module is disabled by default and is linked only to the graphical Editor and its dedicated test when enabled. Player and exported games do not link ImGui. No overlay control changes authoring documents, gameplay state or export settings.
|
||||
|
||||
Run `ctest --test-dir build/linux-debug -R '^editor_debug_overlay$' --output-on-failure` in an enabled build to check actual ImGui geometry/font rendering, F12 toggling, pointer isolation and restoration of the underlying frame. The regular renderer pixel test also verifies GPU labels and clipped UI triangles.
|
||||
@@ -103,9 +103,17 @@ check **Jobs** and **Console**. A successful build and schema export refresh the
|
||||
Inspector. A failed build retains the previous metadata and reports the failure.
|
||||
|
||||
A missing schema or unsupported component version appears as read-only raw fields
|
||||
with **Copy raw fields**. The Editor preserves that data. Restore the matching module
|
||||
or provide a migration and rebuild before expecting normal field editing or Play.
|
||||
See [Build, Play, and export](export.md) for the C++ iteration loop.
|
||||
with **Copy raw fields**. Restore a missing module to make its schema available.
|
||||
For an older component, declare [data migration rules](../scripting/api.md#editor-data-migrations),
|
||||
choose **Build C++**, then **Migrate to v…** in the Inspector. This is one undoable
|
||||
authoring edit; save explicitly afterward. Inherited components show **Open source
|
||||
to migrate** instead. Top-level local additions migrate in their owning instance.
|
||||
Missing rules or conversion errors preserve the data and appear in Console.
|
||||
|
||||
Opening or recovering a scene never migrates it automatically. Future versions
|
||||
stay opaque and cannot be downgraded. Review instance overrides separately when
|
||||
changing the source field's units or meaning. See [Build, Play, and export](export.md)
|
||||
for the C++ iteration loop.
|
||||
|
||||
## Project settings
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## Linux prerequisites
|
||||
|
||||
The selected toolchain is C++20, CMake 3.25 or later, Ninja, and Clang.
|
||||
The selected toolchain is C++20, CMake 3.25 or later, Ninja, Clang, and Python 3.12+.
|
||||
Graphical builds need Vulkan 1.3 headers/loader and a compatible driver.
|
||||
SDL3, FreeType and HarfBuzz are built from pinned source archives.
|
||||
|
||||
@@ -64,8 +64,10 @@ disconnecting. Prefetching source archives alone is not a complete offline SDK.
|
||||
## Windows prerequisites
|
||||
|
||||
Use an x64 Visual Studio Developer shell with the Windows SDK, MSVC runtime libraries,
|
||||
LLVM `clang-cl`, Ninja, CMake, and the Vulkan SDK available. Then use the
|
||||
`windows-debug` or `windows-release` presets.
|
||||
LLVM `clang-cl`, Ninja, CMake 3.25+, Python 3.12+, and the Vulkan SDK available.
|
||||
The commands below use the Python `py` launcher; substitute `python` if your
|
||||
installation exposes that command instead. Use the `windows-debug` or
|
||||
`windows-release` presets.
|
||||
|
||||
Enable **Win32 long paths** on the Windows development machine before starting the
|
||||
build shell. Faset's executable manifest declares long-path support, and its direct
|
||||
|
||||
@@ -76,6 +76,82 @@ automatic migrations or authoring-style custom-field constraint validation.
|
||||
|
||||
`snapshot()` returns a value snapshot for rendering; `snapshotJson()` provides its JSON representation. `diagnostics()` returns a read-only vector of runtime messages. These are native C++ APIs for the Player and tests, **not MCP endpoints**.
|
||||
|
||||
## Editor data migrations
|
||||
|
||||
Gameplay schema versions describe saved component data. When a field changes units
|
||||
or meaning, increase the type's `version` and include declarative `migrations` in
|
||||
that type returned by `gameplay::schema()`. For example, this type declaration
|
||||
converts version 1 speed values from centimetres per second to metres per second:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "game.mover",
|
||||
"version": 2,
|
||||
"fields": {
|
||||
"speed": {"type": "number", "default": 2.5, "min": 0, "max": 10},
|
||||
"enabled": {"type": "boolean", "default": true}
|
||||
},
|
||||
"migrations": [
|
||||
{
|
||||
"from_version": 1,
|
||||
"fields": {
|
||||
"speed": {"scale": 0.01},
|
||||
"enabled": {"default": true}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Build C++ to export and validate the declaration. The Editor reads these rules
|
||||
from the same schema manifest as field metadata; it does not load the gameplay
|
||||
library or execute a migration callback. Invalid metadata or migration rules fail
|
||||
the build before replacing the last published binary/schema generation.
|
||||
|
||||
Each step upgrades `from_version` to the next integer version. A component at
|
||||
version 1 needs both steps 1 and 2 to reach version 3. Empty `fields` explicitly
|
||||
allows a version step with no value conversion. Supported field operations are:
|
||||
|
||||
- `default`: insert a value only when the field is absent.
|
||||
- `scale`: multiply an existing numeric field by a finite number.
|
||||
- `require_manual`: when `true`, stop if the field is present, so incompatible data
|
||||
requires an explicit manual conversion.
|
||||
|
||||
Rules preserve component/entity IDs and fields they do not mention. The final
|
||||
values must satisfy the current field schema. Unsupported operations, repeated
|
||||
steps, invalid version ranges, invalid rules and non-finite scale values are
|
||||
rejected when the schema is loaded. Arithmetic overflow during conversion also
|
||||
fails without applying the transaction.
|
||||
|
||||
Opening or recovering a scene preserves older component versions as opaque data;
|
||||
it never migrates them automatically. Missing rules therefore do not prevent
|
||||
opening the scene. Choose **Migrate to v…** in the Inspector after rebuilding the
|
||||
schema, or use the same editor's `faset_scene_edit` operation with the current
|
||||
document revision:
|
||||
|
||||
```json
|
||||
{
|
||||
"document": "document-id",
|
||||
"revision": 3,
|
||||
"operations": [
|
||||
{"op": "component.migrate", "entity": "entity-id", "component": "component-id"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The whole batch is one Undo step and is written to the recovery journal. Save
|
||||
explicitly to update the scene file. Missing steps, a manual-conversion requirement
|
||||
or a validation error leave the document and revision unchanged. Future versions
|
||||
cannot be downgraded. The same operation accepts an `instance` ID when `entity`
|
||||
and `component` identify a top-level instance-local addition using its original
|
||||
stored IDs, rather than resolved preview IDs.
|
||||
|
||||
Inherited components belong to their source document: open that source to migrate
|
||||
them. Sparse field overrides in other instances are not automatically converted;
|
||||
review and explicitly update overrides when changing a field's units or meaning.
|
||||
The Player performs no migration and still requires the scene version to match its
|
||||
linked gameplay schema before Play or exported-game validation.
|
||||
|
||||
## Inspect a running Player locally
|
||||
|
||||
The Player has local development controls in addition to gameplay input: **P** toggles
|
||||
|
||||
@@ -44,7 +44,7 @@ Read the callback from top to bottom:
|
||||
|
||||
The `[](...) { ... }` expression is a C++ lambda: a function stored in `Behavior::update`. Empty brackets mean it captures no local variables. `registerBehavior` takes ownership of the callback object. Register before calling `load`; registration while entities exist or a callback is running is rejected.
|
||||
|
||||
The `schema()` function describes editable configuration. It does not create a runtime object. `tutorial.move_x` is the stable `TypeId`; `speed` is a stable `FieldId` within that type. Keep these IDs when changing a display label. Changing a field's meaning or units needs an explicit data migration, not just a new label.
|
||||
The `schema()` function describes editable configuration. It does not create a runtime object. `tutorial.move_x` is the stable `TypeId`; `speed` is a stable `FieldId` within that type. Keep these IDs when changing a display label. Changing a field's meaning or units needs an [explicit data migration](api.md#editor-data-migrations), not just a new label.
|
||||
|
||||
## Attach the behavior
|
||||
|
||||
|
||||
Reference in New Issue
Block a user