diff options
| author | skal <pascal.massimino@gmail.com> | 2026-03-08 09:33:17 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-03-08 09:33:17 +0100 |
| commit | a2f0f7c7a45ba8b30984fb135b8b54f11fb119f8 (patch) | |
| tree | 794527d25368227320e5f6aebe409178296db391 /doc | |
| parent | 9d114ae4fec465baed381de7782ef42ca77e734b (diff) | |
feat: Implement dual-mode asset loading and update documentation
This commit introduces a dual-mode asset loading system to enhance developer workflow and optimize release builds.
Key changes include:
- **Dual-Mode Asset Loading:** Assets are now loaded from disk during development (when is OFF) for faster iteration, particularly for heavy assets like and files. For release builds ( ON), all assets are embedded directly into the binary, ensuring a single, self-contained executable.
- **Explicit Asset Typing:** Replaced generic asset type with specific types (, , , , ) in and the enum in for clearer categorization and more robust processing.
- **Build System Integration:** Modified to pass a flag to in development builds.
- **Asset Packer Updates:** now generates file paths for disk-loaded assets and embeds data for others based on the build mode.
- **Asset Manager Enhancements:** includes new logic in for loading and caching disk-based assets and updates to for proper memory deallocation.
- **Documentation:** Updated to reflect the new asset nomenclature and dual-mode loading strategy.
- **Project Rules:** Added a concise rule to mandating top-level documentation updates for medium/large sub-system changes.
handoff(Gemini): Implemented dual-mode asset loading and updated documentation.
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/AI_RULES.md | 1 | ||||
| -rw-r--r-- | doc/ASSET_SYSTEM.md | 88 |
2 files changed, 59 insertions, 30 deletions
diff --git a/doc/AI_RULES.md b/doc/AI_RULES.md index 5500a9a..27d2d47 100644 --- a/doc/AI_RULES.md +++ b/doc/AI_RULES.md @@ -4,6 +4,7 @@ - All changes must keep tests passing - Prefer small, reviewable commits - All `cmake --build` commands must use the `-j4` option for parallel building. +- Medium/large sub-system changes require top-level doc update (summarize, streamline, archive). - after a task, a 'big' final commit should contain a short handoff tag like "handoff(Gemini):..." if you're gemini-cli, or "handoff(Claude): ..." if you're claude-code. ## Adding Visual Effects diff --git a/doc/ASSET_SYSTEM.md b/doc/ASSET_SYSTEM.md index 6104353..87d2a9a 100644 --- a/doc/ASSET_SYSTEM.md +++ b/doc/ASSET_SYSTEM.md @@ -1,6 +1,6 @@ # Compact Asset System for the 64k Demo -All assets are const byte arrays embedded in the binary. Runtime retrieval via `GetAsset(AssetId)` returns direct pointers with O(1) lookup. +This document outlines the architecture for managing assets, which are compiled into the binary for release builds but loaded from disk during development to speed up iteration. ## Asset Manifest Format @@ -8,24 +8,56 @@ Files: `workspaces/main/assets.txt`, `workspaces/test/assets.txt` Format (CSV): ``` -ASSET_NAME, COMPRESSION, path/to/file.ext, "Description" +ASSET_NAME, ASSET_TYPE, path/to/file.ext, "Description" ``` -### Compression Types +### Asset Types -| Type | Behavior | -|------|----------| -| `NONE` | Raw binary embed (shaders, meshes, `.spec` files) | -| `MP3` | MP3 audio; decoded to spectrogram at init | -| `PROC(func, ...)` | CPU procedural generation at init | -| `PROC_GPU(func, ...)` | GPU compute procedural generation at init | +The `ASSET_TYPE` field explicitly defines how the asset is processed and used at runtime. + +| Type | Description | +|------|-------------| +| `WGSL` | WGSL shader source code. | +| `SPEC` | Spectrogram data for audio synthesis. | +| `TEXTURE` | Image file (PNG, JPG, etc.), converted to a raw RGBA8 buffer with a width/height header. | +| `MESH` | 3D model file (.obj), converted to an interleaved vertex/index buffer. | +| `BINARY`| Generic raw binary data. | +| `MP3` | MP3 audio; decoded to a spectrogram at runtime. | +| `PROC(func, ...)` | CPU-based procedural generation at init time. | +| `PROC_GPU(func, ...)`| GPU-based compute shader for procedural generation at init time. | + +## Dual-Mode Loading Strategy + +The asset system operates in two modes, controlled by the `DEMO_STRIP_ALL` CMake flag: + +1. **Development Mode (`DEMO_STRIP_ALL=OFF`)**: + * Heavy assets (`SPEC`, `MP3`) are **loaded from disk** at runtime. + * The `asset_packer` generates a C-string containing the file path for these assets. + * The `AssetManager` reads the file on first access, caches it, and returns the content. + * This mode allows for rapid iteration on audio assets without requiring a full recompile. + +2. **Release Mode (`DEMO_STRIP_ALL=ON`)**: + * All assets are **embedded directly into the binary** as `const` byte arrays. + * This creates a single, self-contained executable suitable for distribution. + * The `asset_packer` generates C++ byte arrays from the asset files. + +This dual-mode system provides both developer convenience and release-ready packaging. ## AssetType Enum -Each `AssetRecord` carries an `AssetType` field (replaces the former `is_procedural`/`is_gpu_procedural` bools): +The C++ `AssetType` enum mirrors the types defined in the asset manifest: ```cpp -enum class AssetType : uint8_t { STATIC, PROC, PROC_GPU, MP3 }; +enum class AssetType : uint8_t { + WGSL, + SPEC, + TEXTURE, + MESH, + BINARY, + MP3, + PROC, + PROC_GPU, +}; ``` Query at runtime: @@ -41,7 +73,7 @@ if (GetAssetType(AssetId::NEVER_MP3) == AssetType::MP3) { ... } // Retrieve asset data size_t size; const uint8_t* data = GetAsset(AssetId::MY_ASSET, &size); -DropAsset(AssetId::MY_ASSET, data); // Release procedural/cached data +DropAsset(AssetId::MY_ASSET, data); // Release procedural or disk-loaded data // Query type AssetType t = GetAssetType(AssetId::MY_ASSET); @@ -51,33 +83,29 @@ AssetType t = GetAssetType(AssetId::MY_ASSET); Tool: `tools/asset_packer.cc` -1. Parse workspace `assets.txt` -2. Read/process files (images → RGBA8 header, meshes → vertex/index binary, others → raw) -3. Generate `src/generated/assets.h` (enum + declarations) -4. Generate `src/generated/assets_data.cc` (byte arrays + `AssetRecord` table) -5. Auto-triggered by CMake on manifest changes +1. Parse workspace `assets.txt`. +2. If in **Development Mode**, for `SPEC` and `MP3` assets, it generates a C-string with the file path. +3. If in **Release Mode**, it reads and processes all files into byte arrays (images → RGBA8, meshes → vertex/index, etc.). +4. Generate `src/generated/assets.h` (enum + declarations). +5. Generate `src/generated/assets_data.cc` (byte arrays/paths + `AssetRecord` table). +6. Auto-triggered by CMake on manifest changes. ## Technical Guarantees -- **Alignment**: All arrays declared `alignas(16)` for safe `reinterpret_cast` -- **String Safety**: Null-terminator appended (safe as C-string) -- **Size**: `size` reflects original file size (buffer is `size + 1`) +- **Alignment**: All embedded data arrays are declared `alignas(16)` for safe `reinterpret_cast`. +- **String Safety**: Embedded assets are null-terminated (safe as C-strings). In disk-load mode, the path itself is a null-terminated C-string. +- **Size**: For embedded assets, `size` reflects the original file size (the buffer is `size + 1`). For disk-loaded assets, it reflects the file path's string length. ## Developer Workflow -**Add a static asset:** -``` -MY_ASSET, NONE, path/to/file.ext, "Description" -``` - -**Add an MP3 sample:** +**Add a spectrogram:** ``` -MY_SAMPLE, MP3, music/sample.mp3, "Description" +MY_KICK, SPEC, music/my_kick.spec, "Description" ``` -**Add a procedural texture:** +**Add a shader:** ``` -MY_TEX, PROC(gen_noise, 1234, 16), _, "Description" +MY_SHADER, WGSL, shaders/my_shader.wgsl, "Description" ``` -Rebuild: `cmake --build build -j4` — CMake detects manifest changes automatically. +Rebuild: `cmake --build build -j4` — CMake detects manifest changes automatically. In development mode, changes to `.spec` or `.mp3` files do not require a rebuild. |
