@idle-screens/schema 2.2.0 → 2.3.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/FORMAT.md +157 -36
- package/dist/index.d.ts +458 -25
- package/dist/index.js +1777 -347
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/saver-spec.schema.json +185 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idle-screens/schema",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Declarative, agent-authorable saver format for idle-screens: validate a data spec, then compile it into a runnable, seeded, flash-safe SaverPlugin.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Shawn Partridge",
|
package/saver-spec.schema.json
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
"seed": { "type": "number", "description": "Deterministic RNG seed. Same spec + same seed = identical frames. Falls back to the host's seed." },
|
|
14
14
|
"motionIntensity": { "enum": ["calm", "moderate", "energetic"], "description": "Advisory intensity for capability/reduced-motion gating." },
|
|
15
15
|
"units": { "enum": ["px", "viewport"], "description": "Dimensional unit system. 'viewport' = all sizes/speeds/distances are fractions of min(w,h)." },
|
|
16
|
+
"referenceViewport": { "type": "number", "minimum": 100, "maximum": 8640, "description": "Resolution the spec was designed at (default 1080). Entity counts density-scale above it." },
|
|
17
|
+
"ghosting": { "type": "number", "minimum": 0, "maximum": 0.95, "description": "Frame persistence 0..0.95: each frame composites over a faded copy of the last, so moving entities smear (Mystify trails, long-exposure light). Flash-safe — only smooths luminance. Seeks stay deterministic via a fixed-step warm-up replay." },
|
|
16
18
|
"background": { "$ref": "#/definitions/background" },
|
|
17
19
|
"layers": {
|
|
18
20
|
"type": "array",
|
|
@@ -115,7 +117,7 @@
|
|
|
115
117
|
"wrap": { "type": "boolean", "description": "Wrap to the opposite edge when leaving the viewport. Default true." },
|
|
116
118
|
"flip": { "type": "boolean", "description": "Flip the sprite horizontally to face its heading. Default false." },
|
|
117
119
|
"alpha": { "$ref": "#/definitions/range01", "description": "Per-entity opacity range. Default [1, 1]." },
|
|
118
|
-
"blend": { "
|
|
120
|
+
"blend": { "enum": ["lighter", "screen", "multiply"], "description": "Compositing: 'lighter' = additive glow, 'screen' = gentle additive for pale backgrounds, 'multiply' = darkening (shadows). Omit for normal source-over." },
|
|
119
121
|
"region": {
|
|
120
122
|
"type": "object",
|
|
121
123
|
"additionalProperties": false,
|
|
@@ -131,7 +133,17 @@
|
|
|
131
133
|
"additionalProperties": false,
|
|
132
134
|
"properties": {
|
|
133
135
|
"amp": { "type": "number", "exclusiveMinimum": 0, "maximum": 0.5, "description": "Opacity breathing amplitude, capped at 0.5." },
|
|
134
|
-
"period": { "type": "number", "minimum": 500, "description": "Breathing period in ms; floor of 500 (max 2 Hz — flash-safety)." }
|
|
136
|
+
"period": { "type": "number", "minimum": 500, "description": "Breathing period in ms; floor of 500 (max 2 Hz — flash-safety)." },
|
|
137
|
+
"wave": {
|
|
138
|
+
"type": "object",
|
|
139
|
+
"required": ["wavelength"],
|
|
140
|
+
"additionalProperties": false,
|
|
141
|
+
"properties": {
|
|
142
|
+
"wavelength": { "type": "number", "exclusiveMinimum": 0, "description": "Spatial wavelength (px or viewport-units)." },
|
|
143
|
+
"angle": { "type": "number", "description": "Propagation direction in degrees (0 = rightward). Default 0." }
|
|
144
|
+
},
|
|
145
|
+
"description": "Derive each entity's phase from its position: breathing becomes a traveling wave across the field (ripples, wind through grass). Neighbors are out of phase by construction — still flash-safe."
|
|
146
|
+
}
|
|
135
147
|
},
|
|
136
148
|
"description": "Sinusoidal opacity breathing. Per-entity seeded phase — a layer can never strobe in unison."
|
|
137
149
|
},
|
|
@@ -176,9 +188,46 @@
|
|
|
176
188
|
"maxDist": { "type": "number", "exclusiveMinimum": 0, "description": "Maximum link distance (px or viewport-units)." },
|
|
177
189
|
"color": { "$ref": "#/definitions/hexColor", "description": "Link color. Defaults to per-entity color." },
|
|
178
190
|
"alpha": { "type": "number", "minimum": 0, "maximum": 1, "description": "Link opacity. Defaults to entity alpha." },
|
|
179
|
-
"width": { "type": "number", "exclusiveMinimum": 0, "description": "Stroke width (px or viewport-units). Default 1." }
|
|
191
|
+
"width": { "type": "number", "exclusiveMinimum": 0, "description": "Stroke width (px or viewport-units). Default 1." },
|
|
192
|
+
"mode": { "enum": ["nearest", "chain", "random"], "description": "'nearest' (default) k-nearest within maxDist; 'chain' connects entities in order (Mystify polygons — ignores k/maxDist); 'random' a fixed deterministic wiring filtered by maxDist." },
|
|
193
|
+
"falloff": { "type": "boolean", "description": "Fade link alpha with distance/maxDist — removes pop-in at the cutoff." },
|
|
194
|
+
"closed": { "type": "boolean", "description": "Chain mode: join the last entity back to the first (closed polygon)." }
|
|
180
195
|
},
|
|
181
|
-
"description": "Draw lines
|
|
196
|
+
"description": "Draw lines between entities. The layer's entity count (count field) must be <= 200 for performance."
|
|
197
|
+
},
|
|
198
|
+
"layout": {
|
|
199
|
+
"type": "object",
|
|
200
|
+
"required": ["type"],
|
|
201
|
+
"additionalProperties": false,
|
|
202
|
+
"properties": {
|
|
203
|
+
"type": { "const": "grid" },
|
|
204
|
+
"columns": { "type": "integer", "minimum": 1, "maximum": 100, "description": "Grid columns. Default: aspect-fit square-ish grid." },
|
|
205
|
+
"jitter": {
|
|
206
|
+
"oneOf": [
|
|
207
|
+
{ "type": "number", "minimum": 0, "maximum": 1 },
|
|
208
|
+
{
|
|
209
|
+
"type": "object",
|
|
210
|
+
"additionalProperties": false,
|
|
211
|
+
"properties": {
|
|
212
|
+
"x": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
213
|
+
"y": { "type": "number", "minimum": 0, "maximum": 1 }
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
],
|
|
217
|
+
"description": "Seeded per-entity offset as a fraction of cell size (scalar or per-axis). { y: 1 } keeps columns crisp while scattering vertically (Matrix rain). Default 0."
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
"description": "Place entities on a grid (row-major, within region) instead of random scatter — Matrix columns, LED walls, uniform dot fields."
|
|
221
|
+
},
|
|
222
|
+
"life": {
|
|
223
|
+
"type": "object",
|
|
224
|
+
"additionalProperties": false,
|
|
225
|
+
"properties": {
|
|
226
|
+
"enter": { "type": "number", "minimum": 0, "description": "Layer fades in starting at this time (ms)." },
|
|
227
|
+
"exit": { "type": "number", "minimum": 0, "description": "Layer fades out starting at this time (ms). Must be > enter." },
|
|
228
|
+
"fade": { "type": "number", "minimum": 0, "description": "Fade ramp duration in ms. Default 1000." }
|
|
229
|
+
},
|
|
230
|
+
"description": "Layer lifecycle for act structure (stars first, dancers at t=3000). Pure function of t — deterministic and seekable."
|
|
182
231
|
}
|
|
183
232
|
},
|
|
184
233
|
"if": { "required": ["position"] },
|
|
@@ -220,11 +269,61 @@
|
|
|
220
269
|
"radius": { "$ref": "#/definitions/positiveRange" },
|
|
221
270
|
"color": { "$ref": "#/definitions/hexColor" },
|
|
222
271
|
"soft": { "type": "boolean", "description": "Radial falloff (glow orb) instead of a hard disc." },
|
|
223
|
-
"colors": { "type": "array", "minItems": 1, "items": { "$ref": "#/definitions/hexColor" }, "description": "Per-entity color palette (seeded pick). Falls back to color." }
|
|
272
|
+
"colors": { "type": "array", "minItems": 1, "items": { "$ref": "#/definitions/hexColor" }, "description": "Per-entity color palette (seeded pick). Falls back to color." },
|
|
273
|
+
"colorWeights": { "$ref": "#/definitions/colorWeights" }
|
|
224
274
|
}
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"type": "object",
|
|
278
|
+
"required": ["kind", "radius", "color"],
|
|
279
|
+
"additionalProperties": false,
|
|
280
|
+
"properties": {
|
|
281
|
+
"kind": { "const": "ring" },
|
|
282
|
+
"radius": { "$ref": "#/definitions/positiveRange" },
|
|
283
|
+
"color": { "$ref": "#/definitions/hexColor" },
|
|
284
|
+
"width": { "type": "number", "exclusiveMinimum": 0, "description": "Stroke width (px or viewport-units). Default ~2px." },
|
|
285
|
+
"colors": { "type": "array", "minItems": 1, "items": { "$ref": "#/definitions/hexColor" }, "description": "Per-entity color palette (seeded pick)." },
|
|
286
|
+
"colorWeights": { "$ref": "#/definitions/colorWeights" }
|
|
287
|
+
},
|
|
288
|
+
"description": "Unfilled circle — bubbles, portals, sonar pings."
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"type": "object",
|
|
292
|
+
"required": ["kind", "length", "color"],
|
|
293
|
+
"additionalProperties": false,
|
|
294
|
+
"properties": {
|
|
295
|
+
"kind": { "const": "streak" },
|
|
296
|
+
"length": { "$ref": "#/definitions/positiveRange", "description": "Segment length range (px or viewport-units)." },
|
|
297
|
+
"color": { "$ref": "#/definitions/hexColor" },
|
|
298
|
+
"width": { "type": "number", "exclusiveMinimum": 0, "description": "Stroke width (px or viewport-units). Default ~2px." },
|
|
299
|
+
"colors": { "type": "array", "minItems": 1, "items": { "$ref": "#/definitions/hexColor" }, "description": "Per-entity color palette (seeded pick)." },
|
|
300
|
+
"colorWeights": { "$ref": "#/definitions/colorWeights" }
|
|
301
|
+
},
|
|
302
|
+
"description": "A line oriented along the entity's heading with a faded tail — rain that reads as rain, shooting stars, warp stars."
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"type": "object",
|
|
306
|
+
"required": ["kind", "width", "color"],
|
|
307
|
+
"additionalProperties": false,
|
|
308
|
+
"properties": {
|
|
309
|
+
"kind": { "const": "rect" },
|
|
310
|
+
"width": { "$ref": "#/definitions/positiveRange", "description": "Horizontal size range (px or viewport-units)." },
|
|
311
|
+
"aspect": { "$ref": "#/definitions/positiveRange", "description": "Height/width ratio range. Default [1,1] = squares." },
|
|
312
|
+
"color": { "$ref": "#/definitions/hexColor" },
|
|
313
|
+
"colors": { "type": "array", "minItems": 1, "items": { "$ref": "#/definitions/hexColor" }, "description": "Per-entity color palette (seeded pick)." },
|
|
314
|
+
"colorWeights": { "$ref": "#/definitions/colorWeights" }
|
|
315
|
+
},
|
|
316
|
+
"description": "Axis-aligned rectangle (rotates with spin) — Mondrian blocks, confetti, city lights."
|
|
225
317
|
}
|
|
226
318
|
]
|
|
227
319
|
},
|
|
320
|
+
"colorWeights": {
|
|
321
|
+
"type": "array",
|
|
322
|
+
"minItems": 1,
|
|
323
|
+
"items": { "type": "number", "minimum": 0 },
|
|
324
|
+
"contains": { "type": "number", "exclusiveMinimum": 0 },
|
|
325
|
+
"description": "Relative weights for the colors[] pick, same length as colors. At least one weight must be > 0. 'Mostly cool tones, occasional ember' without duplicating entries."
|
|
326
|
+
},
|
|
228
327
|
"cycle": {
|
|
229
328
|
"type": "object",
|
|
230
329
|
"required": ["period"],
|
|
@@ -289,6 +388,56 @@
|
|
|
289
388
|
"description": "[min, max] angular velocity in degrees/sec, capped at 180."
|
|
290
389
|
},
|
|
291
390
|
"radius": { "$ref": "#/definitions/positiveRange", "description": "[min, max] orbit radius in px." },
|
|
391
|
+
"center": {
|
|
392
|
+
"oneOf": [
|
|
393
|
+
{
|
|
394
|
+
"type": "object",
|
|
395
|
+
"required": ["x", "y"],
|
|
396
|
+
"additionalProperties": false,
|
|
397
|
+
"properties": {
|
|
398
|
+
"x": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
399
|
+
"y": { "type": "number", "minimum": 0, "maximum": 1 }
|
|
400
|
+
}
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
"type": "object",
|
|
404
|
+
"required": ["layer"],
|
|
405
|
+
"additionalProperties": false,
|
|
406
|
+
"properties": {
|
|
407
|
+
"layer": { "type": "string", "minLength": 1, "pattern": "\\S", "description": "Key of a count-1 parent layer to orbit (moons around a wandering planet). One level deep only — the parent may not itself orbit a layer." }
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
],
|
|
411
|
+
"description": "Orbit center: fractional viewport position (default {0.5, 0.5}) or { layer: key } to orbit a single-entity parent layer."
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
"type": "object",
|
|
417
|
+
"required": ["type", "speed"],
|
|
418
|
+
"additionalProperties": false,
|
|
419
|
+
"properties": {
|
|
420
|
+
"type": { "const": "wander" },
|
|
421
|
+
"speed": { "$ref": "#/definitions/speedRange" },
|
|
422
|
+
"angle": { "type": "number", "description": "Base heading in degrees. Omit for a seeded heading per entity." },
|
|
423
|
+
"meander": { "type": "number", "exclusiveMinimum": 0, "description": "Harmonic amplitude (px or viewport-units). Default ~0.05 viewport-units. How far paths curve away from the base line." },
|
|
424
|
+
"coherence": { "type": "number", "minimum": 0, "maximum": 1, "description": "0 = each entity wanders independently; 1 = the whole layer undulates in unison (fake flocking). Default 0." }
|
|
425
|
+
},
|
|
426
|
+
"description": "Organic harmonic drift — base velocity plus 3 seeded sine octaves per axis. Flowing curved paths (Flurry streams, aurora, jellyfish) with zero simulation state."
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
"type": "object",
|
|
430
|
+
"required": ["type", "speed"],
|
|
431
|
+
"additionalProperties": false,
|
|
432
|
+
"properties": {
|
|
433
|
+
"type": { "const": "warp" },
|
|
434
|
+
"speed": {
|
|
435
|
+
"type": "array",
|
|
436
|
+
"items": { "type": "number", "minimum": 0, "maximum": 1.5 },
|
|
437
|
+
"minItems": 2,
|
|
438
|
+
"maxItems": 2,
|
|
439
|
+
"description": "[min, max] depth-units/sec (1 = full near-to-far span per second), capped at 1.5."
|
|
440
|
+
},
|
|
292
441
|
"center": {
|
|
293
442
|
"type": "object",
|
|
294
443
|
"required": ["x", "y"],
|
|
@@ -297,9 +446,38 @@
|
|
|
297
446
|
"x": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
298
447
|
"y": { "type": "number", "minimum": 0, "maximum": 1 }
|
|
299
448
|
},
|
|
300
|
-
"description": "
|
|
449
|
+
"description": "Vanishing point as fractional viewport position. Default {0.5, 0.5}."
|
|
301
450
|
}
|
|
302
|
-
}
|
|
451
|
+
},
|
|
452
|
+
"description": "Perspective starfield: entities stream toward the viewer along a depth axis, size and alpha scaling with 1/z. Pair with streak sprites for the classic warp tunnel."
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
"type": "object",
|
|
456
|
+
"required": ["type", "points", "duration"],
|
|
457
|
+
"additionalProperties": false,
|
|
458
|
+
"properties": {
|
|
459
|
+
"type": { "const": "path" },
|
|
460
|
+
"points": {
|
|
461
|
+
"type": "array",
|
|
462
|
+
"minItems": 2,
|
|
463
|
+
"maxItems": 24,
|
|
464
|
+
"items": {
|
|
465
|
+
"type": "object",
|
|
466
|
+
"required": ["x", "y"],
|
|
467
|
+
"additionalProperties": false,
|
|
468
|
+
"properties": {
|
|
469
|
+
"x": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
470
|
+
"y": { "type": "number", "minimum": 0, "maximum": 1 }
|
|
471
|
+
}
|
|
472
|
+
},
|
|
473
|
+
"description": "Waypoints as fractional viewport positions."
|
|
474
|
+
},
|
|
475
|
+
"duration": { "type": "number", "minimum": 2000, "description": "Time for one full lap in ms (min 2000)." },
|
|
476
|
+
"curve": { "enum": ["linear", "smooth"], "description": "'smooth' (default) = Catmull-Rom spline through the points; 'linear' = straight segments." },
|
|
477
|
+
"closed": { "type": "boolean", "description": "Loop the path (default true). Open paths ping-pong." },
|
|
478
|
+
"scatter": { "type": "number", "exclusiveMinimum": 0, "description": "Seeded per-entity offset (px or viewport-units) so entities sharing a path don't stack." }
|
|
479
|
+
},
|
|
480
|
+
"description": "Choreographed spline motion — figure-eights, sweeping arcs, patrol routes. Each entity gets a seeded phase offset along the path."
|
|
303
481
|
}
|
|
304
482
|
]
|
|
305
483
|
}
|