008 - Agents
Agents are reusable drawing components for the SceneGraph.
The Concept
An agent is an autonomous "thing that draws." It has its own parameters, its own state, its own Tweakpane UI. You add it to the SceneGraph, and it takes care of the rest.
Why Agents instead of Functions? A function drawParticles(ctx, particles) is stateless – you have to manage the particle list yourself. A ParticleManager agent manages its particles internally, has Tweakpane sliders for Count/Speed/Size, and you only call .draw(props).
Why SceneGraph? Because order matters. What is drawn first is behind. An agent for the background must come before the particles. The SceneGraph makes this explicit and allows reordering at runtime.
The Pattern: Each agent has a static ensureParameterSet() method that writes defaults to the ParameterObject. This must happen BEFORE Tweakpane setup – otherwise the Exhibition Mode crashes (which has no Tweakpane).
Overview
┌─────────────────┐
│ SceneGraph │
└─────────────────┘
│
┌───────────────────────────┼───────────────────────────┐
│ │ │ │ │ │ │
▼ ▼ ▼ │ ▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────┴───┐ ┌────────────┐ ┌────────────┐
│ Background │ │Background- │ │ Brush │ │ Particle- │ │ Particle- │
│ │ │ Shape │ │ │ │ Manager │ │ Wind │
└────────────┘ └────────────┘ └────────┘ └────────────┘ └────────────┘
┌───────────────────────────┼───────────────────────────┐
│ │ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────┐ ┌────────────┐ ┌────────────┐
│ Entity_ │ │ Grid_ │ │ Image- │ │ ImageLayer │ │ Characters │
│ Manager │ │ Manager │ │ Layer │ │ Dithering │ │ │
└────────────┘ └────────────┘ └────────┘ └────────────┘ └────────────┘
┌─────────────────────┐
│ DitherShapeGenerator│
└─────────────────────┘Agents List
| Agent | File | Function |
|---|---|---|
Background |
Background.ts |
Solid Color Background |
BackgroundShape |
BackgroundShape.ts |
Shape in Center |
Brush |
Brush.ts |
Universal Drawing Tool |
ParticleManager |
Particles.ts |
Particle System |
ParticleWind |
ParticleWind.ts |
Wind Particles with Noise |
Entity_Manager |
Entities.ts |
Bouncing/Wrapping Entities |
Grid_Manager |
Grid_Manager.ts |
Grid System |
ImageLayer |
ImageLayer.ts |
Image Display |
ImageLayerDithering |
ImageLayerDithering.ts |
Image with Dithering Effect |
Characters |
Characters.ts |
Text/Character Rendering |
DitherShapeGenerator |
DitherShapeGenerator.ts |
Shapes from Dither Data |
Background
Simple colored background.
Parameters:
| Parameter | Type | Description |
|---|---|---|
color |
string |
Background Color |
opacity |
number |
Transparency |
BackgroundShape
A shape centered in the background.
Parameters:
| Parameter | Type | Description |
|---|---|---|
brush |
Brush_ParameterSet |
Shape Definition |
scale |
number |
Scale |
rotation |
number |
Rotation (degrees) |
Brush
The universal drawing tool.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
shape |
string |
'Circle' | Shape Name |
position |
{x, y} |
(0.5, 0.5) | Position (normalized) |
size |
number |
100 | Size |
rotation |
number |
0 | Rotation |
fill |
boolean |
true | Fill? |
fillColor |
string |
'#FFFFFFFF' | Fill Color |
border |
number |
0 | Border Width |
borderColor |
string |
'#000000FF' | Border Color |
opacity |
number |
1 | Transparency |
Physics Options:
| Option | Type | Description |
|---|---|---|
physics.mode |
'none' | 'rigid' | 'soft' |
Physics Mode |
physics.rigid |
RigidBodyConfig |
Rigid Body Settings |
physics.soft |
SoftBodyConfig |
Soft Body Settings |
ParticleManager
Manages particle systems.
Parameters:
| Parameter | Type | Description |
|---|---|---|
count |
number |
Number of Particles |
source |
ParticleSource |
Spawn Source |
physics |
PhysicsConfig |
Physics Settings |
Particle Sources:
| Source | Description |
|---|---|
ImageParticleSource |
Particles from Image Pixels |
BrushParticleSource |
Particles in Brush Shape |
ParticleWind
Wind simulation with noise.
Parameters:
| Parameter | Type | Description |
|---|---|---|
count |
number |
Particle Count |
windStrength |
number |
Wind Strength |
noiseScale |
number |
Noise Scale |
gravity |
number |
Gravity |
fadeIn |
boolean |
Fade In? |
fadeOut |
boolean |
Fade Out? |
Entity_Manager
Bouncing/Wrapping objects.
Parameters:
| Parameter | Type | Description |
|---|---|---|
count |
number |
Number of Entities |
brush |
Brush_ParameterSet |
Entity Appearance |
velocity |
{min, max} |
Velocity Range |
boundaryMode |
'bounce' | 'wrap' |
Boundary Behavior |
Entity Features:
- Position, Velocity, Acceleration
- Bouncing at Canvas Boundaries
- Wrapping (Pac-Man Style)
- Collision Detection (optional)
Entity Stats Broadcasting
The Entity_Manager automatically writes statistics to the ParameterObject that can be received by other artworks (e.g., ParameterObserver):
// These values are automatically written to parameter.entity.stats:
{
centerX: 0.52, // Normalized center of all entities (0-1)
centerY: 0.48,
avgSpeed: 0.023, // Average speed (normalized)
spreadX: 0.31, // Entity spread
spreadY: 0.28,
// Positions of first 10 entities (normalized 0-1)
e0_x: 0.12, e0_y: 0.45,
e1_x: 0.67, e1_y: 0.23,
// ... up to e9
}Usage with ParameterObserver:
// In the observer artwork:
const observer = new ParameterObserver({
serverUrl: 'http://localhost:4000',
targetArtwork: 'item-cc-entities',
});
observer.onUpdate((params, artworkId) => {
const stats = params.entity?.stats;
if (stats) {
console.log(`Entities center: (${stats.centerX}, ${stats.centerY})`);
console.log(`Average speed: ${stats.avgSpeed}`);
}
});With Smart Filter in ParameterMandala, exactly these dynamic entity stats are visualized while static parameters (canvas size, animation settings) are filtered out.
Grid_Manager
Dual-View Grid System.
Parameters:
| Parameter | Type | Description |
|---|---|---|
cols |
number |
Columns |
rows |
number |
Rows |
cellPadding |
number |
Cell Spacing |
showLines |
boolean |
Show Lines? |
showPoints |
boolean |
Show Points? |
Views:
- PointGrid: Focus on intersection points and lines
- CellGrid: Focus on cells as mini canvases
ImageLayer
Image display.
Parameters:
| Parameter | Type | Description |
|---|---|---|
src |
string |
Image URL |
fit |
'contain' | 'cover' | 'fill' |
Fitting |
position |
{x, y} |
Position |
opacity |
number |
Transparency |
ImageLayerDithering
Image with dithering effect.
Parameters:
| Parameter | Type | Description |
|---|---|---|
src |
string |
Image URL |
ditherMode |
DitherMode |
Dithering Algorithm |
cellSize |
number |
Cell Size |
shape |
DitherShape |
Shape per Cell |
Dither Modes:
| Mode | Description |
|---|---|
threshold |
Simple Threshold |
floydSteinberg |
Floyd-Steinberg |
atkinson |
Atkinson |
ordered |
Ordered Dithering |
halftone |
Halftone Pattern |
Dither Shapes:
| Shape | Description |
|---|---|
circle |
Circles |
square |
Squares |
line |
Lines |
cross |
Crosses |
custom |
Custom Shapes |
Characters
Text and single characters.
Parameters:
| Parameter | Type | Description |
|---|---|---|
text |
string |
Text to Display |
font |
string |
Font Family |
fontSize |
number |
Font Size |
color |
string |
Text Color |
position |
{x, y} |
Position |
DitherShapeGenerator
Generates shapes from dither data for plotters.
Methods:
| Method | Description |
|---|---|
generate(imageData, opts) |
Generate Shapes |
getShapes() |
Get Shape Array |
Agent Interface
All agents implement:
interface Agent {
draw(props: ArtworkProps): void;
update?(deltaTime: number): void;
setParameter?(key: string, value: any): void;
}