@nexart/codemode-sdk 1.7.0 → 1.8.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 +99 -0
- package/COMMERCIAL.md +41 -0
- package/README.md +223 -608
- package/dist/core-index.d.ts +1 -1
- package/dist/core-index.js +1 -1
- package/dist/entry/browser.d.ts +8 -2
- package/dist/entry/browser.d.ts.map +1 -1
- package/dist/entry/browser.js +10 -2
- package/dist/entry/node.d.ts +3 -1
- package/dist/entry/node.d.ts.map +1 -1
- package/dist/entry/node.js +3 -1
- package/dist/runtime.d.ts +52 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +219 -0
- package/examples/basic.ts +61 -0
- package/examples/preflight-test.ts +275 -0
- package/examples/verify.ts +151 -0
- package/package.json +20 -3
package/README.md
CHANGED
|
@@ -1,279 +1,285 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
**Version: 1.7.0 (Protocol v1.2.0)**
|
|
4
|
-
|
|
5
|
-
╔══════════════════════════════════════════════════════════════════════════════╗
|
|
6
|
-
║ @nexart/codemode-sdk — Canonical Execution Surface ║
|
|
7
|
-
║ ║
|
|
8
|
-
║ This SDK IS the protocol. All implementations MUST use this SDK. ║
|
|
9
|
-
║ ║
|
|
10
|
-
║ Protocol: nexart ║
|
|
11
|
-
║ Engine: codemode ║
|
|
12
|
-
║ SDK Version: 1.7.0 ║
|
|
13
|
-
║ Protocol Version: 1.2.0 ║
|
|
14
|
-
║ Phase: 3 ║
|
|
15
|
-
║ Enforcement: HARD ║
|
|
16
|
-
╚══════════════════════════════════════════════════════════════════════════════╝
|
|
1
|
+
# @nexart/codemode-sdk
|
|
17
2
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
## Commercial Licensing
|
|
21
|
-
|
|
22
|
-
> **Commercial usage of NexArt Protocol requires a license.**
|
|
23
|
-
> **Enforcement is not active yet.**
|
|
3
|
+
**Version: 1.8.1 (Protocol v1.2.0)**
|
|
24
4
|
|
|
25
|
-
|
|
5
|
+
A deterministic execution runtime for reproducible, verifiable computation.
|
|
26
6
|
|
|
27
7
|
---
|
|
28
8
|
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
| Property | Value |
|
|
32
|
-
|----------|-------|
|
|
33
|
-
| Protocol Name | NexArt Code Mode |
|
|
34
|
-
| Version | v1.2.0 |
|
|
35
|
-
| Status | **STABLE** |
|
|
36
|
-
| Phase | 3 |
|
|
37
|
-
| Lock Date | January 2026 |
|
|
38
|
-
|
|
39
|
-
**Core protocol surface is frozen. Any breaking change requires v2.0.0.**
|
|
9
|
+
## What This SDK Does
|
|
40
10
|
|
|
41
|
-
|
|
11
|
+
This SDK provides a **deterministic runtime layer** for executing code that must produce identical output given identical inputs — across environments, over time, and under verification.
|
|
42
12
|
|
|
43
|
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
- Canvas pre-initialization (no createCanvas)
|
|
13
|
+
**Core guarantees:**
|
|
14
|
+
- Same `seed` + `vars` + `code` → identical output (always)
|
|
15
|
+
- Cross-environment stability (browser, Node.js, CI pipelines)
|
|
16
|
+
- Strict mode blocks non-deterministic APIs (`Math.random`, `Date.now`, etc.)
|
|
17
|
+
- Canonical state snapshots for replay and verification
|
|
18
|
+
- Stable digest for integrity verification
|
|
50
19
|
|
|
51
20
|
---
|
|
52
21
|
|
|
53
|
-
|
|
22
|
+
## Who This Is For
|
|
23
|
+
|
|
24
|
+
**Use this SDK if determinism is non-negotiable:**
|
|
54
25
|
|
|
55
|
-
|
|
26
|
+
- **On-chain generative art** — NFTs, archival renders, mint verification
|
|
27
|
+
- **Procedural games** — Open-world generation, replay systems, save states
|
|
28
|
+
- **Simulations** — Physics, agent-based models, reproducible experiments
|
|
29
|
+
- **Finance research** — Backtesting, Monte Carlo, reproducible analysis
|
|
30
|
+
- **Education labs** — Repeatable demonstrations, grading consistency
|
|
56
31
|
|
|
57
|
-
**
|
|
32
|
+
**Skip this SDK if you're building:**
|
|
58
33
|
|
|
59
|
-
|
|
34
|
+
- CRUD apps
|
|
35
|
+
- Dashboards
|
|
36
|
+
- E-commerce
|
|
37
|
+
- Typical web applications without reproducibility requirements
|
|
60
38
|
|
|
61
|
-
|
|
39
|
+
For most applications, seeded randomness is unnecessary complexity.
|
|
62
40
|
|
|
63
41
|
---
|
|
64
42
|
|
|
65
|
-
##
|
|
43
|
+
## For AI Coding Agents (Replit / Lovable / Claude Code)
|
|
66
44
|
|
|
67
|
-
**
|
|
45
|
+
**Use `createRuntime({ seed, strict: true })` for deterministic execution.**
|
|
68
46
|
|
|
69
|
-
|
|
47
|
+
```typescript
|
|
48
|
+
import { createRuntime } from "@nexart/codemode-sdk";
|
|
70
49
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
50
|
+
const runtime = createRuntime({
|
|
51
|
+
seed: "my-artwork-42",
|
|
52
|
+
vars: [50, 75, 25],
|
|
53
|
+
strict: true, // Throws on Math.random, Date.now, etc.
|
|
54
|
+
mode: "static"
|
|
55
|
+
});
|
|
74
56
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
57
|
+
// Deterministic APIs
|
|
58
|
+
const value = runtime.random(); // [0, 1)
|
|
59
|
+
const intVal = runtime.randomInt(0, 10); // integer in range
|
|
60
|
+
const n = runtime.noise(x, y); // Perlin noise
|
|
78
61
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
62
|
+
// Verification
|
|
63
|
+
console.log(runtime.digest()); // Stable hash
|
|
64
|
+
console.log(runtime.getState()); // Canonical state snapshot
|
|
65
|
+
```
|
|
83
66
|
|
|
84
|
-
|
|
85
|
-
-
|
|
86
|
-
- API
|
|
87
|
-
- Existing Node.js code continues to work
|
|
67
|
+
**Strict mode throws actionable errors:**
|
|
68
|
+
- `NEXART_STRICT: Non-deterministic API used: Math.random. Use runtime.random() instead.`
|
|
69
|
+
- `NEXART_STRICT: Non-deterministic API used: Date.now. Pass time as an input or use deterministic counters.`
|
|
88
70
|
|
|
89
71
|
---
|
|
90
72
|
|
|
91
|
-
##
|
|
92
|
-
|
|
93
|
-
**Licensing & Builder Identity Scaffolding (Metadata Only)**
|
|
73
|
+
## Where This Fits
|
|
94
74
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
-
|
|
104
|
-
|
|
75
|
+
```
|
|
76
|
+
┌─────────────────────────────────────────────────────────┐
|
|
77
|
+
│ Your Application │
|
|
78
|
+
│ (React, Canvas, Three.js, game engine, simulation) │
|
|
79
|
+
└────────────────────────┬────────────────────────────────┘
|
|
80
|
+
│
|
|
81
|
+
▼
|
|
82
|
+
┌─────────────────────────────────────────────────────────┐
|
|
83
|
+
│ @nexart/codemode-sdk │
|
|
84
|
+
│ Deterministic runtime layer │
|
|
85
|
+
│ - Seeded PRNG (Mulberry32) │
|
|
86
|
+
│ - Seeded noise (Perlin) │
|
|
87
|
+
│ - Strict mode enforcement │
|
|
88
|
+
│ - State snapshots + digest │
|
|
89
|
+
└────────────────────────┬────────────────────────────────┘
|
|
90
|
+
│
|
|
91
|
+
▼
|
|
92
|
+
┌─────────────────────────────────────────────────────────┐
|
|
93
|
+
│ Output │
|
|
94
|
+
│ - Deterministic result │
|
|
95
|
+
│ - Verification digest │
|
|
96
|
+
│ - Replay state │
|
|
97
|
+
└─────────────────────────────────────────────────────────┘
|
|
98
|
+
```
|
|
105
99
|
|
|
106
|
-
|
|
107
|
-
- SDK positioned as "canonical execution surface"
|
|
108
|
-
- Explicit determinism guarantees documented
|
|
109
|
-
- Real product references (ByX, Frontierra)
|
|
100
|
+
The SDK sits between your UI/framework and your output. It does not render, does not manage state, does not touch the DOM. It provides deterministic primitives.
|
|
110
101
|
|
|
111
102
|
---
|
|
112
103
|
|
|
113
|
-
##
|
|
114
|
-
|
|
115
|
-
**The NexArt Code Mode SDK guarantees deterministic output.**
|
|
104
|
+
## Why Not Roll Your Own?
|
|
116
105
|
|
|
117
|
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
- Same `vars` array
|
|
121
|
-
- Same `width` and `height`
|
|
122
|
-
- Same `mode`
|
|
106
|
+
**What's easy:**
|
|
107
|
+
- Seeded PRNG (dozens of implementations exist)
|
|
108
|
+
- Noise libraries (simplex, Perlin, available everywhere)
|
|
123
109
|
|
|
124
|
-
|
|
110
|
+
**What's hard:**
|
|
111
|
+
- **Cross-environment stability** — Same seed producing same sequence across browser versions, Node.js versions, bundlers, and platforms
|
|
112
|
+
- **Strict enforcement** — Actually blocking `Math.random()` and `Date.now()` during execution, with actionable error messages
|
|
113
|
+
- **Replay and verification** — Canonical state snapshots that can reconstruct execution
|
|
114
|
+
- **Long-term drift resistance** — Guaranteeing identical output years later, not just today
|
|
125
115
|
|
|
126
|
-
|
|
116
|
+
If you need a quick seeded random, use any PRNG. If you need guaranteed reproducibility across time, environments, and verification systems — that's what this SDK provides.
|
|
127
117
|
|
|
128
|
-
|
|
118
|
+
---
|
|
129
119
|
|
|
130
|
-
|
|
131
|
-
|---------|--------|-------------|
|
|
132
|
-
| `Math.random()` | Unseeded randomness | BLOCKED |
|
|
133
|
-
| `Date.now()` | Time-based entropy | BLOCKED |
|
|
134
|
-
| `new Date()` | Time-based entropy | BLOCKED |
|
|
135
|
-
| `performance.now()` | Timing entropy | BLOCKED |
|
|
136
|
-
| `crypto.getRandomValues()` | Crypto randomness | BLOCKED |
|
|
137
|
-
| `fetch()` | External IO | BLOCKED |
|
|
138
|
-
| External imports | Uncontrolled code | BLOCKED |
|
|
120
|
+
## Determinism Contract
|
|
139
121
|
|
|
140
|
-
|
|
122
|
+
✅ **Guaranteed:**
|
|
123
|
+
- Same `sdkVersion` + `seed` + `vars` → identical output
|
|
124
|
+
- Cross-environment stable digest (browser, Node.js, CI)
|
|
125
|
+
- Seeded PRNG via `runtime.random()` (Mulberry32)
|
|
126
|
+
- Seeded noise via `runtime.noise()` (Perlin)
|
|
141
127
|
|
|
142
|
-
|
|
128
|
+
❌ **Forbidden (blocked in strict mode):**
|
|
129
|
+
- `Math.random()` — use `runtime.random()` instead
|
|
130
|
+
- `Date.now()` — pass time as input or use frame counters
|
|
131
|
+
- `performance.now()` — use deterministic timing
|
|
132
|
+
- External IO during deterministic runs
|
|
143
133
|
|
|
144
|
-
|
|
134
|
+
---
|
|
145
135
|
|
|
146
|
-
|
|
147
|
-
npx tsx scripts/check-determinism.ts
|
|
148
|
-
```
|
|
136
|
+
## Feature Comparison
|
|
149
137
|
|
|
150
|
-
|
|
138
|
+
| Feature | Plain PRNG | This SDK |
|
|
139
|
+
|---------|-----------|----------|
|
|
140
|
+
| Seeded random | ✅ | ✅ |
|
|
141
|
+
| Seeded noise | ❌ (separate lib) | ✅ built-in |
|
|
142
|
+
| Strict mode (blocks entropy) | ❌ | ✅ |
|
|
143
|
+
| Canonical state snapshot | ❌ | ✅ `getState()` |
|
|
144
|
+
| Cross-env stable digest | ❌ | ✅ `digest()` |
|
|
145
|
+
| VAR protocol (0-100 inputs) | ❌ | ✅ |
|
|
146
|
+
| Replay/verification | Manual | Built-in |
|
|
147
|
+
| Error messages for agents | ❌ | ✅ actionable |
|
|
151
148
|
|
|
152
149
|
---
|
|
153
150
|
|
|
154
|
-
##
|
|
151
|
+
## Environment Imports
|
|
155
152
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
153
|
+
| Environment | Import Path |
|
|
154
|
+
|-------------|-------------|
|
|
155
|
+
| Browser / Vite / Next.js / React | `import { createRuntime } from "@nexart/codemode-sdk"` |
|
|
156
|
+
| Node.js (general use) | `import { createRuntime } from "@nexart/codemode-sdk"` |
|
|
157
|
+
| Node.js server rendering (canvas) | `import { executeCodeMode } from "@nexart/codemode-sdk/node"` |
|
|
159
158
|
|
|
160
|
-
|
|
159
|
+
**The default import is browser-safe.** Node-only features require explicit `/node` import.
|
|
161
160
|
|
|
162
|
-
|
|
161
|
+
---
|
|
163
162
|
|
|
164
|
-
|
|
163
|
+
## Used By
|
|
165
164
|
|
|
166
|
-
-
|
|
165
|
+
- **NexArt** — Generative art platform
|
|
166
|
+
- **ByX** — Curated collections
|
|
167
|
+
- **Frontierra** — External builder integration
|
|
167
168
|
|
|
168
|
-
|
|
169
|
+
These are examples — the SDK is designed for any system requiring deterministic execution.
|
|
169
170
|
|
|
170
171
|
---
|
|
171
172
|
|
|
172
|
-
##
|
|
173
|
+
## Protocol Stability
|
|
173
174
|
|
|
174
|
-
|
|
175
|
+
| Property | Value |
|
|
176
|
+
|----------|-------|
|
|
177
|
+
| Protocol Version | v1.2.0 |
|
|
178
|
+
| Status | **STABLE** |
|
|
179
|
+
| SDK Version | 1.8.1 |
|
|
175
180
|
|
|
176
|
-
|
|
177
|
-
- **Pixel System**: `loadPixels()`, `updatePixels()`, `pixels[]`, `get(x, y)`, `set(x, y, color)`
|
|
178
|
-
- **Graphics System**: `createGraphics(w, h)`, `image(pg, x, y, w, h)` for offscreen rendering
|
|
179
|
-
- **totalFrames**: Now injected into Loop Mode runtime
|
|
181
|
+
**Core protocol surface is frozen. Breaking changes require v2.0.0.**
|
|
180
182
|
|
|
181
|
-
|
|
183
|
+
The following are locked in v1.x:
|
|
184
|
+
- Execution model (Static and Loop modes)
|
|
185
|
+
- VAR[0..9] specification
|
|
186
|
+
- Determinism guarantee
|
|
187
|
+
- Time semantics (t, frameCount, time, tGlobal, totalFrames)
|
|
188
|
+
- Random and noise behavior
|
|
189
|
+
- Forbidden patterns list
|
|
182
190
|
|
|
183
|
-
|
|
191
|
+
---
|
|
184
192
|
|
|
185
|
-
|
|
186
|
-
- **Vector Helpers**: `vec`, `vecAdd`, `vecSub`, `vecMult`, `vecMag`, `vecNorm`, `vecDist`
|
|
187
|
-
- **Shape Helpers**: `polygon()`, `star()`
|
|
188
|
-
- **Blend Modes**: `blendMode(NORMAL|ADD|MULTIPLY|SCREEN)`
|
|
189
|
-
- **Noise Extensions**: `fbm()`, `ridgedNoise()`, `curlNoise()`
|
|
190
|
-
- **Easing Functions**: `easeIn`, `easeOut`, `easeInOut`, `easeCubic`, `easeExpo`
|
|
193
|
+
## Licensing
|
|
191
194
|
|
|
192
|
-
|
|
195
|
+
Free for personal projects, experiments, research, and open-source.
|
|
193
196
|
|
|
194
|
-
|
|
195
|
-
- Added text system: `text()`, `textSize()`, `textFont()`, `textAlign()`, `textWidth()`
|
|
196
|
-
- Added `sq()`, `int()`, `TAU`, arc mode constants
|
|
197
|
+
Commercial production deployments require a license.
|
|
197
198
|
|
|
198
|
-
|
|
199
|
+
See [COMMERCIAL.md](./COMMERCIAL.md) for details.
|
|
199
200
|
|
|
200
|
-
|
|
201
|
-
- All randomness is now deterministic
|
|
201
|
+
---
|
|
202
202
|
|
|
203
|
-
##
|
|
203
|
+
## Installation
|
|
204
204
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
- **Determinism Guarantee**: Same code + seed + vars = identical output
|
|
205
|
+
```bash
|
|
206
|
+
npm install @nexart/codemode-sdk
|
|
207
|
+
```
|
|
209
208
|
|
|
210
209
|
---
|
|
211
210
|
|
|
212
|
-
##
|
|
213
|
-
|
|
214
|
-
This SDK provides the **canonical runtime** for executing p5.js-style generative art:
|
|
215
|
-
|
|
216
|
-
- **Static Mode**: Executes `setup()` only, outputs PNG
|
|
217
|
-
- **Loop Mode**: Frame-authoritative rendering, outputs MP4
|
|
218
|
-
- **Deterministic**: Seed-controlled randomness, no external state
|
|
219
|
-
- **Protocol-Compliant**: All outputs include verification metadata
|
|
211
|
+
## Runtime API
|
|
220
212
|
|
|
221
|
-
|
|
213
|
+
### `createRuntime(options)`
|
|
222
214
|
|
|
223
|
-
|
|
215
|
+
Create a deterministic runtime instance.
|
|
224
216
|
|
|
225
|
-
|
|
217
|
+
```typescript
|
|
218
|
+
import { createRuntime } from "@nexart/codemode-sdk";
|
|
219
|
+
|
|
220
|
+
const runtime = createRuntime({
|
|
221
|
+
seed: "my-seed",
|
|
222
|
+
vars: [50, 75],
|
|
223
|
+
strict: true,
|
|
224
|
+
mode: "static",
|
|
225
|
+
metadata: { artist: "demo" }
|
|
226
|
+
});
|
|
226
227
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
228
|
+
runtime.random(); // Deterministic PRNG
|
|
229
|
+
runtime.randomInt(0, 100); // Deterministic integer
|
|
230
|
+
runtime.noise(x, y, z); // Deterministic Perlin noise
|
|
231
|
+
runtime.digest(); // Stable hash for verification
|
|
232
|
+
runtime.getState(); // Canonical state snapshot
|
|
233
|
+
runtime.run(() => { ... }); // Execute with strict enforcement
|
|
234
|
+
```
|
|
231
235
|
|
|
232
|
-
|
|
236
|
+
### Strict Mode
|
|
233
237
|
|
|
234
|
-
|
|
238
|
+
When `strict: true`, the runtime intercepts non-deterministic APIs during `run()`:
|
|
235
239
|
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
|
|
240
|
+
```typescript
|
|
241
|
+
runtime.run(() => {
|
|
242
|
+
Math.random(); // Throws: NEXART_STRICT: Non-deterministic API used
|
|
243
|
+
});
|
|
239
244
|
```
|
|
240
245
|
|
|
246
|
+
Strict mode:
|
|
247
|
+
- Only applies during `runtime.run()` — non-invasive
|
|
248
|
+
- Does NOT globally mutate your application
|
|
249
|
+
- Provides actionable error messages
|
|
250
|
+
|
|
241
251
|
---
|
|
242
252
|
|
|
243
|
-
## Browser Usage
|
|
253
|
+
## Browser Usage
|
|
244
254
|
|
|
245
|
-
For Vite, React, Next.js, or any browser environment
|
|
255
|
+
For Vite, React, Next.js, or any browser environment:
|
|
246
256
|
|
|
247
257
|
```typescript
|
|
248
258
|
import {
|
|
259
|
+
createRuntime,
|
|
249
260
|
runLoopMode,
|
|
250
261
|
cancelLoopMode,
|
|
251
262
|
createP5Runtime,
|
|
252
263
|
validateCodeModeSource,
|
|
253
|
-
|
|
254
|
-
DEFAULT_CONFIG,
|
|
255
|
-
} from '@nexart/codemode-sdk/browser';
|
|
264
|
+
} from '@nexart/codemode-sdk';
|
|
256
265
|
```
|
|
257
266
|
|
|
258
|
-
**What's included
|
|
259
|
-
-
|
|
267
|
+
**What's included:**
|
|
268
|
+
- Runtime API (createRuntime)
|
|
260
269
|
- P5 runtime (createP5Runtime, injectTimeVariables, injectProtocolVariables)
|
|
261
270
|
- Loop engine (runLoopMode, cancelLoopMode)
|
|
262
271
|
- Execution sandbox (FORBIDDEN_APIS, createSafeMath)
|
|
263
272
|
- Validation (validateCodeModeSource)
|
|
264
|
-
- Builder manifest (registerBuilderManifest)
|
|
265
273
|
|
|
266
274
|
**What's NOT included (Node.js only):**
|
|
267
|
-
- `executeCodeMode` —
|
|
268
|
-
- `runStaticMode` — Requires Node.js canvas
|
|
269
|
-
|
|
270
|
-
For static rendering in browser apps, use your server-side API endpoint.
|
|
275
|
+
- `executeCodeMode` — Requires Node.js canvas
|
|
276
|
+
- `runStaticMode` — Requires Node.js canvas
|
|
271
277
|
|
|
272
278
|
---
|
|
273
279
|
|
|
274
|
-
## Node.js Usage
|
|
280
|
+
## Node.js Usage
|
|
275
281
|
|
|
276
|
-
For server-side rendering, oracles, or CLI tools
|
|
282
|
+
For server-side rendering, oracles, or CLI tools:
|
|
277
283
|
|
|
278
284
|
```typescript
|
|
279
285
|
import {
|
|
@@ -284,27 +290,20 @@ import {
|
|
|
284
290
|
} from '@nexart/codemode-sdk/node';
|
|
285
291
|
```
|
|
286
292
|
|
|
287
|
-
**What's included in `@nexart/codemode-sdk/node`:**
|
|
288
|
-
- Everything from the browser entry
|
|
289
|
-
- `executeCodeMode` — Canonical execution API
|
|
290
|
-
- `runStaticMode` — Node.js static rendering (requires `canvas` package)
|
|
291
|
-
|
|
292
293
|
**Requirements:**
|
|
293
294
|
- Node.js 18+
|
|
294
|
-
- `canvas` package
|
|
295
|
+
- `canvas` package for static mode
|
|
295
296
|
|
|
296
297
|
---
|
|
297
298
|
|
|
298
|
-
## Canonical API
|
|
299
|
-
|
|
300
|
-
### `executeCodeMode(input: ExecuteCodeModeInput): Promise<ExecuteCodeModeResult>`
|
|
299
|
+
## Canonical Execution API
|
|
301
300
|
|
|
302
|
-
|
|
301
|
+
### `executeCodeMode(input): Promise<Result>`
|
|
303
302
|
|
|
304
|
-
|
|
303
|
+
For systems requiring p5.js-style execution with full protocol metadata:
|
|
305
304
|
|
|
306
305
|
```typescript
|
|
307
|
-
import { executeCodeMode } from '@nexart/codemode-sdk';
|
|
306
|
+
import { executeCodeMode } from '@nexart/codemode-sdk/node';
|
|
308
307
|
|
|
309
308
|
const result = await executeCodeMode({
|
|
310
309
|
source: `
|
|
@@ -322,180 +321,24 @@ const result = await executeCodeMode({
|
|
|
322
321
|
mode: 'static'
|
|
323
322
|
});
|
|
324
323
|
|
|
325
|
-
//
|
|
326
|
-
console.log(result.
|
|
327
|
-
console.log(result.metadata.engine); // 'codemode'
|
|
328
|
-
console.log(result.metadata.protocolVersion); // '1.2.0'
|
|
329
|
-
console.log(result.metadata.deterministic); // true
|
|
330
|
-
console.log(result.image); // PNG Blob
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
### Input Parameters
|
|
334
|
-
|
|
335
|
-
| Parameter | Type | Required | Description |
|
|
336
|
-
|-----------|------|----------|-------------|
|
|
337
|
-
| `source` | `string` | ✅ | Code with setup() and optional draw() |
|
|
338
|
-
| `width` | `number` | ✅ | Canvas width in pixels |
|
|
339
|
-
| `height` | `number` | ✅ | Canvas height in pixels |
|
|
340
|
-
| `seed` | `number` | ✅ | Seed for deterministic randomness |
|
|
341
|
-
| `vars` | `number[]` | ❌ | VAR[0..9] values (0-100), defaults to all zeros |
|
|
342
|
-
| `mode` | `'static' \| 'loop'` | ✅ | Execution mode |
|
|
343
|
-
| `totalFrames` | `number` | ⚠️ | Required for loop mode |
|
|
344
|
-
|
|
345
|
-
### Result Structure
|
|
346
|
-
|
|
347
|
-
```typescript
|
|
348
|
-
interface ExecuteCodeModeResult {
|
|
349
|
-
image?: Blob; // Static mode: PNG
|
|
350
|
-
video?: Blob; // Loop mode: MP4
|
|
351
|
-
frames?: ImageData[]; // Optional: raw frame data
|
|
352
|
-
metadata: {
|
|
353
|
-
protocol: 'nexart';
|
|
354
|
-
engine: 'codemode';
|
|
355
|
-
protocolVersion: '1.0.0';
|
|
356
|
-
phase: 1;
|
|
357
|
-
deterministic: true;
|
|
358
|
-
seed: number;
|
|
359
|
-
vars: number[];
|
|
360
|
-
width: number;
|
|
361
|
-
height: number;
|
|
362
|
-
mode: 'static' | 'loop';
|
|
363
|
-
totalFrames?: number;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
324
|
+
console.log(result.metadata.deterministic); // true
|
|
325
|
+
console.log(result.image); // PNG Blob
|
|
366
326
|
```
|
|
367
327
|
|
|
368
328
|
---
|
|
369
329
|
|
|
370
|
-
## Legacy API
|
|
371
|
-
|
|
372
|
-
> ⚠️ **Note**: The `createEngine()` API is still supported but new implementations should use `executeCodeMode()`.
|
|
373
|
-
|
|
374
|
-
### `createEngine(config: EngineConfig): Engine`
|
|
375
|
-
|
|
376
|
-
Create a rendering engine instance.
|
|
377
|
-
|
|
378
|
-
```typescript
|
|
379
|
-
import { createEngine } from './codemode';
|
|
380
|
-
|
|
381
|
-
const engine = createEngine({
|
|
382
|
-
mode: 'static', // 'static' | 'loop'
|
|
383
|
-
width: 1950, // Optional, default: 1950
|
|
384
|
-
height: 2400, // Optional, default: 2400
|
|
385
|
-
duration: 2, // Loop mode only, 1-4 seconds
|
|
386
|
-
fps: 30, // Loop mode only, default: 30
|
|
387
|
-
});
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
### `engine.run(options: RunOptions): Promise<void>`
|
|
391
|
-
|
|
392
|
-
Execute code and produce output.
|
|
393
|
-
|
|
394
|
-
```typescript
|
|
395
|
-
await engine.run({
|
|
396
|
-
code: `
|
|
397
|
-
function setup() {
|
|
398
|
-
background(255);
|
|
399
|
-
fill(0);
|
|
400
|
-
// Use VAR for external control
|
|
401
|
-
let size = map(VAR[0], 0, 100, 50, 200);
|
|
402
|
-
ellipse(width/2, height/2, size);
|
|
403
|
-
}
|
|
404
|
-
`,
|
|
405
|
-
seed: 12345, // Optional: seed for deterministic randomness
|
|
406
|
-
vars: [50, 75, 0, 0, 0, 0, 0, 0, 0, 0], // Optional: VAR[0..9] values (0-100)
|
|
407
|
-
onPreview: (canvas) => {
|
|
408
|
-
// Optional: called with canvas after first frame
|
|
409
|
-
},
|
|
410
|
-
onProgress: (info) => {
|
|
411
|
-
// Optional: progress updates
|
|
412
|
-
console.log(info.message, info.percent + '%');
|
|
413
|
-
},
|
|
414
|
-
onComplete: (result) => {
|
|
415
|
-
// Required: called with final result
|
|
416
|
-
console.log(result.type); // 'image' | 'video'
|
|
417
|
-
console.log(result.blob); // Blob
|
|
418
|
-
},
|
|
419
|
-
onError: (error) => {
|
|
420
|
-
// Optional: called on error
|
|
421
|
-
console.error(error);
|
|
422
|
-
},
|
|
423
|
-
});
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
### Protocol Variables (VAR[0..9]) — Protocol v1.0.0
|
|
427
|
-
|
|
428
|
-
Protocol variables are first-class inputs that control artwork parameters.
|
|
429
|
-
|
|
430
|
-
**VAR Specification (SDK v1.0.2):**
|
|
431
|
-
|
|
432
|
-
| Property | Value | Enforcement |
|
|
433
|
-
|----------|-------|-------------|
|
|
434
|
-
| Input count | 0-10 (VAR[0]..VAR[9]) | HARD — throws if > 10 |
|
|
435
|
-
| Runtime count | Always 10 | Padded with zeros |
|
|
436
|
-
| Type | finite number | HARD — throws if non-number |
|
|
437
|
-
| Range | 0-100 | HARD — throws if out of range |
|
|
438
|
-
| Mutability | Read-only | HARD — Proxy blocks writes |
|
|
439
|
-
| Injection | Before execution | Guaranteed |
|
|
440
|
-
| Lifecycle | Stable for entire render | Guaranteed |
|
|
441
|
-
| Default | All zeros | If not provided |
|
|
442
|
-
|
|
443
|
-
```typescript
|
|
444
|
-
// Pass values when running (0-10 elements)
|
|
445
|
-
await engine.run({
|
|
446
|
-
code: myCode,
|
|
447
|
-
vars: [80, 50, 25], // VAR[0]=80, VAR[1]=50, VAR[2]=25, VAR[3..9]=0
|
|
448
|
-
onComplete: (result) => { /* ... */ },
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
// Or omit entirely (all zeros)
|
|
452
|
-
await engine.run({
|
|
453
|
-
code: myCode,
|
|
454
|
-
onComplete: (result) => { /* ... */ },
|
|
455
|
-
});
|
|
456
|
-
|
|
457
|
-
// Access in sketch code
|
|
458
|
-
function setup() {
|
|
459
|
-
let density = map(VAR[0], 0, 100, 10, 200);
|
|
460
|
-
let speed = map(VAR[1], 0, 100, 0.5, 5);
|
|
461
|
-
// VAR[5] returns 0 if not provided
|
|
462
|
-
}
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
**Rules (Protocol Law):**
|
|
466
|
-
- Input accepts 0-10 elements; runtime VAR is always 10 elements
|
|
467
|
-
- VAR is injected BEFORE code execution (padded with zeros if needed)
|
|
468
|
-
- VAR values are READ-ONLY at runtime (Proxy-protected)
|
|
469
|
-
- Writing to VAR throws a protocol error
|
|
470
|
-
- Values MUST be in range 0-100 (throws if out of range)
|
|
471
|
-
- Same code + same seed + same VARs = identical output
|
|
472
|
-
|
|
473
|
-
### `engine.stop(): void`
|
|
474
|
-
|
|
475
|
-
Cancel a running render (Loop mode only).
|
|
476
|
-
|
|
477
|
-
### `engine.getConfig(): EngineConfig`
|
|
478
|
-
|
|
479
|
-
Get the resolved engine configuration.
|
|
480
|
-
|
|
481
|
-
---
|
|
482
|
-
|
|
483
330
|
## Execution Rules
|
|
484
331
|
|
|
485
332
|
### Static Mode
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
4. Time variables are all `0`
|
|
333
|
+
1. `setup()` executes once
|
|
334
|
+
2. `draw()` is NOT executed
|
|
335
|
+
3. Canvas captured as PNG
|
|
336
|
+
4. Time variables are 0
|
|
491
337
|
|
|
492
338
|
### Loop Mode
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
3. Canvas is **cleared** before each `draw()` call
|
|
497
|
-
4. If artist calls `background()` in draw, it paints over the clear
|
|
498
|
-
5. No canvas persistence between frames
|
|
339
|
+
1. `setup()` executes once
|
|
340
|
+
2. `draw()` executes per frame
|
|
341
|
+
3. Canvas cleared before each `draw()`
|
|
499
342
|
|
|
500
343
|
**Time Variables:**
|
|
501
344
|
|
|
@@ -505,277 +348,49 @@ Get the resolved engine configuration.
|
|
|
505
348
|
| `t` | float | Normalized time [0.0, 1.0) |
|
|
506
349
|
| `time` | float | Elapsed seconds |
|
|
507
350
|
| `tGlobal` | float | Alias for `t` |
|
|
351
|
+
| `totalFrames` | int | Total frames in loop |
|
|
508
352
|
|
|
509
353
|
---
|
|
510
354
|
|
|
511
|
-
## Forbidden Patterns
|
|
355
|
+
## Forbidden Patterns
|
|
512
356
|
|
|
513
|
-
The following
|
|
357
|
+
The following are rejected with `[Code Mode Protocol Error]`:
|
|
514
358
|
|
|
515
359
|
| Pattern | Reason |
|
|
516
360
|
|---------|--------|
|
|
517
|
-
| `
|
|
518
|
-
| `
|
|
519
|
-
| `
|
|
520
|
-
| `
|
|
521
|
-
| `
|
|
522
|
-
| `
|
|
523
|
-
| `
|
|
524
|
-
| `
|
|
525
|
-
| `
|
|
526
|
-
| `document.*` | DOM access
|
|
527
|
-
| `window.*` | DOM access
|
|
528
|
-
| `import` | External imports
|
|
529
|
-
| `require()` | External imports
|
|
530
|
-
|
|
531
|
-
Additionally in Loop Mode:
|
|
532
|
-
- `noLoop()` — Incompatible with frame capture
|
|
533
|
-
|
|
534
|
-
---
|
|
535
|
-
|
|
536
|
-
## Example: Static Mode
|
|
537
|
-
|
|
538
|
-
```typescript
|
|
539
|
-
import { createEngine } from './codemode';
|
|
540
|
-
|
|
541
|
-
const engine = createEngine({ mode: 'static' });
|
|
542
|
-
|
|
543
|
-
await engine.run({
|
|
544
|
-
code: `
|
|
545
|
-
function setup() {
|
|
546
|
-
background(30);
|
|
547
|
-
noStroke();
|
|
548
|
-
for (let i = 0; i < 100; i++) {
|
|
549
|
-
fill(random(255), random(255), random(255));
|
|
550
|
-
ellipse(random(width), random(height), 50);
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
`,
|
|
554
|
-
onComplete: (result) => {
|
|
555
|
-
// result.type === 'image'
|
|
556
|
-
// result.blob is a PNG Blob
|
|
557
|
-
const url = URL.createObjectURL(result.blob);
|
|
558
|
-
document.body.innerHTML = `<img src="${url}" />`;
|
|
559
|
-
},
|
|
560
|
-
});
|
|
561
|
-
```
|
|
562
|
-
|
|
563
|
-
---
|
|
564
|
-
|
|
565
|
-
## Example: Loop Mode
|
|
566
|
-
|
|
567
|
-
```typescript
|
|
568
|
-
import { createEngine } from './codemode';
|
|
569
|
-
|
|
570
|
-
const engine = createEngine({
|
|
571
|
-
mode: 'loop',
|
|
572
|
-
duration: 2, // 2 second loop
|
|
573
|
-
});
|
|
574
|
-
|
|
575
|
-
await engine.run({
|
|
576
|
-
code: `
|
|
577
|
-
function setup() {
|
|
578
|
-
// Called once
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
function draw() {
|
|
582
|
-
background(30);
|
|
583
|
-
|
|
584
|
-
// t goes from 0 to 1 over the loop duration
|
|
585
|
-
let x = width/2 + cos(t * TWO_PI) * 200;
|
|
586
|
-
let y = height/2 + sin(t * TWO_PI) * 200;
|
|
587
|
-
|
|
588
|
-
fill(255);
|
|
589
|
-
ellipse(x, y, 80);
|
|
590
|
-
}
|
|
591
|
-
`,
|
|
592
|
-
onProgress: (info) => {
|
|
593
|
-
console.log(info.message);
|
|
594
|
-
},
|
|
595
|
-
onComplete: (result) => {
|
|
596
|
-
// result.type === 'video'
|
|
597
|
-
// result.blob is an MP4 Blob
|
|
598
|
-
const url = URL.createObjectURL(result.blob);
|
|
599
|
-
document.body.innerHTML = `<video src="${url}" autoplay loop />`;
|
|
600
|
-
},
|
|
601
|
-
});
|
|
602
|
-
```
|
|
361
|
+
| `Math.random()` | Use seeded `random()` |
|
|
362
|
+
| `Date.now()` | Time-based entropy |
|
|
363
|
+
| `new Date()` | Time-based entropy |
|
|
364
|
+
| `performance.now()` | Timing entropy |
|
|
365
|
+
| `crypto.getRandomValues()` | Crypto randomness |
|
|
366
|
+
| `fetch()` | External IO |
|
|
367
|
+
| `setTimeout` | Async timing |
|
|
368
|
+
| `setInterval` | Async timing |
|
|
369
|
+
| `requestAnimationFrame` | Async timing |
|
|
370
|
+
| `document.*` | DOM access |
|
|
371
|
+
| `window.*` | DOM access |
|
|
372
|
+
| `import` | External imports |
|
|
373
|
+
| `require()` | External imports |
|
|
603
374
|
|
|
604
375
|
---
|
|
605
376
|
|
|
606
|
-
##
|
|
607
|
-
|
|
608
|
-
The SDK includes a comprehensive p5.js-like runtime with 130+ functions:
|
|
609
|
-
|
|
610
|
-
**Drawing:**
|
|
611
|
-
`background`, `clear`, `fill`, `noFill`, `stroke`, `noStroke`, `strokeWeight`, `strokeCap`, `strokeJoin`
|
|
612
|
-
|
|
613
|
-
**Shapes:**
|
|
614
|
-
`ellipse`, `circle`, `rect`, `square`, `line`, `point`, `triangle`, `quad`, `arc`, `bezier`, `curve`
|
|
615
|
-
|
|
616
|
-
**Vertex (v1.4.0):**
|
|
617
|
-
`beginShape`, `vertex`, `curveVertex`, `bezierVertex`, `endShape`
|
|
618
|
-
|
|
619
|
-
**Shape Helpers (v1.3.0):**
|
|
620
|
-
`polygon`, `star`
|
|
621
|
-
|
|
622
|
-
**Transform:**
|
|
623
|
-
`push`, `pop`, `translate`, `rotate`, `scale`, `resetMatrix`, `shearX`, `shearY`
|
|
624
|
-
|
|
625
|
-
**Color:**
|
|
626
|
-
`colorMode`, `color`, `lerpColor`, `red`, `green`, `blue`, `alpha`, `hue`, `saturation`, `brightness`
|
|
627
|
-
|
|
628
|
-
**Text:**
|
|
629
|
-
`text`, `textSize`, `textFont`, `textAlign`, `textWidth`
|
|
630
|
-
|
|
631
|
-
**Blend Modes (v1.3.0):**
|
|
632
|
-
`blendMode(NORMAL|ADD|MULTIPLY|SCREEN)`
|
|
633
|
-
|
|
634
|
-
**Pixel System (v1.4.0):**
|
|
635
|
-
`loadPixels`, `updatePixels`, `pixels[]`, `get`, `set`
|
|
636
|
-
|
|
637
|
-
**Graphics (v1.4.0):**
|
|
638
|
-
`createGraphics`, `image`
|
|
639
|
-
|
|
640
|
-
**Color Formats:**
|
|
641
|
-
All of the following are accepted by `fill()`, `stroke()`, `background()`:
|
|
642
|
-
- Grayscale: `fill(128)`, `fill(128, 127)`
|
|
643
|
-
- RGB: `fill(255, 0, 0)`, `fill(255, 0, 0, 128)`
|
|
644
|
-
- Hex: `fill('#ff0000')`, `fill('#f00')`
|
|
645
|
-
- CSS: `fill('rgb(255,0,0)')`, `fill('rgba(255,0,0,0.5)')`, `fill('hsl(180,50%,50%)')`
|
|
646
|
-
|
|
647
|
-
**Protocol Variables:**
|
|
648
|
-
`VAR` — Array of 10 values (VAR[0] through VAR[9])
|
|
649
|
-
|
|
650
|
-
**Math:**
|
|
651
|
-
`random`, `noise`, `map`, `constrain`, `lerp`, `dist`, `mag`, `norm`, `sq`, `int`, `fract`, `sign`
|
|
377
|
+
## Examples
|
|
652
378
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
**Noise Extensions (v1.3.0):**
|
|
657
|
-
`fbm`, `ridgedNoise`, `curlNoise`
|
|
658
|
-
|
|
659
|
-
**Easing (v1.3.0):**
|
|
660
|
-
`easeIn`, `easeOut`, `easeInOut`, `easeCubic`, `easeExpo`
|
|
661
|
-
|
|
662
|
-
**Trig:**
|
|
663
|
-
`sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`, `radians`, `degrees`
|
|
664
|
-
|
|
665
|
-
**Constants:**
|
|
666
|
-
`PI`, `TWO_PI`, `TAU`, `HALF_PI`, `QUARTER_PI`, `width`, `height`, `frameCount`, `totalFrames`
|
|
667
|
-
|
|
668
|
-
---
|
|
669
|
-
|
|
670
|
-
## Video Encoding
|
|
671
|
-
|
|
672
|
-
Loop Mode requires server-side video encoding. The SDK calls:
|
|
673
|
-
|
|
674
|
-
```
|
|
675
|
-
POST /api/encode-loop
|
|
676
|
-
```
|
|
677
|
-
|
|
678
|
-
Ensure your server has this endpoint available (NexArt provides this).
|
|
679
|
-
|
|
680
|
-
---
|
|
681
|
-
|
|
682
|
-
## Files
|
|
683
|
-
|
|
684
|
-
```
|
|
685
|
-
sdk/codemode/
|
|
686
|
-
├── entry/
|
|
687
|
-
│ ├── browser.ts # Browser-safe entry point (v1.7.0)
|
|
688
|
-
│ └── node.ts # Node.js entry point (v1.7.0)
|
|
689
|
-
├── index.ts # Main export (app integration layer)
|
|
690
|
-
├── core-index.ts # Core runtime exports
|
|
691
|
-
├── execute.ts # executeCodeMode canonical entry point
|
|
692
|
-
├── engine.ts # createEngine entry point (legacy)
|
|
693
|
-
├── types.ts # TypeScript types
|
|
694
|
-
├── static-engine.ts # Static mode implementation (Node.js)
|
|
695
|
-
├── loop-engine.ts # Loop mode implementation (browser)
|
|
696
|
-
├── p5-runtime.ts # p5.js-like runtime
|
|
697
|
-
├── execution-sandbox.ts # Determinism enforcement
|
|
698
|
-
├── builder-manifest.ts # Builder manifest (write-only)
|
|
699
|
-
├── CHANGELOG.md # Version history
|
|
700
|
-
└── README.md # This file
|
|
379
|
+
```bash
|
|
380
|
+
npm run example:basic # Basic usage
|
|
381
|
+
npm run example:verify # Determinism verification
|
|
701
382
|
```
|
|
702
383
|
|
|
703
384
|
---
|
|
704
385
|
|
|
705
|
-
##
|
|
386
|
+
## Changelog
|
|
706
387
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
Copyright (c) 2024-2026 NexArt
|
|
388
|
+
See [CHANGELOG.md](./CHANGELOG.md) for version history.
|
|
710
389
|
|
|
711
390
|
---
|
|
712
391
|
|
|
713
|
-
##
|
|
714
|
-
|
|
715
|
-
This SDK is designed for use by:
|
|
716
|
-
|
|
717
|
-
- **NexArt App**: The main generative art platform
|
|
718
|
-
- **ByX**: Curated collection system
|
|
719
|
-
- **External Builders**: Any platform consuming NexArt Code Mode
|
|
720
|
-
|
|
721
|
-
### Integration Example
|
|
722
|
-
|
|
723
|
-
```typescript
|
|
724
|
-
import { executeCodeMode } from '@nexart/codemode-sdk';
|
|
725
|
-
|
|
726
|
-
// Execute with explicit VAR values
|
|
727
|
-
const result = await executeCodeMode({
|
|
728
|
-
source: artistCode,
|
|
729
|
-
width: 1950,
|
|
730
|
-
height: 2400,
|
|
731
|
-
seed: 12345,
|
|
732
|
-
vars: [50, 75, 25, 0, 0, 0, 0, 0, 0, 0], // Exactly 10 values
|
|
733
|
-
mode: 'static'
|
|
734
|
-
});
|
|
735
|
-
|
|
736
|
-
// Result includes full protocol metadata for verification
|
|
737
|
-
const { image, metadata } = result;
|
|
738
|
-
console.log(metadata.protocolVersion); // '1.2.0'
|
|
739
|
-
console.log(metadata.deterministic); // true
|
|
740
|
-
```
|
|
741
|
-
|
|
742
|
-
### Error Handling
|
|
743
|
-
|
|
744
|
-
All protocol violations throw descriptive errors:
|
|
745
|
-
|
|
746
|
-
```typescript
|
|
747
|
-
try {
|
|
748
|
-
await executeCodeMode({ ... });
|
|
749
|
-
} catch (error) {
|
|
750
|
-
// "[Code Mode Protocol Error] VAR array must have exactly 10 elements, got 5"
|
|
751
|
-
// "[Code Mode Protocol Error] Forbidden pattern: Math.random()"
|
|
752
|
-
console.error(error.message);
|
|
753
|
-
}
|
|
754
|
-
```
|
|
755
|
-
|
|
756
|
-
---
|
|
757
|
-
|
|
758
|
-
## Frozen Execution Guarantees — v1.0.0
|
|
759
|
-
|
|
760
|
-
The following guarantees are LOCKED and will not change in v1.x:
|
|
761
|
-
|
|
762
|
-
| Guarantee | Description |
|
|
763
|
-
|-----------|-------------|
|
|
764
|
-
| Determinism | Same code + same seed + same VARs = identical output |
|
|
765
|
-
| Static Mode | `setup()` only, single PNG output |
|
|
766
|
-
| Loop Mode | Frame-authoritative, `draw()` per frame, MP4 output |
|
|
767
|
-
| Time Semantics | `t` ∈ [0,1), `frameCount` ∈ [0,totalFrames), `time` in seconds |
|
|
768
|
-
| Random | Seeded Mulberry32 PRNG via `random()` |
|
|
769
|
-
| Noise | Seeded Perlin noise via `noise()` |
|
|
770
|
-
| Canvas | Pre-initialized, no `createCanvas()` |
|
|
771
|
-
| VAR | Exactly 10 read-only protocol variables |
|
|
772
|
-
| Forbidden Patterns | 13 patterns rejected (see above) |
|
|
773
|
-
|
|
774
|
-
---
|
|
392
|
+
## About
|
|
775
393
|
|
|
776
|
-
|
|
394
|
+
This SDK is a reference implementation of a deterministic execution protocol designed for replay, verification, and long-term stability.
|
|
777
395
|
|
|
778
|
-
|
|
779
|
-
- WebGL/3D rendering support
|
|
780
|
-
- GIF output option
|
|
781
|
-
- GSL v1 SDK (protocol layer) — separate package
|
|
396
|
+
It prioritizes correctness and reproducibility over features.
|