@fungi.computer/sprite-zdog 0.0.0-stage → 0.0.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.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -2
  3. package/dist/agent-proof/moth.d.ts +50 -0
  4. package/dist/agent-proof/moth.js +52 -0
  5. package/dist/author.d.ts +217 -0
  6. package/dist/author.js +372 -0
  7. package/dist/avatar.d.ts +69 -0
  8. package/dist/avatar.js +40 -0
  9. package/dist/builtins/base-face.d.ts +290 -0
  10. package/dist/builtins/base-face.js +615 -0
  11. package/dist/builtins/base.d.ts +331 -0
  12. package/dist/builtins/base.js +579 -0
  13. package/dist/builtins/burger-input.d.ts +310 -0
  14. package/dist/builtins/burger-input.js +517 -0
  15. package/dist/builtins/burger.d.ts +305 -0
  16. package/dist/builtins/burger.js +4 -0
  17. package/dist/builtins/cat-input.d.ts +316 -0
  18. package/dist/builtins/cat-input.js +255 -0
  19. package/dist/builtins/cat.d.ts +311 -0
  20. package/dist/builtins/cat.js +4 -0
  21. package/dist/builtins/index.d.ts +4 -0
  22. package/dist/builtins/index.js +4 -0
  23. package/dist/builtins/mushroom-input.d.ts +314 -0
  24. package/dist/builtins/mushroom-input.js +94 -0
  25. package/dist/builtins/mushroom.d.ts +310 -0
  26. package/dist/builtins/mushroom.js +4 -0
  27. package/dist/burger.d.ts +9 -0
  28. package/dist/burger.js +15 -0
  29. package/dist/cat.d.ts +9 -0
  30. package/dist/cat.js +15 -0
  31. package/dist/catalog.d.ts +3 -0
  32. package/dist/catalog.js +63 -0
  33. package/dist/document.d.ts +444 -0
  34. package/dist/document.js +204 -0
  35. package/dist/index.d.ts +10 -0
  36. package/dist/index.js +10 -0
  37. package/dist/internal.d.ts +41 -0
  38. package/dist/internal.js +21 -0
  39. package/dist/mushroom.character.json +1930 -0
  40. package/dist/mushroom.d.ts +4 -0
  41. package/dist/mushroom.js +9 -0
  42. package/dist/palette.d.ts +3 -0
  43. package/dist/palette.js +5 -0
  44. package/dist/portable.d.ts +4 -0
  45. package/dist/portable.js +61 -0
  46. package/dist/renderer.d.ts +4 -0
  47. package/dist/renderer.js +106 -0
  48. package/dist/zdog-runtime.d.ts +21 -0
  49. package/dist/zdog-runtime.js +622 -0
  50. package/package.json +112 -3
