From 934579def5bd1c4f4b0f2ef7a9d81e21de796495 Mon Sep 17 00:00:00 2001 From: skal Date: Tue, 10 Feb 2026 18:09:41 +0100 Subject: docs: Fix EFFECT keyword syntax and add automation-friendly workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix EFFECT keyword format across all documentation and scripts - priority modifier (+/=/–) is required but was missing from examples. **Documentation fixes:** - doc/HOWTO.md: Added missing + to EFFECT example - doc/RECIPE.md: Added priority modifiers to examples - tools/shadertoy/README.md: Fixed test path, clarified workflow - tools/shadertoy/convert_shadertoy.py: Updated output instructions **New automation guide:** - doc/EFFECT_WORKFLOW.md: Complete step-by-step checklist for AI agents - Exact file paths and line numbers - Common issues and fixes - Asset ID naming conventions - CMakeLists.txt dual-section requirement - Test list instructions (post_process_effects vs scene_effects) **Integration:** - CLAUDE.md: Added EFFECT_WORKFLOW.md to Tier 2 (always loaded) - doc/AI_RULES.md: Added "Adding Visual Effects" quick reference - README.md: Added EFFECT_WORKFLOW.md to documentation list **CMakeLists.txt:** - Disabled incomplete cube_sphere_effect.cc (ShaderToy conversion WIP) **Timeline:** - Commented out incomplete CubeSphereEffect - Removed obsolete constructor argument Fixes #issue-with-effect-syntax Co-Authored-By: Claude Sonnet 4.5 --- CLAUDE.md | 1 + CMakeLists.txt | 2 + README.md | 1 + doc/AI_RULES.md | 19 +++ doc/CONTRIBUTING.md | 15 ++- doc/EFFECT_WORKFLOW.md | 228 +++++++++++++++++++++++++++++++++++ doc/HOWTO.md | 2 +- doc/RECIPE.md | 4 +- tools/shadertoy/README.md | 22 +++- tools/shadertoy/convert_shadertoy.py | 16 ++- workspaces/main/timeline.seq | 3 +- 11 files changed, 291 insertions(+), 22 deletions(-) create mode 100644 doc/EFFECT_WORKFLOW.md diff --git a/CLAUDE.md b/CLAUDE.md index a52dfce..714339b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -11,6 +11,7 @@ @doc/HOWTO.md @doc/CONTRIBUTING.md @doc/AI_RULES.md +@doc/EFFECT_WORKFLOW.md # ============================================ # TIER 3: DESIGN DOCS (Load On-Demand) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97b371a..753a9b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,6 +149,7 @@ if (DEMO_HEADLESS) src/gpu/effects/particle_spray_effect.cc src/gpu/effects/gaussian_blur_effect.cc src/gpu/effects/solarize_effect.cc +# Disabled: src/gpu/effects/cube_sphere_effect.cc (incomplete conversion) src/gpu/effects/chroma_aberration_effect.cc src/gpu/effects/vignette_effect.cc src/gpu/effects/cnn_effect.cc @@ -179,6 +180,7 @@ else() src/gpu/effects/particle_spray_effect.cc src/gpu/effects/gaussian_blur_effect.cc src/gpu/effects/solarize_effect.cc +# Disabled: src/gpu/effects/cube_sphere_effect.cc (incomplete conversion) src/gpu/effects/chroma_aberration_effect.cc src/gpu/effects/vignette_effect.cc src/gpu/effects/cnn_effect.cc diff --git a/README.md b/README.md index f7d78de..ac723db 100644 --- a/README.md +++ b/README.md @@ -16,5 +16,6 @@ cmake --build build -j4 - **TODO.md** - Active tasks and priorities - **doc/HOWTO.md** - Common operations (building, testing, assets) - **doc/CONTRIBUTING.md** - Development guidelines and protocols +- **doc/EFFECT_WORKFLOW.md** - Step-by-step guide for adding visual effects See `doc/` for detailed technical documentation. diff --git a/doc/AI_RULES.md b/doc/AI_RULES.md index d18a0cc..1a4ee78 100644 --- a/doc/AI_RULES.md +++ b/doc/AI_RULES.md @@ -5,3 +5,22 @@ - Prefer small, reviewable commits - All `cmake --build` commands must use the `-j4` option for parallel building. - 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 + +**IMPORTANT:** When adding new visual effects, follow the complete workflow in `doc/EFFECT_WORKFLOW.md`. + +**Required steps (must complete ALL):** +1. Create effect files (.h, .cc, .wgsl) +2. Add shader to `workspaces/main/assets.txt` +3. Add `.cc` to CMakeLists.txt GPU_SOURCES (BOTH sections: headless and normal) +4. Include header in `src/gpu/demo_effects.h` +5. Add to timeline with `EFFECT +` (priority modifier is REQUIRED) +6. Add to test list in `src/tests/gpu/test_demo_effects.cc` +7. Build and verify: `cmake --build build -j4 && cd build && ./test_demo_effects` + +**Common mistakes to avoid:** +- Missing priority modifier in timeline (`EFFECT` must be `EFFECT +`, `EFFECT =`, or `EFFECT -`) +- Adding `.cc` to only one CMakeLists.txt section (need BOTH headless and normal) +- Wrong asset ID (check assets.txt entry name → `ASSET_SHADER_`) +- Forgetting to add to test file diff --git a/doc/CONTRIBUTING.md b/doc/CONTRIBUTING.md index 9cd785b..98df873 100644 --- a/doc/CONTRIBUTING.md +++ b/doc/CONTRIBUTING.md @@ -65,12 +65,15 @@ See `doc/CODING_STYLE.md` for detailed examples. ## Development Protocols ### Adding Visual Effect -1. Implement `Effect` subclass in `src/gpu/demo_effects.cc` -2. Add to workspace `timeline.seq` (e.g., `workspaces/main/timeline.seq`) -3. **Update `test_demo_effects.cc`**: - - Add to test list - - Increment `EXPECTED_*_COUNT` -4. Verify: +1. Create effect class files (use `tools/shadertoy/convert_shadertoy.py` or templates) +2. Add shader to `workspaces/main/assets.txt` +3. Add effect `.cc` file to `CMakeLists.txt` GPU_SOURCES (both sections) +4. Include header in `src/gpu/demo_effects.h` +5. Add to workspace `timeline.seq` (e.g., `workspaces/main/timeline.seq`) +6. **Update `src/tests/gpu/test_demo_effects.cc`**: + - Add to `post_process_effects` list (lines 80-93) or `scene_effects` list (lines 125-137) + - Example: `{"MyEffect", std::make_shared(fixture.ctx())},` +7. Verify: ```bash cmake -S . -B build -DDEMO_BUILD_TESTS=ON cmake --build build -j4 --target test_demo_effects diff --git a/doc/EFFECT_WORKFLOW.md b/doc/EFFECT_WORKFLOW.md new file mode 100644 index 0000000..45c47b7 --- /dev/null +++ b/doc/EFFECT_WORKFLOW.md @@ -0,0 +1,228 @@ +# Effect Creation Workflow + +**Target Audience:** AI coding agents and developers + +Automated checklist for adding new visual effects to the demo. + +--- + +## Quick Reference + +**For ShaderToy conversions:** Use `tools/shadertoy/convert_shadertoy.py` then follow steps 3-8 below. + +**For custom effects:** Follow all steps 1-8. + +--- + +## Step-by-Step Workflow + +### 1. Create Effect Files + +**Location:** +- Header: `src/gpu/effects/_effect.h` +- Implementation: `src/gpu/effects/_effect.cc` +- Shader: `workspaces/main/shaders/.wgsl` + +**Naming Convention:** +- Class name: `Effect` (e.g., `TunnelEffect`, `PlasmaEffect`) +- Files: `_effect.*` (snake_case) + +**Base Class:** +- Post-process effects: inherit from `PostProcessEffect` +- Scene effects: inherit from `Effect` + +**Template:** See `tools/shadertoy/template.*` or use `convert_shadertoy.py` + +### 2. Add Shader to Assets + +**File:** `workspaces/main/assets.txt` + +**Format:** +``` +SHADER_, NONE, shaders/.wgsl, "Effect description" +``` + +**Example:** +``` +SHADER_TUNNEL, NONE, shaders/tunnel.wgsl, "Tunnel effect shader" +``` + +**Asset ID:** Will be `AssetId::ASSET_SHADER_` in C++ + +### 3. Add to CMakeLists.txt + +**File:** `CMakeLists.txt` + +**Action:** Add `src/gpu/effects/_effect.cc` to **BOTH** GPU_SOURCES sections: +- Headless mode section (around line 141-167) +- Normal mode section (around line 171-197) + +**Location:** After similar effects (post-process with post-process, scene with scene) + +**Example:** +```cmake +# In headless section (line ~152): + src/gpu/effects/solarize_effect.cc + src/gpu/effects/tunnel_effect.cc # <-- Add here + src/gpu/effects/chroma_aberration_effect.cc + +# In normal section (line ~183): + src/gpu/effects/solarize_effect.cc + src/gpu/effects/tunnel_effect.cc # <-- Add here + src/gpu/effects/chroma_aberration_effect.cc +``` + +### 4. Include in demo_effects.h + +**File:** `src/gpu/demo_effects.h` + +**Action:** Add include directive: +```cpp +#include "gpu/effects/_effect.h" +``` + +**Location:** Alphabetically with other effect includes + +### 5. Add to Timeline + +**File:** `workspaces/main/timeline.seq` + +**Format:** +``` +SEQUENCE + EFFECT <+|=|-> Effect [params...] +``` + +**Priority Modifiers (REQUIRED):** +- `+` : Increment priority +- `=` : Same priority as previous effect +- `-` : Decrement priority (for backgrounds) + +**Example:** +``` +SEQUENCE 0.0 0 + EFFECT + TunnelEffect 0.0 10.0 +``` + +**Common Mistake:** Missing priority modifier (`+`, `=`, `-`) after EFFECT keyword + +### 6. Update Tests + +**File:** `src/tests/gpu/test_demo_effects.cc` + +**Action:** Add effect to appropriate list: + +**Post-Process Effects (lines 80-93):** +```cpp +{"TunnelEffect", std::make_shared(fixture.ctx())}, +``` + +**Scene Effects (lines 125-137):** +```cpp +{"TunnelEffect", std::make_shared(fixture.ctx())}, +``` + +**3D Effects:** If requires Renderer3D, add to `requires_3d` check (line 148-151) + +### 7. Build and Test + +```bash +# Full build +cmake --build build -j4 + +# Run effect tests +cmake -S . -B build -DDEMO_BUILD_TESTS=ON +cmake --build build -j4 --target test_demo_effects +cd build && ./test_demo_effects + +# Run all tests +cd build && ctest +``` + +### 8. Verify + +**Checklist:** +- [ ] Effect compiles without errors +- [ ] Effect appears in timeline +- [ ] test_demo_effects passes +- [ ] Effect renders correctly: `./build/demo64k` +- [ ] No shader compilation errors +- [ ] Follows naming conventions + +--- + +## Common Issues + +### Build Error: "no member named 'ASSET_..._SHADER'" + +**Cause:** Shader not in assets.txt or wrong asset ID name + +**Fix:** +1. Check `workspaces/main/assets.txt` has shader entry +2. Asset ID is `ASSET_` + uppercase entry name (e.g., `SHADER_TUNNEL` → `ASSET_SHADER_TUNNEL`) + +### Build Error: "undefined symbol for architecture" + +**Cause:** Effect not in CMakeLists.txt GPU_SOURCES + +**Fix:** Add `.cc` file to BOTH sections (headless and normal mode) + +### Timeline Parse Error: "Expected '+', '=', or '-'" + +**Cause:** Missing priority modifier after EFFECT keyword + +**Fix:** Use `EFFECT +`, `EFFECT =`, or `EFFECT -` (never just `EFFECT`) + +### Test Failure: Effect not in test list + +**Cause:** Effect not added to test_demo_effects.cc + +**Fix:** Add to `post_process_effects` or `scene_effects` list + +--- + +## Automation Script Example + +```bash +#!/bin/bash +# Example automation for AI agents + +EFFECT_NAME="$1" # CamelCase (e.g., "Tunnel") +SNAKE_NAME=$(echo "$EFFECT_NAME" | sed 's/\([A-Z]\)/_\L\1/g' | sed 's/^_//') +UPPER_NAME=$(echo "$SNAKE_NAME" | tr '[:lower:]' '[:upper:]') + +echo "Creating effect: $EFFECT_NAME" +echo " Snake case: $SNAKE_NAME" +echo " Upper case: $UPPER_NAME" + +# 1. Generate files (if using ShaderToy) +# ./tools/shadertoy/convert_shadertoy.py shader.txt "$EFFECT_NAME" + +# 2. Add to assets.txt +echo "SHADER_${UPPER_NAME}, NONE, shaders/${SNAKE_NAME}.wgsl, \"${EFFECT_NAME} effect\"" \ + >> workspaces/main/assets.txt + +# 3. Add to CMakeLists.txt (both sections) +# Use Edit tool to add to both GPU_SOURCES sections + +# 4. Add include to demo_effects.h +# Use Edit tool to add #include line + +# 5. Add to timeline.seq +# Use Edit tool to add EFFECT line with priority modifier + +# 6. Add to test file +# Use Edit tool to add to appropriate test list + +# 7. Build +cmake --build build -j4 +``` + +--- + +## See Also + +- `tools/shadertoy/README.md` - ShaderToy conversion guide +- `doc/SEQUENCE.md` - Timeline format documentation +- `doc/CONTRIBUTING.md` - General contribution guidelines +- `src/gpu/effects/` - Existing effect examples diff --git a/doc/HOWTO.md b/doc/HOWTO.md index 07d480b..a57a161 100644 --- a/doc/HOWTO.md +++ b/doc/HOWTO.md @@ -108,7 +108,7 @@ Generate shaders from checkpoint: Edit `workspaces/main/timeline.seq`: ```text SEQUENCE 0.0 0 - EFFECT HeptagonEffect 0.0 60.0 0 + EFFECT + HeptagonEffect 0.0 60.0 0 ``` Rebuild to apply. See `doc/SEQUENCE.md`. diff --git a/doc/RECIPE.md b/doc/RECIPE.md index 6404391..d563027 100644 --- a/doc/RECIPE.md +++ b/doc/RECIPE.md @@ -157,8 +157,8 @@ void MyEffect::render(WGPUTextureView prev, WGPUTextureView target, **.seq syntax:** ``` -EFFECT MyEffect 0.0 10.0 strength=0.5 speed=3.0 -EFFECT MyEffect 10.0 20.0 strength=2.0 # speed keeps previous value +EFFECT + MyEffect 0.0 10.0 strength=0.5 speed=3.0 +EFFECT = MyEffect 10.0 20.0 strength=2.0 # speed keeps previous value ``` **Example:** `src/gpu/effects/flash_effect.cc`, `src/gpu/effects/chroma_aberration_effect.cc` diff --git a/tools/shadertoy/README.md b/tools/shadertoy/README.md index e734684..d12865f 100644 --- a/tools/shadertoy/README.md +++ b/tools/shadertoy/README.md @@ -2,6 +2,8 @@ Quick guide to convert ShaderToy shaders to demo effects. +**For complete workflow:** See `doc/EFFECT_WORKFLOW.md` for full integration checklist. + ## Quick Start (Automated) ```bash @@ -95,16 +97,24 @@ In `src/gpu/demo_effects.h`: In `workspaces/main/timeline.seq`: ``` SEQUENCE 0.0 0 - EFFECT MyEffectEffect 0.0 10.0 0 + EFFECT + MyEffectEffect 0.0 10.0 +``` + +### 7. Update CMakeLists.txt + +Add effect source to `CMakeLists.txt` GPU_SOURCES (both headless and normal mode sections): +```cmake +src/gpu/effects/myeffect_effect.cc ``` -### 7. Update Tests +### 8. Update Tests -In `tests/test_demo_effects.cc`: -- Add `"MyEffectEffect"` to test list -- Increment `EXPECTED_*_COUNT` +In `src/tests/gpu/test_demo_effects.cc`: +- Add to `post_process_effects` list (lines 80-93) if it's a post-process effect +- OR add to `scene_effects` list (lines 125-137) if it's a scene effect +- Example: `{"MyEffectEffect", std::make_shared(fixture.ctx())},` -### 8. Build & Test +### 9. Build & Test ```bash cmake --build build -j4 diff --git a/tools/shadertoy/convert_shadertoy.py b/tools/shadertoy/convert_shadertoy.py index 4956cfd..29eca1d 100755 --- a/tools/shadertoy/convert_shadertoy.py +++ b/tools/shadertoy/convert_shadertoy.py @@ -383,7 +383,7 @@ def main(): print("✓ Files generated") print() - print("Next steps:") + print("Next steps (see doc/EFFECT_WORKFLOW.md for details):") print() print("1. Add shader to workspaces/main/assets.txt:") print(f" shaders/{snake_name}.wgsl") @@ -392,13 +392,17 @@ def main(): print(f' #include "gpu/effects/{snake_name}_effect.h"') print() print("3. Add to timeline in workspaces/main/timeline.seq:") - print(f" EFFECT {effect_name}Effect 0.0 10.0 0") + print(f" EFFECT + {effect_name}Effect 0.0 10.0") print() - print("4. Update tests/test_demo_effects.cc:") - print(f' - Add "{effect_name}Effect" to test list') - print(" - Increment EXPECTED_*_COUNT") + print("4. Add to CMakeLists.txt GPU_SOURCES (both headless and normal mode):") + print(f" src/gpu/effects/{snake_name}_effect.cc") print() - print("5. Build and test:") + print("5. Update src/tests/gpu/test_demo_effects.cc:") + print(f' - Add "{{{effect_name}Effect", std::make_shared<{effect_name}Effect>(fixture.ctx())}}" to appropriate list') + print(" - Use post_process_effects (lines 80-93) for post-process effects") + print(" - Use scene_effects (lines 125-137) for scene effects") + print() + print("6. Build and test:") print(" cmake --build build -j4") print(" ./build/demo64k") print() diff --git a/workspaces/main/timeline.seq b/workspaces/main/timeline.seq index 8f7eea6..5e9a84f 100644 --- a/workspaces/main/timeline.seq +++ b/workspaces/main/timeline.seq @@ -36,7 +36,8 @@ SEQUENCE 8.50 2 "Hybrid3D" SEQUENCE 10.50 0 "CNN effect" EFFECT + HeptagonEffect 0.0 12.00 # EFFECT + RotatingCubeEffect 0.00 12.0 - EFFECT + Hybrid3DEffect 0.00 12.00 +# EFFECT + Hybrid3DEffect 0.00 12.00 +# EFFECT + CubeSphereEffect 0.0 10.0 EFFECT + CNNEffect 1.0 12.0 layers=3 blend=1.5 SEQUENCE 22.0 0 "buggy" -- cgit v1.2.3