Skip to content

Parameter Conventions

How source and effect params are organized, named, and displayed in the UI panel. Governs group naming, label text, positional order, vocabulary, and the decision between element-centric and property-centric grouping.

Scope: All sources and effects. Transform params (t_x, t_y, t_rz, t_scale, t_zoom) are auto-appended by the engine and always appear last — never define them manually.

UI behavior: ParamPanel.tsx renders groups as collapsible sections with colored left borders, in the order params appear in SOURCE_PARAMS / EFFECT_PARAMS (insertion order, not alphabetical). Changing group order means reordering params in ParamDefs.ts. Color sub-groups render collapsed by default — see §VI.

Key distinction — keys vs labels:

  • Keys (color_h, bg_opacity, rot_speed) are internal identifiers — appear in show files, modulation targets, shader uniforms, tests. They may use abbreviations. Key naming is out of scope for this standard — a future migration is tracked as a separate effort.
  • Labels (Hue, Background Opacity, Rotation Speed) are what the user sees. They must be fully spelled out and follow the vocabulary dictionary (§V).
  • Group names (Color 1, Background, Motion) are user-visible. Same rules as labels.

I. Canonical Group Order

Every group maps to exactly one of these 10 positional slots. Groups appear top-to-bottom in the param panel in this order. Skip positions that don’t apply to your source.

PosCategoryWhat it answersPreferred nameDomain-specific names OK
1FormWhat is it? Shape, structure, geometry, pattern.Shape, FormSpirals, Grid, Contour, Layer A, Fractal, Glyphs, Membrane, Beams
2SimulationHow does it behave? Physics, forces, emission.SimulationForces, Emitter, Seed, Trail, Injection, Zones, Flock
3MotionHow does it move over time? Speed, rotation rate, scroll.MotionAvoid Animation, Speed in new sources
4ViewWhere are you looking from? Zoom, pan, camera orbit.ViewAvoid Camera, Scene in new sources
5MaterialWhat’s the surface? PBR, fresnel, SSS.MaterialSurface
6LightingHow is it lit? Direction, intensity, scatter.Lighting
7ColorWhat color? HSB triplets, modes, palette binding.Color 1Background, Foreground, Sky, Dye, semantic element names
8DisplayPost-processing? Contrast, brightness, glow, vignette, invert.DisplayAvoid Render, Output in new sources
9QualityPerformance knob? Iterations, resolution, steps.Quality
10TransformPipeline UV remap. Auto-appended.TransformNever manual

Rationale: Follows the creative workflow — pick a shape, set its motion, frame it, surface it, light it, color it, polish it. Quality and Transform are adjust-rarely utility groups at the bottom.


II. Element-Centric vs Property-Centric

Not all sources are a single visual field. Some have distinct spatial elements (sun, grid, mountain). The grouping strategy depends on which type your source is.

The spatial distinctness test

If colors apply to visually distinct spatial regions → multi-element. Each element gets its own group containing both form and color params.

If colors blend across the whole frame → single-element. Use canonical property groups (Shape, Motion, Color).

Examples:

  • Multi-element: Synthwave (sun, grid, mountain, clouds occupy distinct screen regions), CubeGrid (cubes vs background), Seascape (water vs sky)
  • Single-element: Voronoi (two colors blend across all cells), Plasma (colors blend everywhere), Noise (two colors noise-blended)

Multi-element sources

Group by visual element. Each element group contains that element’s form + color params. The group appears at position 1 (Form) in the canonical order. Within the element group, form params come first, then color params (H → S → B).

Global params that affect the whole source (speed, zoom, quality, overall brightness) go in their own canonical groups at the standard positions.

Synthwave (multi-element):
├─ Sun (pos 1: form + color)
├─ Grid (pos 1: form + color)
├─ Mountain (pos 1: form + color)
├─ Clouds (pos 1: form + color)
├─ Sky (pos 7: background color only — no form, canonical Color slot)
├─ Horizon (pos 1: form + color)
├─ Motion (pos 3: global speed, loops)
└─ View (pos 4: global camera)

Single-element sources

Group by property type using canonical names.

Voronoi (single-element):
├─ Shape (pos 1: cellCount, borderWidth)
├─ Motion (pos 3: speed, jitter)
├─ View (pos 4: scale, rotation)
└─ Color 1 (pos 7: color_h/s/b, bg_b)

Hybrid sources

