@nexart/codemode-sdk 1.5.0 → 1.6.0
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 +326 -0
- package/CODE_MODE_PROTOCOL.md +471 -0
- package/LICENSE.md +62 -0
- package/README.md +296 -58
- package/builder.manifest.schema.json +62 -0
- 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 +283 -0
- package/dist/execution-sandbox.d.ts +107 -0
- package/dist/execution-sandbox.d.ts.map +1 -0
- package/dist/execution-sandbox.js +207 -0
- package/dist/index.d.ts +24 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -16
- package/dist/loop-engine.d.ts +3 -0
- package/dist/loop-engine.d.ts.map +1 -1
- package/dist/loop-engine.js +17 -7
- 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/p5-runtime.d.ts +3 -1
- package/dist/p5-runtime.d.ts.map +1 -1
- package/dist/p5-runtime.js +2 -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/static-engine.d.ts +7 -0
- package/dist/static-engine.d.ts.map +1 -1
- package/dist/static-engine.js +69 -14
- package/dist/types.d.ts +67 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/package.json +26 -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**
|
package/LICENSE.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
NexArt Code Mode SDK — License
|
|
2
|
+
|
|
3
|
+
Version: 1.6.0
|
|
4
|
+
Status: DRAFT — Enforcement Not Active
|
|
5
|
+
|
|
6
|
+
⸻
|
|
7
|
+
|
|
8
|
+
License Status
|
|
9
|
+
|
|
10
|
+
The NexArt Code Mode SDK is currently released under the MIT License.
|
|
11
|
+
|
|
12
|
+
At this time, all usage — including commercial usage — is permitted under the MIT License.
|
|
13
|
+
|
|
14
|
+
This document also serves as advance notice of a future commercial licensing model that may apply to certain uses of the NexArt Protocol.
|
|
15
|
+
|
|
16
|
+
⸻
|
|
17
|
+
|
|
18
|
+
Future Commercial Licensing (Not Active)
|
|
19
|
+
|
|
20
|
+
NexArt intends to introduce a separate commercial license for specific categories of usage in a future release.
|
|
21
|
+
|
|
22
|
+
Planned commercial usage categories may include (non-exhaustive):
|
|
23
|
+
• Minting NFTs for sale
|
|
24
|
+
• Revenue-generating applications
|
|
25
|
+
• Products or services that charge fees
|
|
26
|
+
• Enterprise or business deployments
|
|
27
|
+
|
|
28
|
+
Enforcement is NOT active.
|
|
29
|
+
|
|
30
|
+
No license keys, validation, usage tracking, or commercial restrictions are currently implemented.
|
|
31
|
+
|
|
32
|
+
Until enforcement is introduced in a future version, all usage remains governed solely by the MIT License below.
|
|
33
|
+
|
|
34
|
+
⸻
|
|
35
|
+
|
|
36
|
+
MIT License
|
|
37
|
+
|
|
38
|
+
Copyright (c) 2024–2026 NexArt
|
|
39
|
+
|
|
40
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
41
|
+
of this software and associated documentation files (the “Software”), to deal
|
|
42
|
+
in the Software without restriction, including without limitation the rights
|
|
43
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
44
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
45
|
+
furnished to do so, subject to the following conditions:
|
|
46
|
+
|
|
47
|
+
The above copyright notice and this permission notice shall be included in all
|
|
48
|
+
copies or substantial portions of the Software.
|
|
49
|
+
|
|
50
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
51
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
52
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
53
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
54
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
55
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
56
|
+
SOFTWARE.
|
|
57
|
+
|
|
58
|
+
⸻
|
|
59
|
+
|
|
60
|
+
Contact
|
|
61
|
+
|
|
62
|
+
For future commercial licensing inquiries: arrotu@artnames.io
|