@dopaminefx/effect-lightning 0.1.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.
@@ -0,0 +1,495 @@
1
+ {
2
+ "fmt": "dopamine-effect",
3
+ "v": "1.0.0",
4
+ "id": "dopamine.boost.lightning",
5
+ "meta": {
6
+ "name": "Lightning",
7
+ "description": "A high-energy power-up / boost strike: a branching, fbm-perturbed electric arc cracks into the action point with a hard white flash, secondary forks, and a brief flicker afterglow. Electric OKLCH blues/violets to a hot white core.",
8
+ "tags": [
9
+ "boost",
10
+ "power-up",
11
+ "electric",
12
+ "lightning",
13
+ "anchored"
14
+ ]
15
+ },
16
+ "controls": {
17
+ "mood": {
18
+ "type": "enum",
19
+ "label": "Mood",
20
+ "default": "electric",
21
+ "options": [
22
+ "serene",
23
+ "celebratory",
24
+ "electric"
25
+ ],
26
+ "ui": "segmented"
27
+ },
28
+ "intensity": {
29
+ "type": "scalar",
30
+ "label": "Intensity",
31
+ "default": 0.85,
32
+ "min": 0,
33
+ "max": 1,
34
+ "step": 0.01,
35
+ "ui": "slider",
36
+ "help": "Bolt thickness, branch count, flash brightness."
37
+ },
38
+ "whimsy": {
39
+ "type": "scalar",
40
+ "label": "Whimsy",
41
+ "default": 0.5,
42
+ "min": 0,
43
+ "max": 1,
44
+ "step": 0.01,
45
+ "ui": "slider",
46
+ "help": "Photoreal plasma glow (0) to flat cel comic-book bolt + harder strobe (1)."
47
+ },
48
+ "seed": {
49
+ "type": "int",
50
+ "label": "Seed",
51
+ "default": null,
52
+ "nullable": true,
53
+ "help": "Null = unique bolt + palette per fire; pin to reproduce."
54
+ },
55
+ "origin": {
56
+ "type": "point",
57
+ "label": "Origin",
58
+ "default": "center"
59
+ },
60
+ "target": {
61
+ "type": "selector",
62
+ "label": "Target",
63
+ "default": "document.body"
64
+ }
65
+ },
66
+ "baselines": {
67
+ "serene": {
68
+ "durationMs": 1400,
69
+ "lightness": 0.82,
70
+ "chroma": 0.12,
71
+ "hueCenter": 245,
72
+ "hueRange": 60,
73
+ "thickness": 0.012,
74
+ "jagged": 0.55,
75
+ "branches": 0,
76
+ "flashBright": 0.5,
77
+ "flicker": 0.3,
78
+ "overshoot": 0.7
79
+ },
80
+ "celebratory": {
81
+ "durationMs": 1100,
82
+ "lightness": 0.8,
83
+ "chroma": 0.18,
84
+ "hueCenter": 228,
85
+ "hueRange": 110,
86
+ "thickness": 0.016,
87
+ "jagged": 0.85,
88
+ "branches": 3,
89
+ "flashBright": 0.8,
90
+ "flicker": 0.65,
91
+ "overshoot": 1.05
92
+ },
93
+ "electric": {
94
+ "durationMs": 850,
95
+ "lightness": 0.8,
96
+ "chroma": 0.24,
97
+ "hueCenter": 268,
98
+ "hueRange": 90,
99
+ "thickness": 0.02,
100
+ "jagged": 1.15,
101
+ "branches": 6,
102
+ "flashBright": 1.1,
103
+ "flicker": 1,
104
+ "overshoot": 1.5
105
+ }
106
+ },
107
+ "palette": {
108
+ "model": "oklch",
109
+ "space": "linear-srgb",
110
+ "generator": "golden-angle",
111
+ "goldenAngleDeg": 137.50776405003785,
112
+ "stops": 3,
113
+ "hueSpread": 0.4,
114
+ "lightness": {
115
+ "baseline": "lightness",
116
+ "perStop": [
117
+ 0.08,
118
+ 0,
119
+ -0.06
120
+ ]
121
+ },
122
+ "chroma": {
123
+ "from": {
124
+ "mul": [
125
+ {
126
+ "baseline": "chroma"
127
+ },
128
+ {
129
+ "lerp": [
130
+ "intensity",
131
+ 0.7,
132
+ 1.4
133
+ ]
134
+ }
135
+ ]
136
+ },
137
+ "perStop": [
138
+ -0.02,
139
+ 0.02,
140
+ 0.01
141
+ ]
142
+ },
143
+ "seed": {
144
+ "deterministic": true,
145
+ "source": "controls.seed",
146
+ "prng": "mulberry32"
147
+ },
148
+ "perMood": {
149
+ "serene": {
150
+ "hueCenter": 245,
151
+ "hueRange": 60,
152
+ "lightness": 0.82,
153
+ "chroma": 0.12
154
+ },
155
+ "celebratory": {
156
+ "hueCenter": 228,
157
+ "hueRange": 110,
158
+ "lightness": 0.8,
159
+ "chroma": 0.18
160
+ },
161
+ "electric": {
162
+ "hueCenter": 268,
163
+ "hueRange": 90,
164
+ "lightness": 0.8,
165
+ "chroma": 0.24
166
+ }
167
+ }
168
+ },
169
+ "tempo": {
170
+ "durationMs": {
171
+ "from": {
172
+ "round": {
173
+ "mul": [
174
+ {
175
+ "baseline": "durationMs"
176
+ },
177
+ {
178
+ "lerp": [
179
+ "intensity",
180
+ 1.15,
181
+ 0.9
182
+ ]
183
+ }
184
+ ]
185
+ }
186
+ }
187
+ },
188
+ "frame": {
189
+ "note": "The per-frame logic, datafied (was lightning-tempo): amp = the impact envelope; strike = strikeProgress(animMs), the ease-out-quint crack-in over the 130 ms STRIKE_MS window (the same clock the CPU bolt precompute keys off — see x-build.logic); flash = flashStrobe(life, flicker), an instantaneous near-white primary that decays fast (exp(-t/0.035)) plus 6 discrete afterglow re-pulses (sin^8 spikes) whose peaks decay across the tail, scaled by flicker.",
190
+ "amp": {
191
+ "envelope": [
192
+ {
193
+ "input": "life"
194
+ },
195
+ {
196
+ "param": "overshoot"
197
+ }
198
+ ]
199
+ },
200
+ "extras": {
201
+ "strike": {
202
+ "sub": [
203
+ 1,
204
+ {
205
+ "pow": [
206
+ {
207
+ "sub": [
208
+ 1,
209
+ {
210
+ "clamp01": {
211
+ "div": [
212
+ {
213
+ "input": "animMs"
214
+ },
215
+ 130
216
+ ]
217
+ }
218
+ }
219
+ ]
220
+ },
221
+ 5
222
+ ]
223
+ }
224
+ ]
225
+ },
226
+ "flash": {
227
+ "add": [
228
+ {
229
+ "exp": {
230
+ "div": [
231
+ {
232
+ "mul": [
233
+ -1,
234
+ {
235
+ "clamp01": {
236
+ "input": "life"
237
+ }
238
+ }
239
+ ]
240
+ },
241
+ 0.035
242
+ ]
243
+ }
244
+ },
245
+ {
246
+ "mul": [
247
+ {
248
+ "pow": [
249
+ {
250
+ "max": [
251
+ 0,
252
+ {
253
+ "sin": {
254
+ "mul": [
255
+ {
256
+ "clamp01": {
257
+ "input": "life"
258
+ }
259
+ },
260
+ 6,
261
+ 3.141592653589793,
262
+ 2
263
+ ]
264
+ }
265
+ }
266
+ ]
267
+ },
268
+ 8
269
+ ]
270
+ },
271
+ {
272
+ "mul": [
273
+ {
274
+ "pow": [
275
+ {
276
+ "sub": [
277
+ 1,
278
+ {
279
+ "clamp01": {
280
+ "input": "life"
281
+ }
282
+ }
283
+ ]
284
+ },
285
+ 2.2
286
+ ]
287
+ },
288
+ 0.28,
289
+ {
290
+ "param": "flicker"
291
+ }
292
+ ]
293
+ }
294
+ ]
295
+ }
296
+ ]
297
+ }
298
+ }
299
+ },
300
+ "reducedMotion": {
301
+ "peakMs": 130,
302
+ "holdMs": 300
303
+ }
304
+ },
305
+ "render": {
306
+ "params": {
307
+ "exposure": {
308
+ "type": "float",
309
+ "from": {
310
+ "lerp": [
311
+ "intensity",
312
+ 0.9,
313
+ 1.6
314
+ ]
315
+ }
316
+ },
317
+ "thickness": {
318
+ "type": "float",
319
+ "from": {
320
+ "mul": [
321
+ {
322
+ "baseline": "thickness"
323
+ },
324
+ {
325
+ "lerp": [
326
+ "intensity",
327
+ 0.7,
328
+ 1.35
329
+ ]
330
+ }
331
+ ]
332
+ }
333
+ },
334
+ "jagged": {
335
+ "type": "float",
336
+ "from": {
337
+ "mul": [
338
+ {
339
+ "baseline": "jagged"
340
+ },
341
+ {
342
+ "lerp": [
343
+ "intensity",
344
+ 0.8,
345
+ 1.2
346
+ ]
347
+ }
348
+ ]
349
+ }
350
+ },
351
+ "branches": {
352
+ "type": "int",
353
+ "clampMax": "MAX_FORKS",
354
+ "from": {
355
+ "round": {
356
+ "mul": [
357
+ {
358
+ "baseline": "branches"
359
+ },
360
+ {
361
+ "lerp": [
362
+ "intensity",
363
+ 0.5,
364
+ 1.25
365
+ ]
366
+ }
367
+ ]
368
+ }
369
+ }
370
+ },
371
+ "flashBright": {
372
+ "type": "float",
373
+ "from": {
374
+ "mul": [
375
+ {
376
+ "baseline": "flashBright"
377
+ },
378
+ {
379
+ "lerp": [
380
+ "intensity",
381
+ 0.6,
382
+ 1.4
383
+ ]
384
+ }
385
+ ]
386
+ }
387
+ },
388
+ "flicker": {
389
+ "type": "float",
390
+ "clamp01": true,
391
+ "from": {
392
+ "baseline": "flicker"
393
+ }
394
+ },
395
+ "overshoot": {
396
+ "type": "float",
397
+ "from": {
398
+ "mul": [
399
+ {
400
+ "baseline": "overshoot"
401
+ },
402
+ {
403
+ "lerp": [
404
+ "intensity",
405
+ 0.7,
406
+ 1.25
407
+ ]
408
+ }
409
+ ]
410
+ }
411
+ },
412
+ "style": {
413
+ "type": "float",
414
+ "from": {
415
+ "control": "whimsy"
416
+ }
417
+ }
418
+ },
419
+ "shadowHeightFrac": {
420
+ "add": [
421
+ {
422
+ "mul": [
423
+ {
424
+ "param": "thickness"
425
+ },
426
+ 14
427
+ ]
428
+ },
429
+ 0.4
430
+ ]
431
+ },
432
+ "consts": {
433
+ "MAX_FORKS": 7
434
+ },
435
+ "config": {
436
+ "usesOrigin": true
437
+ },
438
+ "backends": {
439
+ "webgl2": {
440
+ "stage": "fullscreen-triangle",
441
+ "blend": "screen",
442
+ "shader": {
443
+ "program": "lightning"
444
+ }
445
+ }
446
+ },
447
+ "fallbackOrder": [
448
+ "webgl2"
449
+ ]
450
+ },
451
+ "binding": {
452
+ "note": "CROSS-PLATFORM uniform-binding contract. Which render.params are NOT shader uniforms, the seed-keyed scatter field, the per-frame/host extras, the texture samplers, and the per-frame ARRAYS — one source of truth for the web u<Name> list, the Swift struct + packer, and the MSL struct. SHIPS in the portable .dope (the runtime derives its uniform bindings from it); the toolchain consumes it too for the Metal struct codegen. Only `x-build`, `slug` and `kind` stay toolchain-only. lightning's CPU-precomputed bolt polyline rides the frameArrays seam declared in `arrays` (uVerts/uBoltMeta), not the uniform struct.",
453
+ "excludeParams": [
454
+ "style",
455
+ "overshoot",
456
+ "flicker",
457
+ "durationMs",
458
+ "jagged",
459
+ "branches"
460
+ ],
461
+ "scatterKey": "boltSeed",
462
+ "scatterWeb": "uSeed",
463
+ "extras": [
464
+ {
465
+ "name": "strike",
466
+ "type": "float",
467
+ "web": "uStrike",
468
+ "note": "tempo.frame.extras.strike — the 130 ms ease-out-quint crack-in"
469
+ },
470
+ {
471
+ "name": "flash",
472
+ "type": "float",
473
+ "web": "uFlash",
474
+ "note": "tempo.frame.extras.flash — the strobe (primary flash + flicker afterglow)"
475
+ }
476
+ ],
477
+ "samplers": [],
478
+ "arrays": [
479
+ {
480
+ "name": "verts",
481
+ "web": "uVerts",
482
+ "size": 2,
483
+ "buffer": 1,
484
+ "note": "CPU-precomputed bolt polyline (x-build.logic): vertex i of bolt b at [b*VERTS_PER_BOLT + i], device px, gl y-up. Web/GL bind by NAME as the uniform vec2 array; Metal binds it as `constant float2 *uVerts` at fragment buffer 1."
485
+ },
486
+ {
487
+ "name": "meta",
488
+ "web": "uBoltMeta",
489
+ "size": 4,
490
+ "buffer": 2,
491
+ "note": "Per-bolt (segCount, radFrac, fadeMul, isMain); `constant float4 *uBoltMeta` at fragment buffer 2 on Metal."
492
+ }
493
+ ]
494
+ }
495
+ }