summaryrefslogtreecommitdiff
path: root/doc/ASSET_SYSTEM.md
blob: 6104353af55413aa65066a57c1a689be3b70b4a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# 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.

## Asset Manifest Format

Files: `workspaces/main/assets.txt`, `workspaces/test/assets.txt`

Format (CSV):
```
ASSET_NAME, COMPRESSION, path/to/file.ext, "Description"
```

### Compression 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 |

## AssetType Enum

Each `AssetRecord` carries an `AssetType` field (replaces the former `is_procedural`/`is_gpu_procedural` bools):

```cpp
enum class AssetType : uint8_t { STATIC, PROC, PROC_GPU, MP3 };
```

Query at runtime:
```cpp
if (GetAssetType(AssetId::NEVER_MP3) == AssetType::MP3) { ... }
```

## Runtime API

```cpp
#include "util/asset_manager.h"

// Retrieve asset data
size_t size;
const uint8_t* data = GetAsset(AssetId::MY_ASSET, &size);
DropAsset(AssetId::MY_ASSET, data);  // Release procedural/cached data

// Query type
AssetType t = GetAssetType(AssetId::MY_ASSET);
```

## Build Pipeline

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

## 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`)

## Developer Workflow

**Add a static asset:**
```
MY_ASSET, NONE, path/to/file.ext, "Description"
```

**Add an MP3 sample:**
```
MY_SAMPLE, MP3, music/sample.mp3, "Description"
```

**Add a procedural texture:**
```
MY_TEX, PROC(gen_noise, 1234, 16), _, "Description"
```

Rebuild: `cmake --build build -j4` — CMake detects manifest changes automatically.