Some sources have one dominant visual element with distinct sub-features. Use your judgment — if a sub-feature has both form and color params, it’s an element. If it only has color, it goes in a Color group at position 7.

CubeGrid (hybrid):
├─ Grid (pos 1: gridSize, position — form only, no color)
├─ Cubes (pos 1: cubeSize, wireframe, color1/2 H/S/B — element with form + color)
├─ Motion (pos 3: rotX/Y/Z, shift, pulse)
├─ Lighting (pos 6: shadow, lightAngle, lightElev)
├─ Background (pos 7: bg H/S/B — color only, no form)
└─ View (pos 4: zoom)

Case-by-case judgment for naming

When the element’s role is visually distinct (Sun, Mountain, Cubes), use semantic group names. When the source is abstract and colors don’t map to named things (Voronoi two-tone, Plasma gradient), use generic Color 1 / Color 2 / Color 3.

Rule of thumb: if you could point at a spot on screen and say “that’s the sun” → semantic. If the color just “appears somewhere in the pattern” → generic.


III. Within-Group Ordering

Macro before micro. Structure before detail. Mode before continuous.

  1. Type/mode selectors first. geometry (dropdown) before detail (continuous). pattern_a before freq_a.
  2. Count/size before spacing/detail. gridSize before cubeSize. cellCount before borderWidth.
  3. Position before rotation. X/Y/Z position before tilt/rotation angles.
  4. Global speed at top of Motion. Overall speed first, then per-element speeds (scrollSpeed, morphSpeed).
  5. HSB: always H, S, B. Within a color sub-group, hue first, then saturation, then brightness, then opacity if present.
  6. Non-color params before HSB in Color groups. colorMode, colorShift, colorCycle before the HSB triplets they modify.
  7. Quality/performance at the bottom. iterations, stepsPerFrame, quality are adjust-rarely params.

IV. Label Rules

Labels are the user-facing name of a parameter. A single param has two display forms: bare (inside its group) and qualified (anywhere the group context is missing).

Bare label — inside a group

  • The label field in a ParamDef is the bare form. Used in ParamPanel, SourceDetailView, EffectDetailView — anywhere a param renders under its group header.
  • Bare labels never repeat the group name. Under the Color 1 group, the hue param is labeled Hue, not Color 1 Hue. Under Background, it’s Hue, not Background Hue. Under Motion, the global speed is Speed, not Motion Speed.
  • Full words only. Brightness, not Brt. Rotation, not Rot. Frequency, not Freq. See vocabulary dictionary in §V.
  • Title CaseColor Spread, not color spread or ColorSpread.

Qualified label — out-of-group contexts

Compose via getQualifiedLabel(param)${param.group} ${param.label}Color 1 Hue. Use wherever the group header isn’t visible next to the param:

  1. Button binding target picker (ActionButtonPanel)
  2. Modulation target picker (ModulationPopup)
  3. MIDI CC mapping UI
  4. Palette swatch → param binding
  5. Controller panel custom profile element bindings
  6. Current-binding display — anywhere a target is rendered as a string (“Bound to: Color 1 Hue”)
  7. Auto-generated docs (website/scripts/generate-reference.mjs)
  8. Search / filter results that list params outside their group
  9. Tutorial step text that references a specific param

Composition rules

  • Every group name must read naturally when prepended to any param it contains. Color 1 + HueColor 1 Hue ✓. Motion + SpeedMotion Speed ✓. Cubes + Color 1 HueCubes Color 1 Hue (when colors are nested inside an element group, the full qualified label is group element-label).
  • Never prefix the label with the group yourself — the getQualifiedLabel helper composes it. If you write label: 'Color 1 Hue' in a ParamDef under group Color 1, the qualified form becomes Color 1 Color 1 Hue — double-prefix bug.
  • Redundant qualified forms are tolerated. Form Radius, Motion Speed — users accept mild redundancy over ambiguity.

Exceptions

  • Transform params (t_x, t_y, t_rz, t_scale, t_zoom) keep their current descriptive labels (Position X, Position Y, Rotation, Scale, Zoom) because the Transform group is terse and universal.

Axis rotation labels

