summaryrefslogtreecommitdiff
path: root/doc/WORKSPACE_SYSTEM.md
blob: e8e2615c791d785d34cffc4ac792b25fea1ec9fe (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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
# Workspace System (Task #77) [COMPLETED]

## Status

**Implemented:** Feb 9, 2026

Workspace system is now active. Use `cmake -B build -DDEMO_WORKSPACE=<name>` to select workspace.

## Overview

Self-contained demo workspaces for parallel development and clean content separation.

**Motivation:** Current structure scatters demo content across multiple locations:
- `assets/demo.seq` - Timeline
- `assets/music.track` - Audio
- `assets/final/demo_assets.txt` - Asset list
- `assets/final/music/*.spec` - Audio samples
- `assets/shaders/*.wgsl` - Shaders (some demo-specific, some shared)

This makes it hard to:
- Work on multiple demos simultaneously
- Understand what files belong to which demo
- Share common resources cleanly
- Onboard new developers

## Problem Statement

**Current structure (flat):**
```
/assets/
  demo.seq                    # Main demo timeline
  music.track                 # Main demo music
  test_demo.seq              # Test demo timeline
  test_demo.track            # Test demo music
  /final/
    demo_assets.txt          # Main demo assets
    /music/*.spec            # Audio samples (mixed usage)
  /shaders/
    *.wgsl                   # Mixed: common + demo-specific
```

**Issues:**
1. No clear ownership of files
2. Can't easily switch between demos
3. Assets intermingled (demo vs test)
4. Shaders hard to categorize (shared vs demo-specific)
5. Adding new demos requires scattered changes

## Proposed Structure

### Workspace Directory Layout

```
/workspaces/
  /main/                     # Main production demo
    workspace.cfg            # Workspace metadata
    timeline.seq             # Visual effects
    music.track              # Audio patterns
    assets.txt               # Asset list
    /assets/
      /music/*.spec          # Demo-specific audio
      /meshes/*.obj          # Demo-specific meshes
    /shaders/                # Demo-specific shaders
      custom_effect.wgsl

  /test/                     # Test/validation demo
    workspace.cfg
    timeline.seq
    music.track
    assets.txt
    /assets/
    /shaders/

  /experiments/              # Experimental demos
    /demo2024_revision/
      workspace.cfg
      ...

/assets/common/              # Shared resources
  /shaders/
    /math/                   # Shared math utilities
      common_utils.wgsl
      sdf.wgsl
    /common_uniforms/        # Shared uniforms
      common.wgsl
  /audio/
    standard_drums.spec      # Shared samples
```

### Workspace Configuration

**`workspace.cfg` format:**
```ini
[workspace]
name = "Main Demo"
description = "Production 64k demo"
version = "1.0"

[build]
# Output binary name
target = "demo64k"

# Include paths (relative to workspace root)
timeline = "timeline.seq"
music = "music.track"
assets = "assets.txt"

# Asset directories
asset_dirs = ["assets/", "../common/audio/"]

# Shader directories (order matters: workspace-specific first)
shader_dirs = ["shaders/", "../common/shaders/"]

[options]
# Default resolution
width = 1280
height = 720

# Duration (seconds, -1 = auto-detect)
duration = -1

# BPM for timeline
bpm = 120
```

## Architecture

### Build System Integration

**CMakeLists.txt changes:**
```cmake
# Select active workspace (default: main)
set(DEMO_WORKSPACE "main" CACHE STRING "Active workspace")

# Parse workspace config
set(WORKSPACE_DIR "${CMAKE_SOURCE_DIR}/workspaces/${DEMO_WORKSPACE}")
set(WORKSPACE_CFG "${WORKSPACE_DIR}/workspace.cfg")

# Read config and set variables
parse_workspace_config(${WORKSPACE_CFG}
  TIMELINE_PATH
  MUSIC_PATH
  ASSETS_PATH
  ASSET_DIRS
  SHADER_DIRS
  TARGET_NAME
)

# Generate assets from workspace
add_custom_command(
  OUTPUT ${GEN_ASSETS_H}
  COMMAND asset_packer ${WORKSPACE_DIR}/${ASSETS_PATH} ...
  DEPENDS ${WORKSPACE_DIR}/${ASSETS_PATH}
)

# Generate timeline from workspace
add_custom_command(
  OUTPUT ${GEN_TIMELINE_CC}
  COMMAND seq_compiler ${WORKSPACE_DIR}/${TIMELINE_PATH} ...
  DEPENDS ${WORKSPACE_DIR}/${TIMELINE_PATH}
)

# Add shader include paths from workspace
foreach(SHADER_DIR ${SHADER_DIRS})
  list(APPEND SHADER_INCLUDE_DIRS "${WORKSPACE_DIR}/${SHADER_DIR}")
endforeach()
```

**Building specific workspace:**
```bash
# Default (main workspace)
cmake -S . -B build
cmake --build build -j4

# Specific workspace
cmake -S . -B build_test -DDEMO_WORKSPACE=test
cmake --build build_test -j4

# Experimental workspace
cmake -S . -B build_exp -DDEMO_WORKSPACE=experiments/demo2024_revision
cmake --build build_exp -j4
```

### Asset Packer Changes

**Support workspace-relative paths:**
```cpp
// asset_packer.cc
void PackerContext::resolve_asset_path(const char* rel_path) {
  // Try workspace-local first
  std::string workspace_path = workspace_dir + "/" + rel_path;
  if (file_exists(workspace_path)) {
    return workspace_path;
  }

  // Try common assets
  std::string common_path = "assets/common/" + rel_path;
  if (file_exists(common_path)) {
    return common_path;
  }

  error("Asset not found: %s", rel_path);
}
```

### Shader Composer Changes

**Support multiple include paths:**
```cpp
// shader_composer.cc
class ShaderComposer {
  std::vector<std::string> include_paths_;

  void add_include_path(const char* path) {
    include_paths_.push_back(path);
  }

  std::string resolve_include(const char* filename) {
    for (const auto& base : include_paths_) {
      std::string full = base + "/" + filename;
      if (file_exists(full)) {
        return full;
      }
    }
    error("Shader include not found: %s", filename);
  }
};
```

**Shader includes with search paths:**
```wgsl
// workspace-specific shader
#include "custom_uniforms.wgsl"      // From workspaces/main/shaders/
#include "math/common_utils.wgsl"    // From assets/common/shaders/
```

### CLI Tool

**`scripts/workspace.sh` - Workspace management:**
```bash
#!/bin/bash
# workspace.sh - Manage demo workspaces

case "$1" in
  list)
    # List all workspaces
    ls -1 workspaces/
    ;;

  create)
    # Create new workspace from template
    NAME=$2
    mkdir -p workspaces/$NAME/{assets,shaders}
    cp templates/workspace.cfg workspaces/$NAME/
    echo "Created workspace: $NAME"
    ;;

  build)
    # Build specific workspace
    NAME=$2
    cmake -S . -B build_$NAME -DDEMO_WORKSPACE=$NAME
    cmake --build build_$NAME -j4
    ;;

  info)
    # Show workspace details
    NAME=$2
    cat workspaces/$NAME/workspace.cfg
    ;;
esac
```

**Usage:**
```bash
./scripts/workspace.sh list
./scripts/workspace.sh create my_demo
./scripts/workspace.sh build main
./scripts/workspace.sh info test
```

## Implementation Plan

### Phase 1: Create Workspace Structure

**1.1 Create directory tree:**
```bash
mkdir -p workspaces/{main,test}/assets
mkdir -p workspaces/{main,test}/shaders
mkdir -p assets/common/{shaders,audio}
```

**1.2 Move existing files:**
```bash
# Main demo
mv assets/demo.seq workspaces/main/timeline.seq
mv assets/music.track workspaces/main/music.track
mv assets/final/demo_assets.txt workspaces/main/assets.txt
mv assets/final/music workspaces/main/assets/

# Test demo
mv assets/test_demo.seq workspaces/test/timeline.seq
mv assets/test_demo.track workspaces/test/music.track
cp assets/final/demo_assets.txt workspaces/test/assets.txt  # Or create minimal version

# Common shaders
mv assets/shaders/math assets/common/shaders/
mv assets/shaders/common_uniforms assets/common/shaders/
```

**1.3 Create workspace configs:**
```bash
# Generate workspace.cfg for main and test
# See format above
```

### Phase 2: Update Build System

**2.1 Add workspace parsing:**
- Create `cmake/ParseWorkspace.cmake`
- Parse INI-style config
- Set CMake variables

**2.2 Update CMakeLists.txt:**
- Add `DEMO_WORKSPACE` option
- Use workspace paths for assets/timeline/music
- Pass shader include paths to ShaderComposer

**2.3 Update compiler tools:**
- `asset_packer`: Accept workspace root dir
- `seq_compiler`: Accept workspace root dir
- `tracker_compiler`: Accept workspace root dir

### Phase 3: Update Code

**3.1 ShaderComposer:**
- Add multi-path include resolution
- Search workspace shaders first, then common

**3.2 Asset loading:**
- Update paths to match new structure
- Ensure backward compatibility during transition

**3.3 Generated code:**
- Verify generated assets.h/timeline.cc still work
- Update include paths if needed

### Phase 4: Documentation & Tools

**4.1 Update docs:**
- README.md: Explain workspace structure
- HOWTO.md: Document workspace build commands
- CONTRIBUTING.md: Workspace best practices

**4.2 Create helper scripts:**
- `scripts/workspace.sh`: Workspace management CLI
- `templates/workspace.cfg`: Template for new workspaces

**4.3 Update CI:**
- Build both main and test workspaces
- Validate workspace isolation

### Phase 5: Migration & Validation

**5.1 Test builds:**
```bash
# Build both workspaces
cmake -S . -B build_main -DDEMO_WORKSPACE=main
cmake --build build_main -j4

cmake -S . -B build_test -DDEMO_WORKSPACE=test
cmake --build build_test -j4

# Run tests
cd build_main && ctest
cd build_test && ctest
```

**5.2 Verify isolation:**
- Modify workspace-specific shader → only that workspace affected
- Modify common shader → both workspaces affected

**5.3 Update .gitignore:**
```
/build_*/
/workspaces/*/generated/
```

## Benefits

### 1. Clear Ownership
Each workspace is self-contained:
```bash
workspaces/main/
├── workspace.cfg     # Configuration
├── timeline.seq      # Timeline
├── music.track       # Music
├── assets.txt        # Assets
├── assets/           # Local assets
└── shaders/          # Local shaders
```

### 2. Parallel Development
Multiple developers can work on different demos without conflicts:
```bash
# Developer A: Main demo
cd workspaces/main
vim timeline.seq

# Developer B: Experimental demo
cd workspaces/experiments/christmas_demo
vim timeline.seq
```

### 3. Easy Switching
```bash
# Build main demo
cmake -B build -DDEMO_WORKSPACE=main
./build/demo64k

# Build test demo
cmake -B build -DDEMO_WORKSPACE=test
./build/test_demo
```

### 4. Clean Sharing
Common resources in one place:
```
assets/common/
├── shaders/
│   ├── math/          # Shared by all
│   └── common_uniforms/
└── audio/
    └── standard_drums.spec
```

### 5. Scalability
Easy to add new demos:
```bash
./scripts/workspace.sh create party2025
cd workspaces/party2025
# Start developing...
```

## Migration Path

### Backward Compatibility

During transition, support both structures:
```cmake
if(EXISTS "${CMAKE_SOURCE_DIR}/workspaces/${DEMO_WORKSPACE}")
  # New workspace structure
  set(USING_WORKSPACES TRUE)
else()
  # Legacy flat structure
  set(USING_WORKSPACES FALSE)
endif()
```

### Gradual Migration

1. **Phase 1:** Create workspace structure alongside existing
2. **Phase 2:** Update build system to support both
3. **Phase 3:** Move files to workspaces
4. **Phase 4:** Remove legacy paths
5. **Phase 5:** Update all documentation

**Timeline:** 1-2 weeks for full migration

## Trade-offs

### Pros
- Clear project organization
- Parallel demo development
- Clean resource sharing
- Better onboarding for new devs
- Scales to many demos

### Cons
- Initial migration effort
- Build system complexity increases
- More directories to navigate
- Learning curve for contributors

### Alternative Approaches

**1. Monorepo with subprojects:**
- Separate CMake projects per demo
- More isolated but harder to share code

**2. Configuration files only:**
- Keep flat structure, use config to select files
- Less clear, harder to understand ownership

**3. Git branches per demo:**
- Each demo is a branch
- Conflicts when merging shared code

**Chosen:** Workspace system (best balance)

## Implementation Effort

**Estimated time: 12-16 hours**

- Phase 1: Create structure (2-3 hours)
- Phase 2: Build system (4-5 hours)
- Phase 3: Code updates (3-4 hours)
- Phase 4: Documentation (2-3 hours)
- Phase 5: Validation (1-2 hours)

**Priority:** Medium (improves workflow, not blocking)

## Success Criteria

1. Both `main` and `test` workspaces build successfully
2. Switching workspaces requires only CMake flag change
3. Workspace-specific changes don't affect other workspaces
4. Common shader changes affect all workspaces
5. New workspace creation takes < 5 minutes
6. All tests pass for both workspaces
7. Documentation clear for new contributors

## Related Files

**New files:**
- `workspaces/main/workspace.cfg` - Main demo config
- `workspaces/test/workspace.cfg` - Test demo config
- `cmake/ParseWorkspace.cmake` - Config parser
- `scripts/workspace.sh` - Workspace CLI tool
- `templates/workspace.cfg` - New workspace template

**Modified files:**
- `CMakeLists.txt` - Workspace support
- `tools/asset_packer.cc` - Multi-path resolution
- `src/gpu/effects/shader_composer.cc` - Multi-path includes
- `README.md` - Workspace documentation
- `doc/HOWTO.md` - Build commands
- `doc/CONTRIBUTING.md` - Workspace guidelines

**Moved files:**
- `assets/demo.seq` → `workspaces/main/timeline.seq`
- `assets/music.track` → `workspaces/main/music.track`
- `assets/final/demo_assets.txt` → `workspaces/main/assets.txt`
- `assets/test_demo.*` → `workspaces/test/`
- `assets/shaders/math/` → `assets/common/shaders/math/`

## Notes

- This is a **structural refactor**, not a feature
- No runtime behavior changes
- Enables future scalability
- Makes project more professional
- Good foundation for demoscene releases (multiple demos per repo)