Files
Mainline/effects_plugins/noise.py
David Gwilliam 291e96d11e feat(effects): add plugin architecture for visual effects
- Extract effects as fully decoupled plugins in engine/effects/
- Add EffectConfig, EffectContext dataclasses and EffectPlugin protocol
- Add EffectRegistry for plugin discovery and management
- Add EffectChain for ordered pipeline execution
- Move built-in effects to effects_plugins/ directory
- Add interactive effects config picker during startup
- Add NTFY command handler for /effects commands
- Add tests for effects system (24 new tests)
- Update AGENTS.md with effects plugin documentation
- Add conventional commits section to AGENTS.md

chore: add coverage.xml to .gitignore
2026-03-15 17:16:49 -07:00

37 lines
1.1 KiB
Python

import random
from engine import config
from engine.effects.types import EffectConfig, EffectContext, EffectPlugin
from engine.terminal import C_DIM, G_DIM, G_LO, RST, W_GHOST
class NoiseEffect:
name = "noise"
config = EffectConfig(enabled=True, intensity=0.15)
def process(self, buf: list[str], ctx: EffectContext) -> list[str]:
if not ctx.ticker_height:
return buf
result = list(buf)
intensity = self.config.intensity
probability = intensity * 0.15
for r in range(len(result)):
cy = ctx.scroll_cam + r
if random.random() < probability:
result[r] = self._generate_noise(ctx.terminal_width, cy)
return result
def _generate_noise(self, w: int, cy: int) -> str:
d = random.choice([0.15, 0.25, 0.35, 0.12])
return "".join(
f"{random.choice([G_LO, G_DIM, C_DIM, W_GHOST])}"
f"{random.choice(config.GLITCH + config.KATA)}{RST}"
if random.random() < d
else " "
for _ in range(w)
)
def configure(self, cfg: EffectConfig) -> None:
self.config = cfg