Use Rotate X, Rotate Y, and Rotate Z for user-facing labels when a param controls static orientation around a 3D axis. This applies to object, camera, viewport, and scene orientation controls.

  • Do not use Rotation X, Rotation Y, Rotation Z, X Rotation, Y Rotation, Z Rotation, Tilt X/Y/Z, Orbit X/Y/Z, Pitch, Yaw, Roll, Pan, or Cam in user-facing labels for axis rotation controls.
  • Internal keys can stay shader-domain-specific (camPitch, orbitY, tilt_x, etc.). Saved shows, modulation targets, button targets, and shader mappings rely on keys, not labels.
  • If the controlled subject matters, put it in the group name or description, not the bare label. Example: group Orb, labels Rotate X, Rotate Y, Rotate Z; qualified labels become Orb Rotate X, etc.
  • Single-axis 2D/full-frame angle controls remain Rotation.
  • Rotation rate controls remain Rotation Speed; avoid Rotate Speed, Auto Rotate, and Orbit Speed for new labels.
  • Non-orientation directional controls may use semantic labels such as Light Angle, Wind Angle, Scroll Angle, or Gradient Angle.
  • Any angle, phase, hue, or full-cycle wrapping control should use normalized storage, degree display where appropriate, unit: '°', and loopable: true unless the range is intentionally clamped.

V. Vocabulary Dictionary

Canonical word form for every recurring user-visible term. Applies to label and group fields. Keys are out of scope.

CanonicalAvoidNotes
Colors
BackgroundBG, Bg, Bg Color, Background ColorGroup name is Background — no Color suffix needed.
ForegroundFG, Fg
HueH, Hu
SaturationSat, Saturat
BrightnessBrt, Bright, ValuePrefer Brightness over Value (HSB convention).
OpacityOp, AlphaUse Alpha only when specifically the alpha channel of RGBA.
Motion
SpeedSpd
RotationRotWhen referring to rate. See Ambiguity Resolution for static.
Rotate X/Y/ZRotation X/Y/Z, X/Y/Z Rotation, Tilt X/Y/Z, Orbit X/Y/Z, Pitch/Yaw/Roll, Pan, CamUse for static 3D axis orientation labels.
AngleUse for static angular position.
ScrollScrl
Form
ScaleScl
SizeSz
RadiusR, Rad
ThicknessThick, Thk
WidthW
HeightHH conflicts with Hue — always spell out.
DepthD
CountNum, N, Qty
PositionPos
DistanceDist
OffsetOffs, ShiftShift OK when it means a periodic phase shift.
Signal
AmplitudeAmp
FrequencyFreq
PhasePh
WavelengthWavelen, Lambda
Rendering
IterationsIter, Its
ResolutionRes
QualityQ, Qual
ContrastContr
Other
MixBlend (when referring to param amount, not blend mode)
FeedbackFb
JitterJit

When a label would use a term not in this table, add it here. Deviations require a spec update.

Color group naming

  • Single-color sources: group name is Color 1 (future-proofs adding a second color).
  • Two-color sources: Color 1, Color 2. If colors have clear semantic roles (light vs dark, fill vs stroke, dye A vs dye B), prefer semantic names.
  • Multi-element sources: group names are the element’s role (Sun, Mountain, Cloud, Grid, Background). The color belongs to the element — no separate Color group inside the element.
  • Background-only color group: always Background.
  • Foreground-only color group: always Foreground.

VI. Color Rules

Cross-reference: Shader Techniques — Rule VI — two colors, palette-bound, noise-blended.

ParamDef invariants

  1. Every HSB triplet must have colorGroup and colorRole in its ParamDef. No exceptions.
  2. colorGroup values: color1, color2, color3, bg, fg, or a semantic slug matching the group name (sun, mountain, cloud). Used for palette binding lookup.
  3. colorRole values: h, s, or b — which HSB component this param drives. The palette overlay reads it to pull the matching channel (h/s/b) from the bound swatch. (The colorGroup slug — see rule 2 — selects which swatch; colorRole selects the component.)
  4. Labels inside a color group are bare: Hue, Saturation, Brightness, Opacity. Never repeat the group name.
  5. Color sub-ordering within the group: Hue → Saturation → Brightness → Opacity.
  6. Non-color modifier params precede HSB triplets: colorMode, colorShift, colorCycle appear first.
  7. Background opacity required: If a source has a background color group, include an Opacity param so the source can layer under other chain nodes. (Per CLAUDE.md — bg_opacity key, label Opacity, extendable: false.)

Rendering — collapsible color groups

Color groups (any group whose params include an HSB triplet) render collapsed by default in ParamPanel and SourceDetailView. The collapsed row shows:

▶ Color 1 ⬤
▶ Background ⬤

