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.
| Pos | Category | What it answers | Preferred name | Domain-specific names OK |
|---|---|---|---|---|
| 1 | Form | What is it? Shape, structure, geometry, pattern. | Shape, Form | Spirals, Grid, Contour, Layer A, Fractal, Glyphs, Membrane, Beams |
| 2 | Simulation | How does it behave? Physics, forces, emission. | Simulation | Forces, Emitter, Seed, Trail, Injection, Zones, Flock |
| 3 | Motion | How does it move over time? Speed, rotation rate, scroll. | Motion | Avoid Animation, Speed in new sources |
| 4 | View | Where are you looking from? Zoom, pan, camera orbit. | View | Avoid Camera, Scene in new sources |
| 5 | Material | What’s the surface? PBR, fresnel, SSS. | Material | Surface |
| 6 | Lighting | How is it lit? Direction, intensity, scatter. | Lighting | — |
| 7 | Color | What color? HSB triplets, modes, palette binding. | Color 1 | Background, Foreground, Sky, Dye, semantic element names |
| 8 | Display | Post-processing? Contrast, brightness, glow, vignette, invert. | Display | Avoid Render, Output in new sources |
| 9 | Quality | Performance knob? Iterations, resolution, steps. | Quality | — |
| 10 | Transform | Pipeline UV remap. Auto-appended. | Transform | Never 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.
- Type/mode selectors first.
geometry(dropdown) beforedetail(continuous).pattern_abeforefreq_a. - Count/size before spacing/detail.
gridSizebeforecubeSize.cellCountbeforeborderWidth. - Position before rotation. X/Y/Z position before tilt/rotation angles.
- Global speed at top of Motion. Overall
speedfirst, then per-element speeds (scrollSpeed,morphSpeed). - HSB: always H, S, B. Within a color sub-group, hue first, then saturation, then brightness, then opacity if present.
- Non-color params before HSB in Color groups.
colorMode,colorShift,colorCyclebefore the HSB triplets they modify. - Quality/performance at the bottom.
iterations,stepsPerFrame,qualityare 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
labelfield 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 1group, the hue param is labeledHue, notColor 1 Hue. UnderBackground, it’sHue, notBackground Hue. UnderMotion, the global speed isSpeed, notMotion Speed. - Full words only.
Brightness, notBrt.Rotation, notRot.Frequency, notFreq. See vocabulary dictionary in §V. - Title Case —
Color Spread, notcolor spreadorColorSpread.
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:
- Button binding target picker (ActionButtonPanel)
- Modulation target picker (ModulationPopup)
- MIDI CC mapping UI
- Palette swatch → param binding
- Controller panel custom profile element bindings
- Current-binding display — anywhere a target is rendered as a string (“Bound to: Color 1 Hue”)
- Auto-generated docs (
website/scripts/generate-reference.mjs) - Search / filter results that list params outside their group
- 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+Hue→Color 1 Hue✓.Motion+Speed→Motion Speed✓.Cubes+Color 1 Hue→Cubes Color 1 Hue(when colors are nested inside an element group, the full qualified label isgroup element-label). - Never prefix the label with the group yourself — the
getQualifiedLabelhelper composes it. If you writelabel: 'Color 1 Hue'in a ParamDef under groupColor 1, the qualified form becomesColor 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 theTransformgroup 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, orCamin 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, labelsRotate X,Rotate Y,Rotate Z; qualified labels becomeOrb Rotate X, etc. - Single-axis 2D/full-frame angle controls remain
Rotation. - Rotation rate controls remain
Rotation Speed; avoidRotate Speed,Auto Rotate, andOrbit Speedfor new labels. - Non-orientation directional controls may use semantic labels such as
Light Angle,Wind Angle,Scroll Angle, orGradient Angle. - Any angle, phase, hue, or full-cycle wrapping control should use normalized storage, degree display where appropriate,
unit: '°', andloopable: trueunless 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.
| Canonical | Avoid | Notes |
|---|---|---|
| Colors | ||
| Background | BG, Bg, Bg Color, Background Color | Group name is Background — no Color suffix needed. |
| Foreground | FG, Fg | |
| Hue | H, Hu | |
| Saturation | Sat, Saturat | |
| Brightness | Brt, Bright, Value | Prefer Brightness over Value (HSB convention). |
| Opacity | Op, Alpha | Use Alpha only when specifically the alpha channel of RGBA. |
| Motion | ||
| Speed | Spd | |
| Rotation | Rot | When referring to rate. See Ambiguity Resolution for static. |
| Rotate X/Y/Z | Rotation X/Y/Z, X/Y/Z Rotation, Tilt X/Y/Z, Orbit X/Y/Z, Pitch/Yaw/Roll, Pan, Cam | Use for static 3D axis orientation labels. |
| Angle | — | Use for static angular position. |
| Scroll | Scrl | |
| Form | ||
| Scale | Scl | |
| Size | Sz | |
| Radius | R, Rad | |
| Thickness | Thick, Thk | |
| Width | W | |
| Height | H | H conflicts with Hue — always spell out. |
| Depth | D | |
| Count | Num, N, Qty | |
| Position | Pos | |
| Distance | Dist | |
| Offset | Offs, Shift | Shift OK when it means a periodic phase shift. |
| Signal | ||
| Amplitude | Amp | |
| Frequency | Freq | |
| Phase | Ph | |
| Wavelength | Wavelen, Lambda | |
| Rendering | ||
| Iterations | Iter, Its | |
| Resolution | Res | |
| Quality | Q, Qual | |
| Contrast | Contr | |
| Other | ||
| Mix | Blend (when referring to param amount, not blend mode) | |
| Feedback | Fb | |
| Jitter | Jit |
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 separateColorgroup 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
- Every HSB triplet must have
colorGroupandcolorRolein its ParamDef. No exceptions. colorGroupvalues:color1,color2,color3,bg,fg, or a semantic slug matching the group name (sun,mountain,cloud). Used for palette binding lookup.colorRolevalues:h,s, orb— which HSB component this param drives. The palette overlay reads it to pull the matching channel (h/s/b) from the bound swatch. (ThecolorGroupslug — see rule 2 — selects which swatch;colorRoleselects the component.)- Labels inside a color group are bare:
Hue,Saturation,Brightness,Opacity. Never repeat the group name. - Color sub-ordering within the group: Hue → Saturation → Brightness → Opacity.
- Non-color modifier params precede HSB triplets:
colorMode,colorShift,colorCycleappear first. - Background opacity required: If a source has a background color group, include an
Opacityparam so the source can layer under other chain nodes. (Per CLAUDE.md —bg_opacitykey, labelOpacity,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
- Every group maps to one canonical position.
Spiralsis Form (pos 1).Injectionis Simulation (pos 2).Dyeis Color (pos 7). - Use canonical names for generic groups. If your source has basic shape params, call it
Shape— notParametersor a source-specific name. - Use domain names for specialized subsystems. Moire’s
Layer A/Layer B/Layer Care all Form (pos 1) but the names tell the user what they control. - Multiple groups at the same position is fine. They appear in logical sub-order: general before specific, primary before secondary.
- Group names follow the vocabulary dictionary.
Background, notBGorBg Color.Foreground, notFG.
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:
| Param | If it does this… | …it goes here |
|---|---|---|
contrast | Blend/combine between layers | Form (pos 1) |
contrast | Tone mapping / post-processing | Display (pos 8) |
rotation | Animates over time (rotation speed) | Motion (pos 3) |
rotation | Static viewport angle | View (pos 4) |
brightness | Part of an HSB triplet (with colorGroup) | Color (pos 7) |
brightness | Global tone / exposure adjustment | Display (pos 8) |
scale | Changes the pattern structure (cell size, noise frequency) | Form (pos 1) |
scale | Zooms the viewport (camera distance) | View (pos 4) |
quality / iterations | Always | Quality (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 DarkMotion Speed JitterView Scale Rotation▶ Color 1 ⬤ ← collapsed by defaultExpanded Color 1:
▼ Color 1 ⬤ Hue Saturation BrightnessQualified labels (modulation picker, etc.): Shape Cell Count, Motion Speed, Color 1 Hue.
CubeGrid (multi-element, hybrid)
Grid Grid Size, Grid X, Grid Y, Grid ZCubes (element: form + color) Cube Size Wireframe ▶ Color 1 ⬤ ▶ Color 2 ⬤ Gradient Gradient AngleMotion Rotate X, Rotate Y, Rotate Z, Shift V, Shift H, Pulse, Pulse NoiseView Zoom, Rotate X, Rotate Y, Rotate ZLighting 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-groupMountain Peak Height, Roughness Hue, Saturation, BrightnessGrid Lines, Perspective Hue, Saturation, Brightness...Motion SpeedView Camera DistanceFor 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
Scenewith both camera and quality params). - Mode/type selectors come first within each group.
- Macro before micro within each group.
Color
- Every HSB triplet has
colorGroupandcolorRole. - HSB order is always H → S → B → Opacity.
- Color labels are bare within their group (
Hue, notColor 1 Hue). -
colorMode/colorCycle/colorShiftappear before the HSB triplets they modify. - Background-only groups named
Background. - Every source with
bg_h/s/balso hasbg_opacity(CLAUDE.md rule).
Labels & Vocabulary
- Labels follow the vocabulary dictionary (
BrightnessnotBrt,RotationnotRot,FrequencynotFreq). - 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.
Speedalone,Motion Speedqualified). - No label repeats its group name (
Motiongroup containsSpeed, notMotion Speed). - Group names use the vocabulary dictionary (
BackgroundnotBG,ForegroundnotFG). - Color position-7 group names are semantic (
Sun, notSun Color).
Rendering
- Color groups render collapsed by default (automatic if any param has
colorGroup).
Quality
-
iterations,stepsPerFrame,qualityare in aQualitygroup 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()usesMapinsertion order fromSOURCE_PARAMS/EFFECT_PARAMS. Reordering params inParamDefs.tsis 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_h → background_hue) requires a show-file migration plus audits across:
- Factory presets (
FactoryScenePresets.ts,FactorySourcePresets.ts) - Shader
setParam()switches (81 sources, 69 effects) SOURCE_PARAM_RENAMESinShowManager.ts- Modulation target strings in saved shows
- Button target strings in saved shows
- Palette binding target strings
- MIDI CC mapping target strings
- Tests (
param-coverage.test.ts,param-ranges.test.ts) - 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.
Related
- 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
colorGroupandcolorRoleplug into. - Color Palettes — how palette swatches bind to
colorGroup-tagged params.