@nexart/codemode-sdk 1.5.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +289 -0
- package/CODE_MODE_PROTOCOL.md +471 -0
- package/README.md +232 -55
- package/dist/builder-manifest.d.ts +79 -0
- package/dist/builder-manifest.d.ts.map +1 -0
- package/dist/builder-manifest.js +97 -0
- package/dist/core-index.d.ts +21 -0
- package/dist/core-index.d.ts.map +1 -0
- package/dist/core-index.js +26 -0
- package/dist/engine.d.ts +17 -39
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +52 -253
- package/dist/execute.d.ts +46 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.js +282 -0
- package/dist/index.d.ts +24 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -16
- package/dist/noise-bridge.d.ts +44 -0
- package/dist/noise-bridge.d.ts.map +1 -0
- package/dist/noise-bridge.js +68 -0
- package/dist/noise-engine.d.ts +74 -0
- package/dist/noise-engine.d.ts.map +1 -0
- package/dist/noise-engine.js +132 -0
- package/dist/noise-sketches/fractalNoise.d.ts +11 -0
- package/dist/noise-sketches/fractalNoise.d.ts.map +1 -0
- package/dist/noise-sketches/fractalNoise.js +121 -0
- package/dist/noise-sketches/index.d.ts +21 -0
- package/dist/noise-sketches/index.d.ts.map +1 -0
- package/dist/noise-sketches/index.js +28 -0
- package/dist/sound-bridge.d.ts +89 -0
- package/dist/sound-bridge.d.ts.map +1 -0
- package/dist/sound-bridge.js +128 -0
- package/dist/soundart-engine.d.ts +87 -0
- package/dist/soundart-engine.d.ts.map +1 -0
- package/dist/soundart-engine.js +173 -0
- package/dist/soundart-sketches/chladniBloom.d.ts +3 -0
- package/dist/soundart-sketches/chladniBloom.d.ts.map +1 -0
- package/dist/soundart-sketches/chladniBloom.js +53 -0
- package/dist/soundart-sketches/dualVortex.d.ts +3 -0
- package/dist/soundart-sketches/dualVortex.d.ts.map +1 -0
- package/dist/soundart-sketches/dualVortex.js +67 -0
- package/dist/soundart-sketches/geometryIllusion.d.ts +3 -0
- package/dist/soundart-sketches/geometryIllusion.d.ts.map +1 -0
- package/dist/soundart-sketches/geometryIllusion.js +89 -0
- package/dist/soundart-sketches/index.d.ts +39 -0
- package/dist/soundart-sketches/index.d.ts.map +1 -0
- package/dist/soundart-sketches/index.js +72 -0
- package/dist/soundart-sketches/isoflow.d.ts +3 -0
- package/dist/soundart-sketches/isoflow.d.ts.map +1 -0
- package/dist/soundart-sketches/isoflow.js +60 -0
- package/dist/soundart-sketches/loomWeave.d.ts +3 -0
- package/dist/soundart-sketches/loomWeave.d.ts.map +1 -0
- package/dist/soundart-sketches/loomWeave.js +59 -0
- package/dist/soundart-sketches/noiseTerraces.d.ts +3 -0
- package/dist/soundart-sketches/noiseTerraces.d.ts.map +1 -0
- package/dist/soundart-sketches/noiseTerraces.js +53 -0
- package/dist/soundart-sketches/orb.d.ts +3 -0
- package/dist/soundart-sketches/orb.d.ts.map +1 -0
- package/dist/soundart-sketches/orb.js +50 -0
- package/dist/soundart-sketches/pixelGlyphs.d.ts +3 -0
- package/dist/soundart-sketches/pixelGlyphs.d.ts.map +1 -0
- package/dist/soundart-sketches/pixelGlyphs.js +72 -0
- package/dist/soundart-sketches/prismFlowFields.d.ts +3 -0
- package/dist/soundart-sketches/prismFlowFields.d.ts.map +1 -0
- package/dist/soundart-sketches/prismFlowFields.js +51 -0
- package/dist/soundart-sketches/radialBurst.d.ts +3 -0
- package/dist/soundart-sketches/radialBurst.d.ts.map +1 -0
- package/dist/soundart-sketches/radialBurst.js +60 -0
- package/dist/soundart-sketches/resonantSoundBodies.d.ts +3 -0
- package/dist/soundart-sketches/resonantSoundBodies.d.ts.map +1 -0
- package/dist/soundart-sketches/resonantSoundBodies.js +89 -0
- package/dist/soundart-sketches/rings.d.ts +11 -0
- package/dist/soundart-sketches/rings.d.ts.map +1 -0
- package/dist/soundart-sketches/rings.js +89 -0
- package/dist/soundart-sketches/squares.d.ts +3 -0
- package/dist/soundart-sketches/squares.d.ts.map +1 -0
- package/dist/soundart-sketches/squares.js +52 -0
- package/dist/soundart-sketches/waveStripes.d.ts +3 -0
- package/dist/soundart-sketches/waveStripes.d.ts.map +1 -0
- package/dist/soundart-sketches/waveStripes.js +44 -0
- package/dist/types.d.ts +41 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/package.json +24 -15
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
# Code Mode Protocol v1.2.0 — Phase 3
|
|
2
|
+
|
|
3
|
+
> **Status:** STABLE
|
|
4
|
+
> **Enforcement:** HARD
|
|
5
|
+
> **Effective Date:** January 2026
|
|
6
|
+
|
|
7
|
+
This document is **normative**. It defines the official Code Mode execution surface for NexArt Protocol. All implementations (NexArt app, ByX, external builders) MUST conform to this specification.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. Protocol Identity
|
|
12
|
+
|
|
13
|
+
| Property | Value |
|
|
14
|
+
|----------|-------|
|
|
15
|
+
| Protocol | `nexart` |
|
|
16
|
+
| Engine | `codemode` |
|
|
17
|
+
| Version | `1.2.0` |
|
|
18
|
+
| Phase | `3` |
|
|
19
|
+
| Deterministic | `true` |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 2. Execution Modes
|
|
24
|
+
|
|
25
|
+
### 2.1 Static Mode
|
|
26
|
+
- Executes `setup()` once
|
|
27
|
+
- `draw()` is **NOT** executed
|
|
28
|
+
- Output: Single PNG image
|
|
29
|
+
- Time variables: All `0`
|
|
30
|
+
|
|
31
|
+
### 2.2 Loop Mode
|
|
32
|
+
- Executes `setup()` once
|
|
33
|
+
- Executes `draw()` for each frame
|
|
34
|
+
- Canvas is cleared before each `draw()` call
|
|
35
|
+
- Blend mode resets to `NORMAL` before each `draw()` call
|
|
36
|
+
- Output: MP4 video (1-4 seconds, 30 FPS)
|
|
37
|
+
- Requires `totalFrames` to be specified
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 3. Protocol Variables (VAR[0..9])
|
|
42
|
+
|
|
43
|
+
### 3.1 Definition
|
|
44
|
+
- Input: 0-10 elements allowed (protocol error if > 10)
|
|
45
|
+
- Runtime: ALWAYS 10 elements (padded with zeros)
|
|
46
|
+
- Type: `readonly number[]`
|
|
47
|
+
- Range: `0` to `100` (strict — protocol error if out of range)
|
|
48
|
+
- Default: All zeros `[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
|
|
49
|
+
|
|
50
|
+
### 3.2 Access
|
|
51
|
+
```javascript
|
|
52
|
+
// ✅ Allowed - reading (missing indices return 0)
|
|
53
|
+
let size = VAR[0]; // Returns provided value or 0
|
|
54
|
+
let opacity = map(VAR[1], 0, 100, 0, 255);
|
|
55
|
+
|
|
56
|
+
// ❌ Forbidden - writing (throws protocol error)
|
|
57
|
+
VAR[0] = 50; // [Code Mode Protocol Error] VAR is read-only
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3.3 Enforcement
|
|
61
|
+
| Condition | Enforcement |
|
|
62
|
+
|-----------|-------------|
|
|
63
|
+
| Input length > 10 | HARD — throws protocol error |
|
|
64
|
+
| Value outside 0-100 | HARD — throws protocol error |
|
|
65
|
+
| Non-number value | HARD — throws protocol error |
|
|
66
|
+
| Write attempt | HARD — throws protocol error |
|
|
67
|
+
| Missing input | Runtime padded with zeros |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 4. Supported Globals
|
|
72
|
+
|
|
73
|
+
### 4.1 Canvas Environment
|
|
74
|
+
| Global | Type | Description |
|
|
75
|
+
|--------|------|-------------|
|
|
76
|
+
| `width` | `number` | Canvas width (default: 1950) |
|
|
77
|
+
| `height` | `number` | Canvas height (default: 2400) |
|
|
78
|
+
|
|
79
|
+
### 4.2 Time Variables
|
|
80
|
+
| Global | Type | Description |
|
|
81
|
+
|--------|------|-------------|
|
|
82
|
+
| `frameCount` | `number` | Current frame (0, 1, 2, ...) |
|
|
83
|
+
| `t` | `number` | Normalized time [0.0, 1.0) |
|
|
84
|
+
| `time` | `number` | Elapsed seconds |
|
|
85
|
+
| `tGlobal` | `number` | Alias for `t` |
|
|
86
|
+
| `totalFrames` | `number` | Total frames in loop mode |
|
|
87
|
+
|
|
88
|
+
### 4.3 Math Constants
|
|
89
|
+
| Global | Value |
|
|
90
|
+
|--------|-------|
|
|
91
|
+
| `PI` | `3.141592653589793` |
|
|
92
|
+
| `TWO_PI` | `6.283185307179586` |
|
|
93
|
+
| `TAU` | `6.283185307179586` |
|
|
94
|
+
| `HALF_PI` | `1.5707963267948966` |
|
|
95
|
+
| `QUARTER_PI` | `0.7853981633974483` |
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 5. Supported Functions
|
|
100
|
+
|
|
101
|
+
### 5.1 Drawing Primitives
|
|
102
|
+
- `line(x1, y1, x2, y2)`
|
|
103
|
+
- `rect(x, y, w, h, [r])`
|
|
104
|
+
- `square(x, y, s, [r])` — Square shorthand
|
|
105
|
+
- `ellipse(x, y, w, h)`
|
|
106
|
+
- `circle(x, y, d)`
|
|
107
|
+
- `triangle(x1, y1, x2, y2, x3, y3)`
|
|
108
|
+
- `quad(x1, y1, x2, y2, x3, y3, x4, y4)`
|
|
109
|
+
- `arc(x, y, w, h, start, stop, [mode])`
|
|
110
|
+
- `point(x, y)`
|
|
111
|
+
- `beginShape()` / `vertex(x, y)` / `endShape([close])`
|
|
112
|
+
- `curveVertex(x, y)` — Add Catmull-Rom spline vertex
|
|
113
|
+
- `bezierVertex(cx1, cy1, cx2, cy2, x, y)` — Add cubic bezier vertex
|
|
114
|
+
- `bezier(x1, y1, cx1, cy1, cx2, cy2, x2, y2)`
|
|
115
|
+
- `curve(x1, y1, x2, y2, x3, y3, x4, y4)`
|
|
116
|
+
|
|
117
|
+
### 5.1.1 Shape Helpers (v1.1)
|
|
118
|
+
- `polygon(cx, cy, radius, sides, [rotation])` — Regular polygon
|
|
119
|
+
- `star(cx, cy, innerRadius, outerRadius, points, [rotation])` — Star shape
|
|
120
|
+
|
|
121
|
+
Rules:
|
|
122
|
+
- Internally expand to `beginShape()` / `vertex()` / `endShape(CLOSE)`
|
|
123
|
+
- No hidden state
|
|
124
|
+
- No randomness (pure geometry)
|
|
125
|
+
|
|
126
|
+
### 5.2 Style
|
|
127
|
+
- `fill(...)` — Supports all CSS color formats
|
|
128
|
+
- `noFill()`
|
|
129
|
+
- `stroke(...)` — Supports all CSS color formats
|
|
130
|
+
- `noStroke()`
|
|
131
|
+
- `strokeWeight(w)`
|
|
132
|
+
- `strokeCap(cap)` — `ROUND`, `SQUARE`, `PROJECT`
|
|
133
|
+
- `strokeJoin(join)` — `MITER`, `BEVEL`, `ROUND`
|
|
134
|
+
- `background(...)` — Supports all CSS color formats
|
|
135
|
+
- `clear()` — Clear canvas to transparent
|
|
136
|
+
- `colorMode(mode, [max1], [max2], [max3], [maxA])`
|
|
137
|
+
|
|
138
|
+
### 5.2.1 Blend Modes (v1.1)
|
|
139
|
+
- `blendMode(mode)` — Set compositing mode
|
|
140
|
+
|
|
141
|
+
Supported modes (ONLY these are allowed):
|
|
142
|
+
| Mode | Canvas Equivalent |
|
|
143
|
+
|------|-------------------|
|
|
144
|
+
| `NORMAL` | `source-over` |
|
|
145
|
+
| `ADD` | `lighter` |
|
|
146
|
+
| `MULTIPLY` | `multiply` |
|
|
147
|
+
| `SCREEN` | `screen` |
|
|
148
|
+
|
|
149
|
+
Rules:
|
|
150
|
+
- Unsupported modes MUST throw a protocol error
|
|
151
|
+
- Blend mode resets to `NORMAL` before each `draw()` in Loop Mode
|
|
152
|
+
- No custom or dynamic modes
|
|
153
|
+
|
|
154
|
+
### 5.2.2 Shape Mode Constants
|
|
155
|
+
- `CORNER` / `CENTER` / `CORNERS` / `RADIUS` — Rect/ellipse mode
|
|
156
|
+
- `CLOSE` — For `endShape(CLOSE)`
|
|
157
|
+
- `ROUND` / `SQUARE` / `PROJECT` — Stroke cap styles
|
|
158
|
+
- `MITER` / `BEVEL` — Stroke join styles
|
|
159
|
+
- `PIE` / `CHORD` / `OPEN` — Arc modes
|
|
160
|
+
- `LEFT` / `CENTER` / `RIGHT` — Horizontal alignment
|
|
161
|
+
- `TOP` / `BOTTOM` / `BASELINE` — Vertical alignment
|
|
162
|
+
- `NORMAL` / `ADD` / `MULTIPLY` / `SCREEN` — Blend modes
|
|
163
|
+
|
|
164
|
+
### 5.3 Color Functions
|
|
165
|
+
- `color(...)` — Create color object
|
|
166
|
+
- `lerpColor(c1, c2, amt)` — Interpolate colors
|
|
167
|
+
- `red(c)` / `green(c)` / `blue(c)` / `alpha(c)` — Extract components
|
|
168
|
+
- `hue(c)` / `saturation(c)` / `brightness(c)` — HSB extraction
|
|
169
|
+
|
|
170
|
+
### 5.4 Transforms
|
|
171
|
+
- `push()` / `pop()`
|
|
172
|
+
- `translate(x, y)`
|
|
173
|
+
- `rotate(angle)`
|
|
174
|
+
- `scale(s)` / `scale(sx, sy)`
|
|
175
|
+
- `resetMatrix()`
|
|
176
|
+
- `shearX(angle)` / `shearY(angle)`
|
|
177
|
+
|
|
178
|
+
### 5.5 Random (Seeded)
|
|
179
|
+
- `random([min], [max])` — Seeded pseudo-random
|
|
180
|
+
- `randomSeed(seed)` — Set random seed
|
|
181
|
+
- `randomGaussian([mean], [sd])` — Seeded Gaussian
|
|
182
|
+
|
|
183
|
+
### 5.6 Noise (Seeded)
|
|
184
|
+
- `noise(x, [y], [z])` — Seeded Perlin noise
|
|
185
|
+
- `noiseSeed(seed)` — Set noise seed
|
|
186
|
+
- `noiseDetail(octaves, [falloff])` — Configure noise
|
|
187
|
+
|
|
188
|
+
### 5.6.1 Noise Extensions (v1.1)
|
|
189
|
+
- `fbm(x, y, [octaves], [falloff])` — Fractal Brownian Motion
|
|
190
|
+
- `ridgedNoise(x, y)` — Ridged/turbulent noise
|
|
191
|
+
- `curlNoise(x, y)` — Returns `{x, y}` curl noise vector
|
|
192
|
+
|
|
193
|
+
Rules:
|
|
194
|
+
- All use existing seeded `noise()` internally
|
|
195
|
+
- Pure functions with no internal state
|
|
196
|
+
- Deterministic for same inputs + seed
|
|
197
|
+
|
|
198
|
+
### 5.7 Math Utilities
|
|
199
|
+
- `map(value, start1, stop1, start2, stop2)`
|
|
200
|
+
- `constrain(value, min, max)`
|
|
201
|
+
- `lerp(start, stop, amt)`
|
|
202
|
+
- `dist(x1, y1, x2, y2)`
|
|
203
|
+
- `mag(x, y)`
|
|
204
|
+
- `norm(value, start, stop)`
|
|
205
|
+
- `abs()` / `floor()` / `ceil()` / `round()` / `sqrt()` / `pow()` / `exp()` / `log()`
|
|
206
|
+
- `sin()` / `cos()` / `tan()` / `asin()` / `acos()` / `atan()` / `atan2()`
|
|
207
|
+
- `min()` / `max()`
|
|
208
|
+
- `radians(degrees)` / `degrees(radians)`
|
|
209
|
+
|
|
210
|
+
### 5.7.1 Math Helpers (v1.1)
|
|
211
|
+
- `sq(n)` — Square: `n * n`
|
|
212
|
+
- `int(n)` — Floor to integer: `floor(n)`
|
|
213
|
+
- `fract(n)` — Fractional part: `n - floor(n)`
|
|
214
|
+
- `sign(n)` — Sign: `-1`, `0`, or `1`
|
|
215
|
+
|
|
216
|
+
Rules:
|
|
217
|
+
- Pure functions only
|
|
218
|
+
- No side effects
|
|
219
|
+
- Deterministic
|
|
220
|
+
|
|
221
|
+
### 5.8 Vector Helpers (v1.1)
|
|
222
|
+
|
|
223
|
+
Vectors are **plain objects** `{ x: number, y: number }`. No classes or mutable state.
|
|
224
|
+
|
|
225
|
+
- `vec(x, y)` — Create vector `{ x, y }`
|
|
226
|
+
- `vecAdd(a, b)` — Add vectors: `{ x: a.x + b.x, y: a.y + b.y }`
|
|
227
|
+
- `vecSub(a, b)` — Subtract vectors: `{ x: a.x - b.x, y: a.y - b.y }`
|
|
228
|
+
- `vecMult(v, s)` — Scale vector: `{ x: v.x * s, y: v.y * s }`
|
|
229
|
+
- `vecMag(v)` — Magnitude: `sqrt(v.x² + v.y²)`
|
|
230
|
+
- `vecNorm(v)` — Normalize to unit vector
|
|
231
|
+
- `vecDist(a, b)` — Distance between two vectors
|
|
232
|
+
|
|
233
|
+
Rules:
|
|
234
|
+
- All functions return NEW objects (no mutation)
|
|
235
|
+
- No p5.Vector compatibility
|
|
236
|
+
- No methods on vector objects
|
|
237
|
+
|
|
238
|
+
### 5.9 Easing Functions (v1.1)
|
|
239
|
+
|
|
240
|
+
All easing functions:
|
|
241
|
+
- Input: `t ∈ [0, 1]`
|
|
242
|
+
- Output: `∈ [0, 1]`
|
|
243
|
+
- Pure functions, no clamping side effects
|
|
244
|
+
|
|
245
|
+
- `easeIn(t)` — Quadratic ease in
|
|
246
|
+
- `easeOut(t)` — Quadratic ease out
|
|
247
|
+
- `easeInOut(t)` — Quadratic ease in-out
|
|
248
|
+
- `easeCubic(t)` — Cubic ease in-out
|
|
249
|
+
- `easeExpo(t)` — Exponential ease in-out
|
|
250
|
+
|
|
251
|
+
### 5.10 Text
|
|
252
|
+
- `text(str, x, y)`
|
|
253
|
+
- `textSize(size)`
|
|
254
|
+
- `textFont(font)`
|
|
255
|
+
- `textAlign(horizAlign, [vertAlign])`
|
|
256
|
+
- `textWidth(str)`
|
|
257
|
+
|
|
258
|
+
### 5.11 Image/Pixel (v1.2)
|
|
259
|
+
- `loadPixels()` — Load canvas pixels into `pixels[]` array
|
|
260
|
+
- `updatePixels()` — Write `pixels[]` array back to canvas
|
|
261
|
+
- `pixels[]` — RGBA pixel array (length = width × height × 4)
|
|
262
|
+
- `get(x, y)` — Get pixel color at (x, y) as RGBA array
|
|
263
|
+
- `set(x, y, color)` — Set pixel color at (x, y)
|
|
264
|
+
|
|
265
|
+
Rules:
|
|
266
|
+
- `pixels[]` is a flat array: `[R, G, B, A, R, G, B, A, ...]`
|
|
267
|
+
- Index formula: `i = (y * width + x) * 4`
|
|
268
|
+
- Must call `loadPixels()` before reading/modifying `pixels[]`
|
|
269
|
+
- Must call `updatePixels()` after modifying `pixels[]`
|
|
270
|
+
- Deterministic: no external state
|
|
271
|
+
|
|
272
|
+
### 5.12 Offscreen Graphics (v1.2)
|
|
273
|
+
- `createGraphics(w, h)` — Create offscreen canvas
|
|
274
|
+
|
|
275
|
+
Returns a graphics object with:
|
|
276
|
+
- All drawing functions (rect, ellipse, line, etc.)
|
|
277
|
+
- All style functions (fill, stroke, etc.)
|
|
278
|
+
- All transform functions (push, pop, translate, etc.)
|
|
279
|
+
- `image(pg, x, y, [w], [h])` — Draw to main canvas
|
|
280
|
+
|
|
281
|
+
Rules:
|
|
282
|
+
- Offscreen graphics inherit seed from main canvas
|
|
283
|
+
- Each graphics object has independent state
|
|
284
|
+
- Deterministic: same execution = identical output
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## 6. Forbidden Patterns
|
|
289
|
+
|
|
290
|
+
The following patterns are **explicitly forbidden** and MUST throw errors:
|
|
291
|
+
|
|
292
|
+
| Pattern | Reason |
|
|
293
|
+
|---------|--------|
|
|
294
|
+
| `setTimeout()` | Async timing breaks determinism |
|
|
295
|
+
| `setInterval()` | Async timing breaks determinism |
|
|
296
|
+
| `requestAnimationFrame()` | Async timing breaks determinism |
|
|
297
|
+
| `noLoop()` (in Loop Mode) | Incompatible with frame capture |
|
|
298
|
+
| `createCanvas()` | Canvas is pre-initialized |
|
|
299
|
+
| `fetch()` / `XMLHttpRequest` | External IO breaks determinism |
|
|
300
|
+
| `import` / `require` | No external modules |
|
|
301
|
+
| DOM manipulation | No direct DOM access |
|
|
302
|
+
| `Date.now()` / `new Date()` | Time-based entropy breaks determinism |
|
|
303
|
+
| `Math.random()` | Use `random()` instead (seeded) |
|
|
304
|
+
| `p5.Vector` | Use plain vector objects instead |
|
|
305
|
+
| Unsupported blend modes | Only NORMAL, ADD, MULTIPLY, SCREEN |
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## 7. Determinism Guarantees
|
|
310
|
+
|
|
311
|
+
### 7.1 Invariant
|
|
312
|
+
```
|
|
313
|
+
Same code + Same seed + Same VARs = Identical output
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### 7.2 Sources of Randomness
|
|
317
|
+
- **Allowed:** `random()`, `noise()` — Both are seeded
|
|
318
|
+
- **Forbidden:** `Math.random()`, `Date`, browser entropy
|
|
319
|
+
|
|
320
|
+
### 7.3 Verification
|
|
321
|
+
Any execution can be verified by re-running with the same inputs.
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## 8. Canonical Execution API
|
|
326
|
+
|
|
327
|
+
### 8.1 Entry Point
|
|
328
|
+
```typescript
|
|
329
|
+
executeCodeMode({
|
|
330
|
+
source: string,
|
|
331
|
+
width: number,
|
|
332
|
+
height: number,
|
|
333
|
+
seed: number,
|
|
334
|
+
vars?: number[],
|
|
335
|
+
mode: 'static' | 'loop',
|
|
336
|
+
totalFrames?: number
|
|
337
|
+
}) => Promise<ExecutionResult>
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### 8.2 Result Structure
|
|
341
|
+
```typescript
|
|
342
|
+
interface ExecutionResult {
|
|
343
|
+
image?: Blob; // Static mode: PNG
|
|
344
|
+
video?: Blob; // Loop mode: MP4
|
|
345
|
+
frames?: ImageData[]; // Optional: raw frames
|
|
346
|
+
metadata: {
|
|
347
|
+
protocol: 'nexart';
|
|
348
|
+
engine: 'codemode';
|
|
349
|
+
protocolVersion: '1.2.0';
|
|
350
|
+
phase: 3;
|
|
351
|
+
deterministic: true;
|
|
352
|
+
seed: number;
|
|
353
|
+
vars: number[];
|
|
354
|
+
width: number;
|
|
355
|
+
height: number;
|
|
356
|
+
mode: 'static' | 'loop';
|
|
357
|
+
totalFrames?: number;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## 9. Implementation Requirements
|
|
365
|
+
|
|
366
|
+
### 9.1 SDK Authority
|
|
367
|
+
- `@nexart/codemode-sdk` is the single source of truth
|
|
368
|
+
- NexArt app, ByX, and external clients MUST delegate to this SDK
|
|
369
|
+
- No other renderer may redefine Code Mode semantics
|
|
370
|
+
|
|
371
|
+
### 9.2 Logging
|
|
372
|
+
All executions MUST log:
|
|
373
|
+
```
|
|
374
|
+
[CodeMode] Rendered via @nexart/codemode-sdk (Protocol v1.2.0)
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### 9.3 Error Handling
|
|
378
|
+
- Missing `draw()` in Loop Mode → Error
|
|
379
|
+
- Missing `totalFrames` in Loop Mode → Error
|
|
380
|
+
- VAR mutation attempt → Warning + Error log (no crash)
|
|
381
|
+
- Unsupported function → Clear error message
|
|
382
|
+
- Unsupported blend mode → Protocol error
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## 10. Why These Were Added (v1.1 Rationale)
|
|
387
|
+
|
|
388
|
+
### Expressive Power
|
|
389
|
+
- **Shape Helpers**: `polygon()` and `star()` reduce boilerplate for common patterns
|
|
390
|
+
- **Vector Helpers**: Enable clean geometric calculations without p5.Vector overhead
|
|
391
|
+
- **Easing Functions**: Essential for smooth animations in Loop Mode
|
|
392
|
+
|
|
393
|
+
### Determinism
|
|
394
|
+
- **All new functions are pure**: No side effects, no hidden state
|
|
395
|
+
- **Blend modes are strictly limited**: Only 4 safe compositing modes
|
|
396
|
+
- **Noise extensions use seeded noise()**: No new sources of randomness
|
|
397
|
+
|
|
398
|
+
### Cross-Runtime Portability
|
|
399
|
+
- **Plain vector objects**: Work identically in browser, Node.js, and headless environments
|
|
400
|
+
- **No DOM dependencies**: All functions work without a browser
|
|
401
|
+
- **Stateless math**: Every function can be verified independently
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## 11. Future Phases
|
|
406
|
+
|
|
407
|
+
| Phase | Scope | Status |
|
|
408
|
+
|-------|-------|--------|
|
|
409
|
+
| Phase 3 | Pixel manipulation, offscreen buffers | ✅ COMPLETE (v1.2.0) |
|
|
410
|
+
| Phase 4 | External asset loading (controlled) | Planned |
|
|
411
|
+
| Phase 5 | WebGL/3D support | Planned |
|
|
412
|
+
|
|
413
|
+
Each phase requires a protocol version bump and formal specification.
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
## 12. Changelog
|
|
418
|
+
|
|
419
|
+
### v1.2.0 (January 2026)
|
|
420
|
+
**Phase 3 — Pixel & Graphics**
|
|
421
|
+
|
|
422
|
+
Added:
|
|
423
|
+
- Vertex functions: `curveVertex(x, y)`, `bezierVertex(cx1, cy1, cx2, cy2, x, y)`
|
|
424
|
+
- Pixel system: `loadPixels()`, `updatePixels()`, `pixels[]`, `get(x, y)`, `set(x, y, color)`
|
|
425
|
+
- Graphics system: `createGraphics(w, h)`, `image(pg, x, y, w, h)`
|
|
426
|
+
- Time variable: `totalFrames` now injected in Loop Mode
|
|
427
|
+
|
|
428
|
+
Rules:
|
|
429
|
+
- All new functions are pure and deterministic
|
|
430
|
+
- Pixel manipulation follows p5.js semantics
|
|
431
|
+
- Offscreen graphics inherit seed from main canvas
|
|
432
|
+
|
|
433
|
+
### v1.1.0 (January 2026)
|
|
434
|
+
**Phase 2 — Expressive Extensions**
|
|
435
|
+
|
|
436
|
+
Added:
|
|
437
|
+
- Math helpers: `fract(n)`, `sign(n)` (sq, int already in v1.0.1)
|
|
438
|
+
- Vector helpers: `vec`, `vecAdd`, `vecSub`, `vecMult`, `vecMag`, `vecNorm`, `vecDist`
|
|
439
|
+
- Shape helpers: `polygon(cx, cy, r, sides, rotation)`, `star(cx, cy, rIn, rOut, points, rotation)`
|
|
440
|
+
- Blend modes: `blendMode(NORMAL|ADD|MULTIPLY|SCREEN)`
|
|
441
|
+
- Noise extensions: `fbm(x, y, octaves, falloff)`, `ridgedNoise(x, y)`, `curlNoise(x, y)`
|
|
442
|
+
- Easing functions: `easeIn`, `easeOut`, `easeInOut`, `easeCubic`, `easeExpo`
|
|
443
|
+
|
|
444
|
+
Rules:
|
|
445
|
+
- All new functions are pure and deterministic
|
|
446
|
+
- Vectors are plain objects (no p5.Vector)
|
|
447
|
+
- Blend mode resets per frame in Loop Mode
|
|
448
|
+
- Unsupported blend modes throw protocol errors
|
|
449
|
+
|
|
450
|
+
### v1.0.1 (January 2026)
|
|
451
|
+
- Added `square(x, y, s, [r])` to drawing primitives
|
|
452
|
+
- Added `clear()` to style functions
|
|
453
|
+
- Added `bezier()`, `curve()` to drawing primitives
|
|
454
|
+
- Added `strokeCap()`, `strokeJoin()` to style
|
|
455
|
+
- Added `shearX()`, `shearY()` to transforms
|
|
456
|
+
- Added `sq()`, `int()` to math
|
|
457
|
+
- Added text system: `text()`, `textSize()`, `textFont()`, `textAlign()`, `textWidth()`
|
|
458
|
+
- Documented shape mode constants
|
|
459
|
+
- Documented text alignment constants
|
|
460
|
+
|
|
461
|
+
### v1.0.0 (December 2024)
|
|
462
|
+
- Initial locked specification
|
|
463
|
+
- VAR[0..9] read-only protocol variables
|
|
464
|
+
- Full CSS color support
|
|
465
|
+
- Seeded random/noise
|
|
466
|
+
- Static + Loop modes
|
|
467
|
+
- HARD enforcement enabled
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
**End of Specification**
|