Group name + color swatch preview (composited from current H/S/B) + expand chevron. Click expands to reveal HSB sliders.

This applies equally to single-color and multi-element sources. For multi-element sources where an element group contains form + color params mixed, the HSB triplet forms a collapsible sub-section within the element group — the form params remain always-visible.

Rendering implementation is Phase B work; no ParamDef schema change required. The renderer detects HSB triplets by colorGroup presence.


VII. Domain-Specific Group Names

Descriptive group names are encouraged when they help the user understand what params control. The standard governs position, not naming.

Rules

  1. Every group maps to one canonical position. Spirals is Form (pos 1). Injection is Simulation (pos 2). Dye is Color (pos 7).
  2. Use canonical names for generic groups. If your source has basic shape params, call it Shape — not Parameters or a source-specific name.
  3. Use domain names for specialized subsystems. Moire’s Layer A / Layer B / Layer C are all Form (pos 1) but the names tell the user what they control.
  4. Multiple groups at the same position is fine. They appear in logical sub-order: general before specific, primary before secondary.
  5. Group names follow the vocabulary dictionary. Background, not BG or Bg Color. Foreground, not FG.

Canonical position map for existing group names

Position 1 — Form: Shape, Form, Rings, Segments, Fractal, Spirals, Grid, Contour, Noise, Membrane, Glyphs, Spheres, Cymatics, Cloud, Wave, Waves, Dual, Stars, Tunnel, Deform, Layer A, Layer B, Layer C, Combine, Beams, Sun, Horizon, Mountain, Plasma, Core, Rays, Ink, Distortion (structural UV warp), Style, Shimmer, Snow, Loops, Text

Position 2 — Simulation: Simulation, Forces, Emitter, Flock, Physics, Trail, Trails, Seed, Injection, Zones, Particles (when behavioral)

Position 3 — Motion: Motion, Rotation (when animation rate), Playback, Modulation, Position (when animated movement), Vortex (when spin rate). Avoid Animation, Speed as group names in new code.

Position 4 — View: View. Avoid Camera, Scene in new code.

Position 5 — Material: Material, Surface

Position 6 — Lighting: Lighting, Atmosphere. Avoid Scene for lighting-focused groups.

Position 7 — Color: Color 1, Color 2, Color 3, Background, Foreground, Dye, Sky, Sun, Mountain, Cloud, Grid, Wave, Palette 1, Palette 2 (and other semantic element names). Avoid BG Color, Bg, Sun Color, Mountain Color (the group name IS the semantic label — no Color suffix).

Position 8 — Display: Display, Glow. Avoid Render, Output in new code.

Position 9 — Quality: Quality

Position 10 — Transform: Transform (auto-appended)


VIII. Ambiguity Resolution

Some params could plausibly live in multiple categories. Use these tiebreakers:

ParamIf it does this……it goes here
contrastBlend/combine between layersForm (pos 1)
contrastTone mapping / post-processingDisplay (pos 8)
rotationAnimates over time (rotation speed)Motion (pos 3)
rotationStatic viewport angleView (pos 4)
brightnessPart of an HSB triplet (with colorGroup)Color (pos 7)
brightnessGlobal tone / exposure adjustmentDisplay (pos 8)
scaleChanges the pattern structure (cell size, noise frequency)Form (pos 1)
scaleZooms the viewport (camera distance)View (pos 4)
quality / iterationsAlwaysQuality (pos 9)

Mixed groups should be split. If a group contains params from multiple canonical positions (e.g., Scene with camera + lighting + quality), split it into separate groups. One group, one position.


IX. Examples

Each example shows: group structure (left border color comes from position), labels (what the user sees), and, where relevant, keys (internal, unchanged).

Voronoi (single-color, single-element)

Current keys (unchanged): cellCount, borderWidth, colorSpread, innerDark, speed, jitter, scale, rotation, color_h, color_s, brightness

Panel:

Shape
Cell Count
Border Width
Color Spread
Inner Dark
Motion
Speed
Jitter
View
Scale
Rotation
▶ Color 1 ⬤ ← collapsed by default

Expanded Color 1:

▼ Color 1 ⬤
Hue
Saturation
Brightness

Qualified labels (modulation picker, etc.): Shape Cell Count, Motion Speed, Color 1 Hue.

CubeGrid (multi-element, hybrid)

