diff --git a/.opencode/skills/mainline-display/SKILL.md b/.opencode/skills/mainline-display/SKILL.md index 9a11c83..bd1dd2a 100644 --- a/.opencode/skills/mainline-display/SKILL.md +++ b/.opencode/skills/mainline-display/SKILL.md @@ -96,3 +96,68 @@ python mainline.py --display terminal # default python mainline.py --display websocket python mainline.py --display moderngl # GPU-accelerated (requires moderngl) ``` + +## Common Bugs and Patterns + +### BorderMode.OFF Enum Bug + +**Problem**: `BorderMode.OFF` has enum value `1` (not `0`), and Python enums are always truthy. + +**Incorrect Code**: +```python +if border: + buffer = render_border(buffer, width, height, fps, frame_time) +``` + +**Correct Code**: +```python +from engine.display import BorderMode +if border and border != BorderMode.OFF: + buffer = render_border(buffer, width, height, fps, frame_time) +``` + +**Why**: Checking `if border:` evaluates to `True` even when `border == BorderMode.OFF` because enum members are always truthy in Python. + +### Context Type Mismatch + +**Problem**: `PipelineContext` and `EffectContext` have different APIs for storing data. + +- `PipelineContext`: Uses `set()`/`get()` for services +- `EffectContext`: Uses `set_state()`/`get_state()` for state + +**Pattern for Passing Data**: +```python +# In pipeline setup (uses PipelineContext) +ctx.set("pipeline_order", pipeline.execution_order) + +# In EffectPluginStage (must copy to EffectContext) +effect_ctx.set_state("pipeline_order", ctx.get("pipeline_order")) +``` + +### Terminal Display ANSI Patterns + +**Screen Clearing**: +```python +output = "\033[H\033[J" + "".join(buffer) +``` + +**Cursor Positioning** (used by HUD effect): +- `\033[row;colH` - Move cursor to row, column +- Example: `\033[1;1H` - Move to row 1, column 1 + +**Key Insight**: Terminal display joins buffer lines WITHOUT newlines, relying on ANSI cursor positioning codes to move the cursor to the correct location for each line. + +### EffectPluginStage Context Copying + +**Problem**: When effects need access to pipeline services (like `pipeline_order`), they must be copied from `PipelineContext` to `EffectContext`. + +**Pattern**: +```python +# In EffectPluginStage.process() +# Copy pipeline_order from PipelineContext services to EffectContext state +pipeline_order = ctx.get("pipeline_order") +if pipeline_order: + effect_ctx.set_state("pipeline_order", pipeline_order) +``` + +This ensures effects can access `ctx.get_state("pipeline_order")` in their process method.