@@ -0,0 +1,579 @@
1
+ import { defineSprite } from "../author.js";
2
+ const microMotion = (x, y) => ({
3
+ target: "root",
4
+ translate: { x, y },
5
+ durationMs: 150,
6
+ repeat: "none",
7
+ });
8
+ const base = defineSprite({
9
+ apiVersion: 1,
10
+ name: "ball",
11
+ palette: {
12
+ body: "#accce4",
13
+ eye: "#28282e",
14
+ mouth: "#28282e",
15
+ blush: "#feaae4",
16
+ dead: "#6c5671",
17
+ deadTongue: "#d9c8bf",
18
+ tongue: "#f98284",
19
+ sweat: "#accce4",
20
+ white: "#ffffff",
21
+ },
22
+ build({ scene, color }) {
23
+ const root = scene.group({ name: "root" });
24
+ const body = scene.group({ parent: root, name: "body", updateSort: true });
25
+ // The body is a Zdog dot with stroke 32, the legacy base sphere.
26
+ scene.path({
27
+ parent: body,
28
+ name: "body.sphere",
29
+ path: [{ x: 0, y: 0 }],
30
+ stroke: 32,
31
+ color: color("body"),
32
+ });
33
+ const face = scene.group({
34
+ parent: body,
35
+ name: "face",
36
+ translate: { z: 20 },
37
+ });
38
+ const ellipseEyes = (name, width, height, y, rotate, highlightWidth, highlightHeight) => {
39
+ const group = scene.group({ parent: face, name: `eyes.${name}` });
40
+ for (const side of [-1, 1]) {
41
+ const eyeOptions = { parent: group, translate: { x: 6 * side, y } };
42
+ if (rotate)
43
+ Object.assign(eyeOptions, { rotate: { z: rotate * side } });
44
+ const eye = scene.group(eyeOptions);
45
+ scene.ellipse({
46
+ parent: eye,
47
+ width,
48
+ height,
49
+ stroke: 1.5,
50
+ fill: true,
51
+ color: color("eye"),
52
+ });
53
+ scene.ellipse({
54
+ parent: eye,
55
+ width: highlightWidth,
56
+ height: highlightHeight,
57
+ stroke: 0.5,
58
+ fill: true,
59
+ color: color("white"),
60
+ translate: { y: -highlightHeight / 2, z: 1 },
61
+ });
62
+ }
63
+ return group;
64
+ };
65
+ const normalEyes = ellipseEyes("normal", 3, 5, -2, 0, 1.5, 2);
66
+ const sadEyes = ellipseEyes("sad", 3, 4, -1, -0.2, 1.5, 2);
67
+ const surprisedEyes = ellipseEyes("surprised", 4, 5, -2, 0, 1.5, 2);
68
+ const happyEyes = scene.group({ parent: face, name: "eyes.happy" });
69
+ for (const side of [-1, 1]) {
70
+ scene.path({
71
+ parent: happyEyes,
72
+ path: [
73
+ { x: -2.5, y: 2 },
74
+ {
75
+ bezier: [
76
+ { x: -1, y: -1.5 },
77
+ { x: 1, y: -1.5 },
78
+ { x: 2.5, y: 2 },
79
+ ],
80
+ },
81
+ ],
82
+ closed: false,
83
+ stroke: 1.5,
84
+ color: color("eye"),
85
+ translate: { x: 6 * side, y: -2 },
86
+ });
87
+ }
88
+ const angryEyes = scene.group({ parent: face, name: "eyes.angry" });
89
+ for (const side of [-1, 1]) {
90
+ const eye = scene.group({
91
+ parent: angryEyes,
92
+ rotate: { z: 0.3 * side },
93
+ translate: { x: 6 * side, y: -1 },
94
+ });
95
+ scene.ellipse({
96
+ parent: eye,
97
+ width: 3,
98
+ height: 4,
99
+ stroke: 1.5,
100
+ fill: true,
101
+ color: color("eye"),
102
+ });
103
+ scene.path({
104
+ parent: eye,
105
+ path: [
106
+ { x: -3, y: -3 },
107
+ { x: 3, y: -2 },
108
+ ],
109
+ stroke: 1.5,
110
+ color: color("eye"),
111
+ translate: { y: -1 },
112
+ });
113
+ }
114
+ const deadEyes = scene.group({ parent: face, name: "eyes.dead" });
115
+ for (const side of [-1, 1]) {
116
+ const eye = scene.group({
117
+ parent: deadEyes,
118
+ translate: { x: 6 * side, y: -2 },
119
+ });
120
+ for (const points of [
121
+ [
122
+ { x: -2, y: -3 },
123
+ { x: 2, y: 3 },
124
+ ],
125
+ [
126
+ { x: 2, y: -3 },
127
+ { x: -2, y: 3 },
128
+ ],
129
+ ]) {
130
+ scene.path({
131
+ parent: eye,
132
+ path: points,
133
+ stroke: 1.5,
134
+ color: color("dead"),
135
+ });
136
+ }
137
+ }
138
+ const confusedEyes = scene.group({ parent: face, name: "eyes.confused" });
139
+ const confusedLeft = scene.group({
140
+ parent: confusedEyes,
141
+ translate: { x: -6, y: -2 },
142
+ });
143
+ scene.ellipse({
144
+ parent: confusedLeft,
145
+ width: 3,
146
+ height: 5,
147
+ stroke: 1.5,
148
+ fill: true,
149
+ color: color("eye"),
150
+ });
151
+ scene.path({
152
+ parent: confusedLeft,
153
+ path: [
154
+ { x: -3, y: -4 },
155
+ { x: 3, y: -2 },
156
+ ],
157
+ stroke: 1.5,
158
+ color: color("eye"),
159
+ });
160
+ const confusedRight = scene.group({
161
+ parent: confusedEyes,
162
+ translate: { x: 6, y: -2 },
163
+ });
164
+ scene.ellipse({
165
+ parent: confusedRight,
166
+ width: 3,
167
+ height: 5,
168
+ stroke: 1.5,
169
+ fill: true,
170
+ color: color("eye"),
171
+ });
172
+ const sleepyEyes = scene.group({ parent: face, name: "eyes.sleepy" });
173
+ for (const side of [-1, 1]) {
174
+ scene.path({
175
+ parent: sleepyEyes,
176
+ path: [
177
+ { x: -2.5, y: 1 },
178
+ {
179
+ bezier: [
180
+ { x: -1, y: 0 },
181
+ { x: 1, y: 0 },
182
+ { x: 2.5, y: 1 },
183
+ ],
184
+ },
185
+ ],
186
+ closed: false,
187
+ stroke: 1.5,
188
+ color: color("eye"),
189
+ translate: { x: 6 * side, y: -1 },
190
+ });
191
+ }
192
+ const nervousEyes = scene.group({ parent: face, name: "eyes.nervous" });
193
+ for (const side of [-1, 1]) {
194
+ const eye = scene.group({
195
+ parent: nervousEyes,
196
+ translate: { x: 6 * side, y: -2 },
197
+ });
198
+ scene.ellipse({
199
+ parent: eye,
200
+ width: 3,
201
+ height: 5,
202
+ stroke: 1.5,
203
+ fill: true,
204
+ color: color("eye"),
205
+ });
206
+ }
207
+ const sweat = scene.group({
208
+ parent: nervousEyes,
209
+ translate: { x: 10, y: 4 },
210
+ });
211
+ scene.path({
212
+ parent: sweat,
213
+ path: [{ x: 0, y: -4 }],
214
+ stroke: 2,
215
+ color: color("sweat"),
216
+ });
217
+ scene.ellipse({
218
+ parent: sweat,
219
+ width: 3,
220
+ height: 4,
221
+ stroke: 0,
222
+ fill: true,
223
+ color: color("sweat"),
224
+ translate: { y: 2 },
225
+ });
226
+ const shyEyes = scene.group({ parent: face, name: "eyes.shy" });
227
+ for (const side of [-1, 1]) {
228
+ scene.ellipse({
229
+ parent: shyEyes,
230
+ width: 2.5,
231
+ height: 2,
232
+ stroke: 1.5,
233
+ fill: true,
234
+ color: color("eye"),
235
+ translate: { x: 6 * side, y: -2 },
236
+ });
237
+ }
238
+ const cuteEyes = scene.group({ parent: face, name: "eyes.cute" });
239
+ for (const side of [-1, 1]) {
240
+ const eye = scene.group({
241
+ parent: cuteEyes,
242
+ translate: { x: 6 * side, y: -1 },
243
+ });
244
+ scene.ellipse({
245
+ parent: eye,
246
+ width: 5,
247
+ height: 6,
248
+ stroke: 1.5,
249
+ fill: true,
250
+ color: color("eye"),
251
+ });
252
+ scene.ellipse({
253
+ parent: eye,
254
+ width: 2.5,
255
+ height: 3,
256
+ stroke: 0,
257
+ fill: true,
258
+ color: color("white"),
259
+ translate: { y: -1.5, z: 1 },
260
+ });
261
+ scene.ellipse({
262
+ parent: eye,
263
+ width: 1,
264
+ height: 1,
265
+ stroke: 0,
266
+ fill: true,
267
+ color: color("white"),
268
+ translate: { x: -1.5, y: 1.5, z: 1 },
269
+ });
270
+ }
271
+ // A wink closes one eye and keeps the other open: each choice draws both.
272
+ const winkEyes = scene.group({ parent: face, name: "eyes.wink" });
273
+ const wink = (side) => {
274
+ const group = scene.group({
275
+ parent: winkEyes,
276
+ name: `eyes.wink.${side}`,
277
+ });
278
+ const closed = side === "left" ? -1 : 1;
279
+ scene.path({
280
+ parent: group,
281
+ path: [
282
+ { x: -2.5, y: 2 },
283
+ {
284
+ bezier: [
285
+ { x: -1, y: -1.5 },
286
+ { x: 1, y: -1.5 },
287
+ { x: 2.5, y: 2 },
288
+ ],
289
+ },
290
+ ],
291
+ closed: false,
292
+ stroke: 1.5,
293
+ color: color("eye"),
294
+ translate: { x: 6 * closed, y: -2 },
295
+ });
296
+ scene.ellipse({
297
+ parent: group,
298
+ width: 3,
299
+ height: 5,
300
+ stroke: 1.5,
301
+ fill: true,
302
+ color: color("eye"),
303
+ translate: { x: -6 * closed, y: -2 },
304
+ });
305
+ return group;
306
+ };
307
+ const winkLeft = wink("left");
308
+ const winkRight = wink("right");
309
+ const mouth = (name, path, stroke = 1.5) => scene.path({
310
+ parent: face,
311
+ name: `mouth.${name}`,
312
+ path,
313
+ closed: false,
314
+ stroke,
315
+ color: color("mouth"),
316
+ translate: { y: 2 },
317
+ });
318
+ const normalMouth = mouth("normal", [
319
+ { x: -2.5, y: 0 },
320
+ { x: 2.5, y: 0 },
321
+ ]);
322
+ const happyMouth = mouth("happy", [
323
+ { x: -2.5, y: 2 },
324
+ {
325
+ bezier: [
326
+ { x: 0, y: 4 },
327
+ { x: 2.5, y: 2 },
328
+ { x: 2.5, y: 2 },
329
+ ],
330
+ },
331
+ ]);
332
+ const sadMouth = mouth("sad", [
333
+ { x: -2.5, y: 2 },
334
+ {
335
+ bezier: [
336
+ { x: 0, y: 0 },
337
+ { x: 2.5, y: 2 },
338
+ { x: 2.5, y: 2 },
339
+ ],
340
+ },
341
+ ]);
342
+ const smallMouth = mouth("small", [
343
+ { x: -1.5, y: 0 },
344
+ { x: 1.5, y: 0 },
345
+ ], 1);
346
+ const worriedMouth = mouth("worried", [
347
+ { x: -2, y: 1 },
348
+ {
349
+ bezier: [
350
+ { x: -0.5, y: 0.5 },
351
+ { x: 0.5, y: 0.5 },
352
+ { x: 2, y: 1 },
353
+ ],
354
+ },
355
+ ], 1);
356
+ const poutMouth = scene.ellipse({
357
+ parent: face,
358
+ name: "mouth.pout",
359
+ width: 2,
360
+ height: 2.5,
361
+ stroke: 1.5,
362
+ fill: true,
363
+ color: color("mouth"),
364
+ translate: { y: 3 },
365
+ });
366
+ const surprisedMouth = scene.ellipse({
367
+ parent: face,
368
+ name: "mouth.surprised",
369
+ width: 3,
370
+ height: 4,
371
+ stroke: 1.5,
372
+ fill: true,
373
+ color: color("mouth"),
374
+ translate: { y: 3 },
375
+ });
376
+ const deadMouth = scene.group({
377
+ parent: face,
378
+ name: "mouth.dead",
379
+ translate: { y: 5 },
380
+ });
381
+ scene.ellipse({
382
+ parent: deadMouth,
383
+ width: 3,
384
+ height: 2,
385
+ stroke: 1.5,
386
+ fill: true,
387
+ color: color("dead"),
388
+ });
389
+ scene.ellipse({
390
+ parent: deadMouth,
391
+ width: 1.5,
392
+ height: 1,
393
+ stroke: 0,
394
+ fill: true,
395
+ color: color("deadTongue"),
396
+ translate: { y: 0.5 },
397
+ });
398
+ const openMouth = scene.group({
399
+ parent: face,
400
+ name: "mouth.open",
401
+ translate: { y: 2 },
402
+ });
403
+ scene.ellipse({
404
+ parent: openMouth,
405
+ width: 6,
406
+ height: 4,
407
+ stroke: 1.5,
408
+ fill: true,
409
+ color: color("mouth"),
410
+ });
411
+ scene.ellipse({
412
+ parent: openMouth,
413
+ name: "mouth.tongue",
414
+ width: 3,
415
+ height: 1.5,
416
+ stroke: 0,
417
+ fill: true,
418
+ color: color("tongue"),
419
+ translate: { y: 1 },
420
+ });
421
+ const blush = (name, width, height, stroke, x) => {
422
+ const group = scene.group({ parent: face, name: `blush.${name}` });
423
+ for (const side of [-1, 1])
424
+ scene.ellipse({
425
+ parent: group,
426
+ width,
427
+ height,
428
+ stroke,
429
+ fill: true,
430
+ color: color("blush"),
431
+ translate: { x: x * side, y: 4 },
432
+ });
433
+ return group;
434
+ };
435
+ const blushOff = scene.group({ parent: face, name: "blush.off" });
436
+ const blushSmall = blush("small", 3.5, 1.8, 1, 9);
437
+ const blushMedium = blush("medium", 5, 2.5, 1.5, 10);
438
+ const blushBig = blush("big", 7, 3.5, 2, 11);
439
+ return {
440
+ root,
441
+ variants: {
442
+ eyes: {
443
+ normal: normalEyes,
444
+ happy: happyEyes,
445
+ sad: sadEyes,
446
+ angry: angryEyes,
447
+ surprised: surprisedEyes,
448
+ dead: deadEyes,
449
+ confused: confusedEyes,
450
+ sleepy: sleepyEyes,
451
+ nervous: nervousEyes,
452
+ shy: shyEyes,
453
+ wink: winkLeft,
454
+ cute: cuteEyes,
455
+ "wink.left": winkLeft,
456
+ "wink.right": winkRight,
457
+ },
458
+ mouth: {
459
+ normal: normalMouth,
460
+ happy: happyMouth,
461
+ sad: sadMouth,
462
+ angry: sadMouth,
463
+ surprised: surprisedMouth,
464
+ dead: deadMouth,
465
+ small: smallMouth,
466
+ worried: worriedMouth,
467
+ pout: poutMouth,
468
+ open: openMouth,
469
+ },
470
+ blush: {
471
+ off: blushOff,
472
+ small: blushSmall,
473
+ medium: blushMedium,
474
+ big: blushBig,
475
+ },
476
+ },
477
+ };
478
+ },
479
+ expressions: {
480
+ angry: {
481
+ variants: { eyes: "angry", mouth: "angry", blush: "off" },
482
+ motion: microMotion(1, 0),
483
+ },
484
+ confused: {
485
+ variants: { eyes: "confused", mouth: "normal", blush: "off" },
486
+ motion: microMotion(0, 0.5),
487
+ },
488
+ cute: {
489
+ variants: { eyes: "cute", mouth: "happy", blush: "big" },
490
+ motion: microMotion(0, -2.5),
491
+ },
492
+ dead: { variants: { eyes: "dead", mouth: "dead", blush: "off" } },
493
+ happy: {
494
+ variants: { eyes: "happy", mouth: "happy", blush: "medium" },
495
+ motion: microMotion(0, -2),
496
+ },
497
+ nervous: {
498
+ variants: { eyes: "nervous", mouth: "worried", blush: "off" },
499
+ motion: microMotion(-0.5, -1),
500
+ },
501
+ normal: {
502
+ variants: { eyes: "normal", mouth: "normal", blush: "off" },
503
+ motion: microMotion(0, 1),
504
+ },
505
+ pleading: {
506
+ variants: { eyes: "cute", mouth: "pout", blush: "medium" },
507
+ motion: microMotion(0, -1),
508
+ },
509
+ sad: {
510
+ variants: { eyes: "sad", mouth: "sad", blush: "off" },
511
+ motion: microMotion(0, 2),
512
+ },
513
+ shy: {
514
+ variants: { eyes: "shy", mouth: "small", blush: "small" },
515
+ motion: microMotion(0, 1.5),
516
+ },
517
+ sleepy: {
518
+ variants: { eyes: "sleepy", mouth: "small", blush: "off" },
519
+ motion: microMotion(0, 2),
520
+ },
521
+ surprised: {
522
+ variants: { eyes: "surprised", mouth: "surprised", blush: "off" },
523
+ motion: microMotion(0, -3),
524
+ },
525
+ wink: {
526
+ variants: { eyes: "wink", mouth: "happy", blush: "small" },
527
+ variantChoices: { eyes: ["wink.left", "wink.right"] },
528
+ motion: microMotion(0, -1.5),
529
+ },
530
+ },
531
+ activities: {
532
+ idle: {
533
+ motion: {
534
+ target: "root",
535
+ translate: { y: 0.5 },
536
+ durationMs: 2000,
537
+ repeat: "yoyo",
538
+ },
539
+ mouseInfluence: 1,
540
+ },
541
+ listening: {
542
+ motion: {
543
+ target: "root",
544
+ rotate: { x: -0.2 },
545
+ durationMs: 300,
546
+ repeat: "yoyo",
547
+ },
548
+ mouseInfluence: 0.3,
549
+ },
550
+ processing: { mouseInfluence: 0.2 },
551
+ speaking: {
552
+ motion: {
553
+ target: "root",
554
+ translate: { y: 0.5 },
555
+ durationMs: 1500,
556
+ repeat: "yoyo",
557
+ },
558
+ mouseInfluence: 0,
559
+ mouthCycle: [
560
+ { durationMs: 100, mouth: "open" },
561
+ { durationMs: 150, mouth: "base" },
562
+ { durationMs: 100, mouth: "open" },
563
+ { durationMs: 200, mouth: "base" },
564
+ ],
565
+ },
566
+ thinking: {
567
+ motion: {
568
+ target: "root",
569
+ rotate: { z: 0.1 },
570
+ durationMs: 800,
571
+ repeat: "yoyo",
572
+ },
573
+ mouseInfluence: 0,
574
+ },
575
+ error: { geometry: { expression: "dead" }, mouseInfluence: 0.1 },
576
+ },
577
+ defaultPresentation: { activity: "idle", expression: "normal" },
578
+ });
579
+ export default base;