Grid
Grid Size, Grid X, Grid Y, Grid Z
Cubes (element: form + color)
Cube Size
Wireframe
▶ Color 1 ⬤
▶ Color 2 ⬤
Gradient
Gradient Angle
Motion
Rotate X, Rotate Y, Rotate Z, Shift V, Shift H, Pulse, Pulse Noise
View
Zoom, Rotate X, Rotate Y, Rotate Z
Lighting
Shadow, Light Angle, Light Elevation
▶ Background ⬤

Synthwave (multi-element, semantic group names)

Sun (form + color, flat — no color sub-group)
Radius, Height, Glow
Hue, Saturation, Brightness ← color params inline, not a sub-group
Mountain
Peak Height, Roughness
Hue, Saturation, Brightness
Grid
Lines, Perspective
Hue, Saturation, Brightness
...
Motion
Speed
View
Camera Distance

For element groups with a small number of color params, the HSB triplet renders as a collapsible inline row rather than a nested sub-group. Qualified label: Sun Hue, Mountain Saturation.


X. Audit Checklist

Run through this when creating a new source/effect or reviewing an existing one.

Structure

  • Spatial distinctness test applied. Multi-element vs single-element decision is deliberate.
  • Groups appear in canonical positional order (Form → Sim → Motion → View → Material → Lighting → Color → Display → Quality → Transform).
  • No group mixes canonical positions (e.g., no Scene with both camera and quality params).
  • Mode/type selectors come first within each group.
  • Macro before micro within each group.

Color

  • Every HSB triplet has colorGroup and colorRole.
  • HSB order is always H → S → B → Opacity.
  • Color labels are bare within their group (Hue, not Color 1 Hue).
  • colorMode / colorCycle / colorShift appear before the HSB triplets they modify.
  • Background-only groups named Background.
  • Every source with bg_h/s/b also has bg_opacity (CLAUDE.md rule).

Labels & Vocabulary

  • Labels follow the vocabulary dictionary (Brightness not Brt, Rotation not Rot, Frequency not Freq).
  • Labels are Title Case and fully spelled.
  • Static 3D axis orientation labels use Rotate X, Rotate Y, Rotate Z.
  • Labels read naturally both bare and qualified (e.g. Speed alone, Motion Speed qualified).
  • No label repeats its group name (Motion group contains Speed, not Motion Speed).
  • Group names use the vocabulary dictionary (Background not BG, Foreground not FG).
  • Color position-7 group names are semantic (Sun, not Sun Color).

Rendering

  • Color groups render collapsed by default (automatic if any param has colorGroup).

Quality

  • iterations, stepsPerFrame, quality are in a Quality group at position 9.

XI. Migration Notes

Phase B — Labels & Groups (non-breaking)

Renaming labels and group names has zero impact on saved shows, modulation bindings, button targets, MIDI mappings, or palette bindings. Show files store keys, not labels.

  • groupParamDefs() uses Map insertion order from SOURCE_PARAMS / EFFECT_PARAMS. Reordering params in ParamDefs.ts is sufficient to change UI order.
  • New sources MUST follow this standard.
  • Existing sources will be migrated as a coordinated Phase B pass.
  • Legacy group names tolerated during migration: Animation, Camera, Render, Scene, Output, Speed, BG Color, Sun Color. New code must not use these.

Phase D — Key renames (deferred)

Renaming internal keys (e.g. bg_hbackground_hue) requires a show-file migration plus audits across:

  1. Factory presets (FactoryScenePresets.ts, FactorySourcePresets.ts)
  2. Shader setParam() switches (81 sources, 69 effects)
  3. SOURCE_PARAM_RENAMES in ShowManager.ts
  4. Modulation target strings in saved shows
  5. Button target strings in saved shows
  6. Palette binding target strings
  7. MIDI CC mapping target strings
  8. Tests (param-coverage.test.ts, param-ranges.test.ts)
  9. Auto-generated docs

Not in scope for the labels/groups standardization pass. If/when pursued, requires: versioned show file bump, pre-migration auto-backup, user-visible toast on migration, per-source visual verification (before + after).

Phase E — File split (deferred)

Splitting ParamDefs.ts (37K lines) into per-source/per-effect files with a barrel is a separate infrastructure task. Defer until pending feat/*-source branches merge to avoid rebase pain.

  • Parameter Priority — how a parameter’s final value is resolved when MIDI, modulation, palette, and slider all want to set it.
  • The Modulation System — what colorGroup and colorRole plug into.
  • Color Palettes — how palette swatches bind to colorGroup-tagged params.