wobnimo 0.1.4 → 0.2.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.
Files changed (68) hide show
  1. package/AGENTS.md +18 -4
  2. package/README.md +38 -7
  3. package/dist/characters/bao.d.ts +6 -0
  4. package/dist/characters/bao.js +1 -0
  5. package/dist/characters/berry.d.ts +6 -0
  6. package/dist/characters/berry.js +1 -0
  7. package/dist/characters/boo.js +1 -1
  8. package/dist/characters/bumble.d.ts +6 -0
  9. package/dist/characters/bumble.js +1 -0
  10. package/dist/characters/cacti.d.ts +6 -0
  11. package/dist/characters/cacti.js +1 -0
  12. package/dist/characters/cap.d.ts +6 -0
  13. package/dist/characters/cap.js +1 -0
  14. package/dist/characters/drift.d.ts +6 -0
  15. package/dist/characters/drift.js +1 -0
  16. package/dist/characters/ember.d.ts +6 -0
  17. package/dist/characters/ember.js +1 -0
  18. package/dist/characters/hop.d.ts +6 -0
  19. package/dist/characters/hop.js +1 -0
  20. package/dist/characters/index.d.ts +11 -1
  21. package/dist/characters/index.js +11 -11
  22. package/dist/characters/inky.js +1 -1
  23. package/dist/characters/latte.d.ts +6 -0
  24. package/dist/characters/latte.js +1 -0
  25. package/dist/characters/microduck.js +1 -1
  26. package/dist/characters/miso.js +1 -1
  27. package/dist/characters/mochi.js +1 -1
  28. package/dist/characters/pebble.js +1 -1
  29. package/dist/characters/pip.js +1 -1
  30. package/dist/characters/rex.js +1 -1
  31. package/dist/characters/swirl.d.ts +6 -0
  32. package/dist/characters/swirl.js +1 -0
  33. package/dist/characters/tad.js +1 -1
  34. package/dist/characters/volt.js +1 -1
  35. package/dist/cli.js +1888 -0
  36. package/dist/element.d.ts +1 -1
  37. package/dist/element.js +9 -9
  38. package/dist/index-Cm5wWKoT.d.ts +12 -0
  39. package/dist/index.d.ts +4 -0
  40. package/dist/index.js +6 -6
  41. package/dist/react.js +16 -16
  42. package/dist/wobnimo.js +12 -12
  43. package/package.json +14 -4
  44. package/skill/SKILL.md +719 -0
  45. package/skill/examples/bao.ts +73 -0
  46. package/skill/examples/berry.ts +97 -0
  47. package/skill/examples/boo.ts +87 -0
  48. package/skill/examples/bumble.ts +70 -0
  49. package/skill/examples/cacti.ts +79 -0
  50. package/skill/examples/cap.ts +59 -0
  51. package/skill/examples/drift.ts +74 -0
  52. package/skill/examples/ember.ts +78 -0
  53. package/skill/examples/hop.ts +66 -0
  54. package/skill/examples/inky.ts +168 -0
  55. package/skill/examples/latte.ts +73 -0
  56. package/skill/examples/microduck.ts +222 -0
  57. package/skill/examples/miso.ts +182 -0
  58. package/skill/examples/mochi.ts +78 -0
  59. package/skill/examples/pebble.ts +174 -0
  60. package/skill/examples/pip.ts +170 -0
  61. package/skill/examples/rex.ts +193 -0
  62. package/skill/examples/swirl.ts +69 -0
  63. package/skill/examples/tad.ts +117 -0
  64. package/skill/examples/volt.ts +214 -0
  65. package/skill/reference/recipes.md +551 -0
  66. package/skill/reference/spec.md +258 -0
  67. package/skill/templates/starter.ts +73 -0
  68. package/dist/index-DRDEWSGV.d.ts +0 -8
@@ -0,0 +1,182 @@
1
+ import type { CharacterSpec } from 'wobnimo';
2
+
3
+ /** A plush cat: soft fur, big green eyes, ears that talk and a tail that never stops. */
4
+ export const miso: CharacterSpec = {
5
+ id: 'miso',
6
+ name: 'Miso',
7
+ tagline: 'A plush tabby with velvet fur, swivelling ears and a tail that never sits still',
8
+ accent: '#e38b3c',
9
+ frame: { target: 0.56, radius: 0.72 },
10
+ bound: { y: 0.52, radius: 0.88 },
11
+ motion: { hop: 0.14, squash: 1.2, snap: 1.1, talkSquash: 0.3 },
12
+ materials: {
13
+ /* matte plush: almost no highlight, a velvet glow at the edges where
14
+ the fibres catch the light, and a little light through the fluff */
15
+ fur: { color: '#eaa15c', f0: 0.015, spec: 0.06, shininess: 6, rim: 1.1, sheen: 0.95, gloss: 0, sss: 0.18, sssColor: '#ffcf9e' },
16
+ cream: { color: '#fbe8d0', f0: 0.015, spec: 0.06, shininess: 6, rim: 1, sheen: 0.9, gloss: 0, sss: 0.18, sssColor: '#ffe6cc' },
17
+ pink: { color: '#ff9fb2', f0: 0.04, spec: 0.5, shininess: 40, rim: 0.4, sss: 0.4, sssColor: '#ffc4cf' },
18
+ nose: { color: '#f27a93', f0: 0.06, spec: 1.6, shininess: 160, rim: 0.3, gloss: 0.8 },
19
+ whisker: { color: '#fff8ee', f0: 0.04, spec: 0.6, shininess: 60, rim: 0.5 },
20
+ },
21
+ bones: [
22
+ { name: 'body', pivot: [0, 0, 0], drive: { ry: [['yaw', 0.2]], rz: [['roll', 0.25]] } },
23
+ { name: 'head', parent: 'body', pivot: [0, 0.5, 0.02], drive: { rx: [['pitch', -1]], ry: [['yaw', 0.85]], rz: [['roll', 0.8]] } },
24
+ /* ears twitch on their own every so often, and flick with every hop */
25
+ {
26
+ name: 'earL', parent: 'head', pivot: [-0.19, 0.38, -0.02], rest: { rz: 0.32 }, wave: { rx: [0.06, 0.37, 0] },
27
+ jiggle: { axis: [0, 1, 0], length: 0.16, freq: 3.2, damping: 0.16, maxAngle: 0.5 },
28
+ },
29
+ {
30
+ name: 'earR', parent: 'head', pivot: [0.19, 0.38, -0.02], rest: { rz: -0.32 }, wave: { rx: [0.06, 0.29, 2] },
31
+ jiggle: { axis: [0, 1, 0], length: 0.16, freq: 3.2, damping: 0.16, maxAngle: 0.5 },
32
+ },
33
+ { name: 'pawL', parent: 'body', pivot: [-0.13, 0.22, 0.17], drive: { rx: [['flap', -1.2]], rz: [['flap', -0.4]] } },
34
+ { name: 'pawR', parent: 'body', pivot: [0.13, 0.22, 0.17], drive: { rx: [['flap', -1.2]], rz: [['flap', 0.4]] } },
35
+ /* the tail: three links, each lagging the one before */
36
+ { name: 'tail0', parent: 'body', pivot: [0.12, 0.1, -0.24], rest: { rx: -0.5, rz: -0.5 }, wave: { rz: [0.25, 0.45, 0] }, jiggle: { axis: [0, 1, 0], length: 0.16, freq: 2, damping: 0.25, maxAngle: 0.7 } },
37
+ { name: 'tail1', parent: 'tail0', pivot: [0, 0.16, 0], rest: { rx: -0.3 }, wave: { rz: [0.2, 0.45, 0.8] }, jiggle: { axis: [0, 1, 0], length: 0.15, freq: 1.8, damping: 0.22, maxAngle: 0.8 } },
38
+ { name: 'tail2', parent: 'tail1', pivot: [0, 0.15, 0], rest: { rx: 0.25 }, wave: { rz: [0.3, 0.45, 1.6] }, jiggle: { axis: [0, 1, 0], length: 0.13, freq: 1.6, damping: 0.2, maxAngle: 0.9 } },
39
+ ],
40
+ parts: [
41
+ /* a round sitting body with haunches and big back feet */
42
+ { bone: 'body', shape: 'ellipsoid', at: [0, 0.25, -0.02], radii: [0.29, 0.26, 0.26], material: 'fur' },
43
+ { bone: 'body', shape: 'ellipsoid', at: [-0.17, 0.13, -0.02], radii: [0.14, 0.13, 0.19], blend: 0.08, material: 'fur' },
44
+ { bone: 'body', shape: 'ellipsoid', at: [0.17, 0.13, -0.02], radii: [0.14, 0.13, 0.19], blend: 0.08, material: 'fur' },
45
+ { bone: 'body', shape: 'ellipsoid', at: [-0.17, 0.04, 0.14], radii: [0.085, 0.05, 0.11], blend: 0.03, material: 'cream' },
46
+ { bone: 'body', shape: 'ellipsoid', at: [0.17, 0.04, 0.14], radii: [0.085, 0.05, 0.11], blend: 0.03, material: 'cream' },
47
+ /* a big head with chubby cheeks and a muzzle */
48
+ { bone: 'head', shape: 'ellipsoid', at: [0, 0.2, 0], radii: [0.34, 0.28, 0.29], blend: 0.1, material: 'fur' },
49
+ { bone: 'head', shape: 'sphere', at: [-0.17, 0.1, 0.12], radius: 0.15, blend: 0.1, material: 'fur' },
50
+ { bone: 'head', shape: 'sphere', at: [0.17, 0.1, 0.12], radius: 0.15, blend: 0.1, material: 'fur' },
51
+ { bone: 'head', shape: 'ellipsoid', at: [0, 0.09, 0.22], radii: [0.12, 0.075, 0.08], blend: 0.05, material: 'cream' },
52
+ { bone: 'head', shape: 'ellipsoid', at: [0, 0.135, 0.3], rot: [0.3, 0, 0], radii: [0.032, 0.02, 0.018], blend: 0.01, material: 'nose' },
53
+ /* ears, with pink insides */
54
+ { bone: 'earL', shape: 'roundCone', from: [0, 0, 0], to: [0, 0.15, 0], r1: 0.1, r2: 0.022, blend: 0.05, material: 'fur' },
55
+ { bone: 'earL', shape: 'ellipsoid', at: [0, 0.055, 0.045], radii: [0.05, 0.075, 0.03], material: 'pink' },
56
+ { bone: 'earR', shape: 'roundCone', from: [0, 0, 0], to: [0, 0.15, 0], r1: 0.1, r2: 0.022, blend: 0.05, material: 'fur' },
57
+ { bone: 'earR', shape: 'ellipsoid', at: [0, 0.055, 0.045], radii: [0.05, 0.075, 0.03], material: 'pink' },
58
+ /* front paws, cream mittens */
59
+ { bone: 'pawL', shape: 'capsule', from: [0, 0, 0], to: [0, -0.15, 0.03], radius: 0.065, blend: 0.05, material: 'fur' },
60
+ { bone: 'pawL', shape: 'ellipsoid', at: [0, -0.17, 0.05], radii: [0.07, 0.05, 0.075], blend: 0.03, material: 'cream' },
61
+ { bone: 'pawR', shape: 'capsule', from: [0, 0, 0], to: [0, -0.15, 0.03], radius: 0.065, blend: 0.05, material: 'fur' },
62
+ { bone: 'pawR', shape: 'ellipsoid', at: [0, -0.17, 0.05], radii: [0.07, 0.05, 0.075], blend: 0.03, material: 'cream' },
63
+ /* the tail, thick at the root, with a cream tip */
64
+ { bone: 'tail0', shape: 'roundCone', from: [0, 0, 0], to: [0, 0.16, 0], r1: 0.055, r2: 0.05, blend: 0.04, material: 'fur' },
65
+ { bone: 'tail1', shape: 'roundCone', from: [0, 0, 0], to: [0, 0.15, 0], r1: 0.05, r2: 0.047, blend: 0.02, material: 'fur' },
66
+ { bone: 'tail2', shape: 'roundCone', from: [0, 0, 0], to: [0, 0.12, 0], r1: 0.047, r2: 0.04, blend: 0.02, material: 'cream' },
67
+ /* whiskers */
68
+ { bone: 'head', shape: 'capsule', from: [-0.13, 0.1, 0.27], to: [-0.33, 0.13, 0.24], radius: 0.005, material: 'whisker' },
69
+ { bone: 'head', shape: 'capsule', from: [-0.13, 0.08, 0.27], to: [-0.33, 0.06, 0.23], radius: 0.005, material: 'whisker' },
70
+ { bone: 'head', shape: 'capsule', from: [0.13, 0.1, 0.27], to: [0.33, 0.13, 0.24], radius: 0.005, material: 'whisker' },
71
+ { bone: 'head', shape: 'capsule', from: [0.13, 0.08, 0.27], to: [0.33, 0.06, 0.23], radius: 0.005, material: 'whisker' },
72
+ ],
73
+ paints: [
74
+ /* tabby stripes on the forehead and a cream belly */
75
+ { bone: 'head', on: ['fur'], kind: 'ellipse', at: [0, 0.4, 0.2], radii: [0.022, 0.08], color: '#c4733a', soft: 0.5 },
76
+ { bone: 'head', on: ['fur'], kind: 'ellipse', at: [-0.075, 0.38, 0.2], radii: [0.018, 0.065], color: '#c4733a', soft: 0.5 },
77
+ { bone: 'head', on: ['fur'], kind: 'ellipse', at: [0.075, 0.38, 0.2], radii: [0.018, 0.065], color: '#c4733a', soft: 0.5 },
78
+ { bone: 'body', on: ['fur'], kind: 'ellipse', at: [0, 0.24, 0.2], radii: [0.17, 0.2], color: '#fbe8d0', soft: 0.35 },
79
+ { bone: 'head', on: ['fur'], kind: 'sphere', at: [-0.21, 0.1, 0.24], radius: 0.06, color: '#ff9db0', soft: 0.6, opacity: 0.75 },
80
+ { bone: 'head', on: ['fur'], kind: 'sphere', at: [0.21, 0.1, 0.24], radius: 0.06, color: '#ff9db0', soft: 0.6, opacity: 0.75 },
81
+ ],
82
+ eyes: {
83
+ kind: 'ball',
84
+ bone: 'head',
85
+ at: [[-0.125, 0.22, 0.2], [0.125, 0.22, 0.2]],
86
+ radius: 0.088,
87
+ iris: '#8ccf4d',
88
+ irisSize: 0.78,
89
+ pupilSize: 0.42,
90
+ pupilAspect: 0.5,
91
+ lid: 'fur',
92
+ },
93
+ face: {
94
+ kind: 'mouth',
95
+ bone: 'head',
96
+ on: ['cream'],
97
+ at: [0, 0.06, 0.29],
98
+ width: 0.045,
99
+ color: '#5b2630',
100
+ tongue: '#ff8ea3',
101
+ },
102
+ anchors: {
103
+ top: { bone: 'head', at: [0.2, 0.42, 0.08] },
104
+ mouth: { bone: 'head', at: [0, 0.06, 0.32] },
105
+ ear: { bone: 'head', at: [-0.34, 0.25, 0] },
106
+ feet: { bone: 'root', at: [0, 0.03, 0.18] },
107
+ tail: { bone: 'tail2', at: [0, 0.12, 0] },
108
+ },
109
+ acting: {
110
+ idle: { tail0: { rz: [-0.5, 0.15, 0.4, 0] } },
111
+ /* a paw up to the chin, the tail tip tapping */
112
+ thinking: {
113
+ pawR: { rx: -1.75, rz: 0.35 },
114
+ tail2: { rx: [0.25, 0.3, 1.6, 0] },
115
+ earL: { ry: 0.5 },
116
+ },
117
+ /* both ears swivel forward, one turned to catch the sound */
118
+ listening: {
119
+ earL: { rx: -0.35, ry: -0.6 },
120
+ earR: { rx: -0.35 },
121
+ tail0: { rz: -0.35 },
122
+ },
123
+ speaking: {
124
+ pawL: { rx: [-0.4, 0.25, 1.2, 0] },
125
+ pawR: { rx: [-0.3, 0.25, 1.2, 1.9] },
126
+ tail0: { rz: [-0.5, 0.2, 0.9, 0] },
127
+ },
128
+ /* ears folded flat, tail wrapped round the front */
129
+ sleeping: {
130
+ earL: { rz: 0.5, rx: 0.4 },
131
+ earR: { rz: -0.5, rx: 0.4 },
132
+ tail0: { rx: 0.4, rz: -1.2 },
133
+ tail1: { rx: 0.5 },
134
+ },
135
+ /* kneading: making biscuits, paw after paw */
136
+ working: {
137
+ pawL: { rx: [-0.35, 0.3, 3.4, 0] },
138
+ pawR: { rx: [-0.35, 0.3, 3.4, Math.PI] },
139
+ earL: { rx: -0.25 },
140
+ earR: { rx: -0.25 },
141
+ tail2: { rx: [0.25, 0.2, 1.7, 0] },
142
+ },
143
+ /* airplane ears and a tail stood straight up, bristling */
144
+ error: {
145
+ earL: { rz: 1.1, rx: 0.3 },
146
+ earR: { rz: -1.1, rx: 0.3 },
147
+ tail0: { rx: [-0.9, 0.05, 12, 0], rz: 0 },
148
+ tail1: { rx: 0.3 },
149
+ tail2: { rx: 0.2 },
150
+ },
151
+ surprised: {
152
+ earL: { rz: -0.1, rx: -0.2 },
153
+ earR: { rz: 0.1, rx: -0.2 },
154
+ pawL: { rx: -1.4, rz: -0.4 },
155
+ pawR: { rx: -1.4, rz: 0.4 },
156
+ tail0: { rx: -0.9, rz: 0 },
157
+ },
158
+ celebrating: {
159
+ pawL: { rx: [-2.2, 0.35, 4, 0], rz: -0.5 },
160
+ pawR: { rx: [-2.2, 0.35, 4, Math.PI], rz: 0.5 },
161
+ tail0: { rz: [-0.4, 0.5, 2.6, 0] },
162
+ },
163
+ /* ears droop out to the sides, the tail lies flat on the floor */
164
+ sad: {
165
+ earL: { rz: 0.95, rx: 0.35 },
166
+ earR: { rz: -0.95, rx: 0.35 },
167
+ tail0: { rx: 0.7, rz: -0.8 },
168
+ tail1: { rx: 0.3 },
169
+ tail2: { rx: 0.1 },
170
+ },
171
+ happy: {
172
+ pawL: { rx: [-1.6, 0.3, 5, 0] },
173
+ pawR: { rx: [-1.6, 0.3, 5, 1.4] },
174
+ tail0: { rz: [-0.5, 0.45, 3, 0] },
175
+ },
176
+ },
177
+ fx: {
178
+ happy: [{ glyph: 'heart', anchor: 'top', rate: 1.2, spread: 0.15, velocity: [0, 0.22, 0.05], jitter: 0.12, wobble: 0.06, life: [1, 1.3], size: [0.04, 0.07], color: '#ff86a2' }],
179
+ },
180
+ };
181
+
182
+ export default miso;
@@ -0,0 +1,78 @@
1
+ import type { CharacterSpec } from 'wobnimo';
2
+
3
+ /** A drop of jelly with a sprout on top: all squash, stretch and wobble. */
4
+ export const mochi: CharacterSpec = {
5
+ id: 'mochi',
6
+ name: 'Mochi',
7
+ tagline: 'Translucent jelly that squashes and splashes, with a propeller sprout',
8
+ accent: '#1fae8a',
9
+ frame: { target: 0.56, radius: 0.8 },
10
+ bound: { y: 0.5, radius: 0.82 },
11
+ motion: { hop: 0.17, squash: 1.9, snap: 0.9, talkSquash: 1.3 },
12
+ materials: {
13
+ jelly: { color: '#3fcf9f', f0: 0.06, spec: 1.6, shininess: 140, rim: 0.7, sss: 0.55, sssColor: '#9effd9', gloss: 0.9 },
14
+ bead: { color: '#120d18', f0: 0.06, spec: 2.2, shininess: 400, rim: 0.2, gloss: 1 },
15
+ leaf: { color: '#5bbf3a', f0: 0.04, spec: 0.7, shininess: 50, rim: 0.6, sss: 0.25, sssColor: '#c8ff7a' },
16
+ },
17
+ bones: [
18
+ { name: 'body', pivot: [0, 0, 0], drive: { rx: [['pitch', -0.35]], ry: [['yaw', 0.55]], rz: [['roll', 0.6]] } },
19
+ { name: 'sprout', parent: 'body', pivot: [0, 0.83, -0.02], jiggle: { axis: [0, 1, 0], length: 0.16, freq: 2.2, damping: 0.09 } },
20
+ ],
21
+ parts: [
22
+ { bone: 'body', shape: 'sphere', at: [0, 0.41, 0], radius: 0.42, material: 'jelly' },
23
+ { bone: 'body', shape: 'ellipsoid', at: [0, 0.17, 0], radii: [0.5, 0.17, 0.47], blend: 0.24, material: 'jelly' },
24
+ { bone: 'body', shape: 'roundCone', from: [0, 0.62, 0], to: [0, 0.83, -0.02], r1: 0.17, r2: 0.035, blend: 0.22, material: 'jelly' },
25
+ { bone: 'sprout', shape: 'capsule', from: [0, -0.02, 0], to: [0, 0.09, 0], radius: 0.014, material: 'leaf' },
26
+ { bone: 'sprout', shape: 'ellipsoid', at: [-0.065, 0.11, 0], rot: [0, 0.3, 0.5], radii: [0.075, 0.018, 0.042], blend: 0.015, material: 'leaf' },
27
+ { bone: 'sprout', shape: 'ellipsoid', at: [0.07, 0.12, 0], rot: [0, -0.3, -0.45], radii: [0.08, 0.018, 0.045], blend: 0.015, material: 'leaf' },
28
+ ],
29
+ paints: [
30
+ { bone: 'body', on: ['jelly'], kind: 'sphere', at: [-0.25, 0.32, 0.31], radius: 0.07, color: '#ff8fa8', soft: 0.6, opacity: 0.8 },
31
+ { bone: 'body', on: ['jelly'], kind: 'sphere', at: [0.25, 0.32, 0.31], radius: 0.07, color: '#ff8fa8', soft: 0.6, opacity: 0.8 },
32
+ ],
33
+ eyes: {
34
+ kind: 'bead',
35
+ bone: 'body',
36
+ at: [[-0.14, 0.43, 0.385], [0.14, 0.43, 0.385]],
37
+ radii: [0.045, 0.066, 0.03],
38
+ material: 'bead',
39
+ },
40
+ face: {
41
+ kind: 'mouth',
42
+ bone: 'body',
43
+ on: ['jelly'],
44
+ at: [0, 0.32, 0.4],
45
+ width: 0.065,
46
+ color: '#173528',
47
+ tongue: '#ff7d97',
48
+ },
49
+ anchors: {
50
+ top: { bone: 'body', at: [0.16, 0.86, 0.1] },
51
+ mouth: { bone: 'body', at: [0, 0.32, 0.42] },
52
+ ear: { bone: 'body', at: [-0.42, 0.45, 0] },
53
+ feet: { bone: 'root', at: [0, 0.05, 0.25] },
54
+ },
55
+ acting: {
56
+ idle: { sprout: { rz: [0, 0.1, 0.6, 0] } },
57
+ /* the sprout spins like a propeller while it thinks */
58
+ thinking: { sprout: { rx: -0.15, ry: [0, 0, 0, 0, 7] } },
59
+ listening: { sprout: { rx: -0.4, rz: 0.15 } },
60
+ speaking: { sprout: { rz: [0, 0.2, 2.4, 0] } },
61
+ sleeping: { sprout: { rx: 0.85, rz: 0.35 } },
62
+ working: { sprout: { ry: [0, 0, 0, 0, 3] } },
63
+ error: { sprout: { rx: 0.45, rz: [0.3, 0.15, 12, 0] } },
64
+ surprised: { sprout: { rx: -0.3 } },
65
+ celebrating: { sprout: { ry: [0, 0, 0, 0, 18] } },
66
+ /* the sprout wilts */
67
+ sad: { sprout: { rx: 1.1, rz: 0.5 } },
68
+ happy: { sprout: { ry: [0, 0, 0, 0, 16] } },
69
+ },
70
+ fx: {
71
+ replace: ['land'],
72
+ /* it splashes when it lands */
73
+ land: [{ glyph: 'drop', anchor: 'feet', rate: 7, spread: 0.18, velocity: [0, 0.65, 0.05], jitter: 0.7, gravity: 3.2, life: [0.45, 0.6], size: [0.035, 0.022], color: '#55d6ad', align: true }],
74
+ 'enter:happy': [{ glyph: 'drop', anchor: 'top', rate: 5, velocity: [0, 0.7, 0.05], jitter: 0.9, gravity: 3, life: [0.5, 0.7], size: [0.035, 0.02], color: '#6fe3bd', align: true }],
75
+ },
76
+ };
77
+
78
+ export default mochi;
@@ -0,0 +1,174 @@
1
+ import type { CharacterSpec, PartSpec } from 'wobnimo';
2
+
3
+ /** A penguin chick in a knitted scarf: a satin coat, a white face, flippers that flap. */
4
+ export const pebble: CharacterSpec = {
5
+ id: 'pebble',
6
+ name: 'Pebble',
7
+ tagline: 'A penguin chick in a knitted scarf: satin coat, waddling walk, flippers that flap when it is happy',
8
+ accent: '#3d5a9e',
9
+ frame: { target: 0.56, radius: 0.76 },
10
+ bound: { y: 0.52, radius: 0.74 },
11
+ motion: { hop: 0.12, squash: 1.2, snap: 1.05, talkSquash: 0.45 },
12
+ materials: {
13
+ /* a short, dense coat: a satin sheen over very fine down */
14
+ coat: {
15
+ color: '#27324f', f0: 0.04, spec: 0.7, shininess: 46, rim: 1, sheen: 0.55, gloss: 0.35,
16
+ surface: { kind: 'fur', scale: 130, strength: 0.28, bone: 'head' },
17
+ },
18
+ bodyCoat: {
19
+ color: '#27324f', shadeOf: 'coat', f0: 0.04, spec: 0.7, shininess: 46, rim: 1, sheen: 0.55, gloss: 0.35,
20
+ surface: { kind: 'fur', scale: 130, strength: 0.28 },
21
+ },
22
+ flipper: { color: '#222b45', shadeOf: 'coat', f0: 0.04, spec: 0.8, shininess: 50, rim: 0.9, sheen: 0.5, gloss: 0.4 },
23
+ beak: { color: '#ffa53d', f0: 0.05, spec: 1, shininess: 80, rim: 0.4, gloss: 0.6 },
24
+ mouth: { color: '#5d1a22', f0: 0.04, spec: 0.5, shininess: 30, rim: 0 },
25
+ feet: { color: '#ff9b3d', f0: 0.04, spec: 0.7, shininess: 50, rim: 0.35, gloss: 0.4, sss: 0.25, sssColor: '#ffc68a' },
26
+ /* chunky red knit: a pebbled surface with dark seams reads as stitches */
27
+ knit: {
28
+ color: '#e8433f', f0: 0.02, spec: 0.15, shininess: 10, rim: 0.7, sheen: 0.7,
29
+ surface: { kind: 'scales', scale: 42, strength: 0.75, color: '#a8242a' },
30
+ },
31
+ knitStripe: { color: '#fff2e6', f0: 0.02, spec: 0.15, shininess: 10, rim: 0.6, sheen: 0.7 },
32
+ },
33
+ bones: [
34
+ /* the body rolls side to side as it shifts its weight: the waddle */
35
+ { name: 'body', pivot: [0, 0, 0], drive: { ry: [['yaw', 0.2]], rz: [['roll', 0.35]] }, wave: { rz: [0.035, 0.9, 0] } },
36
+ { name: 'head', parent: 'body', pivot: [0, 0.6, 0.01], drive: { rx: [['pitch', -1]], ry: [['yaw', 0.8]], rz: [['roll', 0.7]] } },
37
+ { name: 'beak', parent: 'head', pivot: [0, 0.12, 0.27], drive: { rx: [['talk', -0.22]] } },
38
+ { name: 'jaw', parent: 'head', pivot: [0, 0.12, 0.27], drive: { rx: [['talk', 0.75]] } },
39
+ /* a little crest of down on top */
40
+ { name: 'tuft', parent: 'head', pivot: [0, 0.42, 0.02], rest: { rx: -0.2 }, jiggle: { axis: [0, 1, 0], length: 0.1, freq: 3.4, damping: 0.15 } },
41
+ {
42
+ name: 'flipperL', parent: 'body', pivot: [-0.3, 0.5, 0], rest: { rz: -0.2 },
43
+ drive: { rz: [['flap', -1.4]] }, jiggle: { axis: [0, -1, 0], length: 0.26, freq: 3.4, damping: 0.3, maxAngle: 0.45 },
44
+ },
45
+ {
46
+ name: 'flipperR', parent: 'body', pivot: [0.3, 0.5, 0], rest: { rz: 0.2 },
47
+ drive: { rz: [['flap', 1.4]] }, jiggle: { axis: [0, -1, 0], length: 0.26, freq: 3.4, damping: 0.3, maxAngle: 0.45 },
48
+ },
49
+ /* the scarf's loose end hangs over the shoulder and swings */
50
+ { name: 'scarf', parent: 'body', pivot: [0.13, 0.56, 0.25], rest: { rz: 0.12, rx: -0.15 }, jiggle: { axis: [0, -1, 0], length: 0.2, freq: 2.4, damping: 0.16, maxAngle: 0.7 } },
51
+ { name: 'tail', parent: 'body', pivot: [0, 0.1, -0.27], rest: { rx: -1.2 }, jiggle: { axis: [0, 1, 0], length: 0.08, freq: 3, damping: 0.2 } },
52
+ ],
53
+ parts: [
54
+ /* an egg of a body and a big round head, blended into one */
55
+ { bone: 'body', shape: 'ellipsoid', at: [0, 0.34, -0.01], radii: [0.32, 0.34, 0.29], material: 'bodyCoat' },
56
+ { bone: 'head', shape: 'sphere', at: [0, 0.16, 0], radius: 0.28, blend: 0.14, material: 'coat' },
57
+ /* the scarf: a fat knitted collar and a striped end */
58
+ { bone: 'body', shape: 'ellipsoid', at: [0, 0.575, 0.005], radii: [0.3, 0.078, 0.28], material: 'knit' },
59
+ { bone: 'scarf', shape: 'roundBox', at: [0, -0.1, 0.01], half: [0.05, 0.1, 0.018], round: 0.016, material: 'knit' },
60
+ { bone: 'scarf', shape: 'roundBox', at: [0, -0.195, 0.01], half: [0.052, 0.018, 0.02], round: 0.012, material: 'knitStripe' },
61
+ /* a small beak in two halves */
62
+ { bone: 'head', shape: 'ellipsoid', at: [0, 0.12, 0.29], radii: [0.035, 0.02, 0.025], material: 'mouth' },
63
+ { bone: 'beak', shape: 'ellipsoid', at: [0, 0, 0.035], rot: [0.15, 0, 0], radii: [0.05, 0.034, 0.05], clip: { normal: [0, -1, 0] }, material: 'beak' },
64
+ { bone: 'beak', shape: 'ellipsoid', at: [0, 0, 0.035], rot: [0.15, 0, 0], radii: [0.041, 0.028, 0.042], clip: { normal: [0, -1, 0], offset: 0.003 }, material: 'mouth' },
65
+ { bone: 'jaw', shape: 'ellipsoid', at: [0, 0, 0.026], radii: [0.043, 0.025, 0.044], clip: { normal: [0, 1, 0] }, material: 'beak' },
66
+ { bone: 'jaw', shape: 'ellipsoid', at: [0, 0, 0.026], radii: [0.035, 0.019, 0.036], clip: { normal: [0, 1, 0], offset: 0.003 }, material: 'mouth' },
67
+ { bone: 'tuft', shape: 'roundCone', from: [0, -0.03, 0], to: [0.01, 0.07, 0.02], r1: 0.035, r2: 0.008, blend: 0.03, material: 'coat' },
68
+ { bone: 'tuft', shape: 'roundCone', from: [0, -0.03, 0], to: [-0.04, 0.05, -0.02], r1: 0.028, r2: 0.007, blend: 0.03, material: 'coat' },
69
+ /* flippers: flat, tapered, lying against the sides */
70
+ { bone: 'flipperL', shape: 'ellipsoid', at: [-0.02, -0.16, 0.02], rot: [0, 0, -0.12], radii: [0.045, 0.2, 0.11], blend: 0.02, material: 'flipper' },
71
+ { bone: 'flipperR', shape: 'ellipsoid', at: [0.02, -0.16, 0.02], rot: [0, 0, 0.12], radii: [0.045, 0.2, 0.11], blend: 0.02, material: 'flipper' },
72
+ { bone: 'tail', shape: 'ellipsoid', at: [0, 0.05, 0], radii: [0.08, 0.07, 0.025], blend: 0.03, material: 'bodyCoat' },
73
+ /* big orange feet, three soft toes each */
74
+ ...[-1, 1].flatMap((s): PartSpec[] => [
75
+ { bone: 'root', shape: 'ellipsoid', at: [s * 0.13, 0.03, 0.17], rot: [0, s * 0.25, 0], radii: [0.1, 0.03, 0.11], material: 'feet' },
76
+ ...[-1, 0, 1].map((t): PartSpec => ({
77
+ bone: 'root', shape: 'sphere', at: [s * 0.16 + t * 0.055, 0.03, 0.26 - Math.abs(t) * 0.02], radius: 0.034, blend: 0.03, material: 'feet',
78
+ })),
79
+ ]),
80
+ ],
81
+ paints: [
82
+ /* a white belly and a heart-shaped white face */
83
+ { bone: 'body', on: ['bodyCoat'], kind: 'ellipse', at: [0, 0.3, 0.08], radii: [0.24, 0.27], color: '#f8f6f0', soft: 0.12 },
84
+ { bone: 'head', on: ['coat'], kind: 'sphere', at: [-0.1, 0.13, 0.22], radius: 0.14, color: '#f8f6f0', soft: 0.12 },
85
+ { bone: 'head', on: ['coat'], kind: 'sphere', at: [0.1, 0.13, 0.22], radius: 0.14, color: '#f8f6f0', soft: 0.12 },
86
+ { bone: 'head', on: ['coat'], kind: 'ellipse', at: [0, 0.02, 0.1], radii: [0.17, 0.08], color: '#f8f6f0', soft: 0.2 },
87
+ { bone: 'head', on: ['coat'], kind: 'sphere', at: [-0.17, 0.06, 0.2], radius: 0.05, color: '#ff9eb0', soft: 0.6, opacity: 0.8 },
88
+ { bone: 'head', on: ['coat'], kind: 'sphere', at: [0.17, 0.06, 0.2], radius: 0.05, color: '#ff9eb0', soft: 0.6, opacity: 0.8 },
89
+ /* a white stripe across the scarf's end, knitted in */
90
+ { bone: 'scarf', on: ['knit'], kind: 'ellipse', at: [0, -0.12, 0], radii: [0.08, 0.018], color: '#fff2e6', soft: 0.15 },
91
+ ],
92
+ eyes: {
93
+ kind: 'ball',
94
+ bone: 'head',
95
+ at: [[-0.1, 0.18, 0.23], [0.1, 0.18, 0.23]],
96
+ radius: 0.066,
97
+ iris: '#1d2233',
98
+ irisSize: 0.8,
99
+ pupilSize: 0.5,
100
+ lid: 'coat',
101
+ },
102
+ anchors: {
103
+ top: { bone: 'head', at: [0.12, 0.44, 0.06] },
104
+ mouth: { bone: 'head', at: [0, 0.11, 0.36] },
105
+ ear: { bone: 'head', at: [-0.3, 0.18, 0] },
106
+ feet: { bone: 'root', at: [0, 0.02, 0.17] },
107
+ chest: { bone: 'body', at: [0, 0.4, 0.3] },
108
+ },
109
+ acting: {
110
+ idle: { tail: { rz: [0, 0.2, 0.9, 0] } },
111
+ /* a flipper tip to the beak */
112
+ thinking: {
113
+ flipperR: { rz: 1.2, rx: -1.1, ry: -0.3 },
114
+ head: { rz: 0.1 },
115
+ },
116
+ listening: {
117
+ flipperL: { rz: -0.9, rx: -0.3 },
118
+ tuft: { rx: -0.35 },
119
+ },
120
+ speaking: {
121
+ flipperL: { rz: [-0.15, 0.15, 1.8, 0] },
122
+ flipperR: { rz: [0.15, 0.15, 1.8, 1.5] },
123
+ },
124
+ /* flippers folded over the belly, tucked into the scarf */
125
+ sleeping: {
126
+ flipperL: { ry: 0.6, rz: 0.2 },
127
+ flipperR: { ry: -0.6, rz: -0.2 },
128
+ tuft: { rx: 0.5 },
129
+ },
130
+ /* tapping away with both flipper tips */
131
+ working: {
132
+ flipperL: { rx: [-0.7, 0.15, 6, 0], rz: 0.2 },
133
+ flipperR: { rx: [-0.7, 0.15, 6, Math.PI], rz: -0.2 },
134
+ head: { rx: 0.12 },
135
+ },
136
+ /* flippers stuck straight out, trembling */
137
+ error: {
138
+ flipperL: { rz: [-1.25, 0.08, 13, 0] },
139
+ flipperR: { rz: [1.25, 0.08, 13, 1] },
140
+ tuft: { rx: -0.6 },
141
+ },
142
+ surprised: {
143
+ flipperL: { rz: -1.6, rx: -0.3 },
144
+ flipperR: { rz: 1.6, rx: -0.3 },
145
+ tuft: { rx: -0.7 },
146
+ },
147
+ /* penguins flap when they are delighted */
148
+ celebrating: {
149
+ flipperL: { rz: [-1.1, 0.55, 8, 0] },
150
+ flipperR: { rz: [1.1, 0.55, 8, 0] },
151
+ tail: { rz: [0, 0.4, 4, 0] },
152
+ },
153
+ /* flippers hang, the crest flops */
154
+ sad: {
155
+ flipperL: { rz: 0.18 },
156
+ flipperR: { rz: -0.18 },
157
+ tuft: { rx: 0.8 },
158
+ scarf: { rx: 0.1 },
159
+ },
160
+ happy: {
161
+ flipperL: { rz: [-0.8, 0.6, 9, 0] },
162
+ flipperR: { rz: [0.8, 0.6, 9, 0] },
163
+ tail: { rz: [0, 0.35, 5, 0] },
164
+ },
165
+ },
166
+ fx: {
167
+ replace: ['land'],
168
+ /* it lands in snow */
169
+ land: [{ glyph: 'puff', anchor: 'feet', rate: 8, spread: 0.12, velocity: [0, 0.06, 0], jitter: 0.34, drag: 3.5, life: [0.5, 0.75], size: [0.05, 0.12], color: '#eef4ff' }],
170
+ celebrating: [{ glyph: 'sparkle', anchor: 'top', rate: 3, spread: 0.4, velocity: [0, -0.05, 0], jitter: 0.08, wobble: 0.08, life: [1.4, 1.8], size: [0.04, 0.01], spin: 1.2, color: '#dff0ff' }],
171
+ },
172
+ };
173
+
174
+ export default pebble;
@@ -0,0 +1,170 @@
1
+ import type { CharacterSpec } from 'wobnimo';
2
+
3
+ /** A round songbird chick: soft feathers, flapping wings, a beak that talks. */
4
+ export const pip: CharacterSpec = {
5
+ id: 'pip',
6
+ name: 'Pip',
7
+ tagline: 'Sings with a real beak, snaps its head like a bird, flaps',
8
+ accent: '#e8892a',
9
+ frame: { target: 0.66, radius: 0.86 },
10
+ bound: { y: 0.62, radius: 0.92 },
11
+ motion: { hop: 0.13, squash: 1.1, snap: 1.25, snapLook: 1, talkSquash: 0.5 },
12
+ materials: {
13
+ feather: { color: '#f4a63c', f0: 0.03, spec: 0.22, shininess: 14, rim: 0.9, sheen: 0.55 },
14
+ wing: { color: '#d8692a', shadeOf: 'feather', f0: 0.03, spec: 0.25, shininess: 16, rim: 0.8, sheen: 0.5 },
15
+ beak: { color: '#ff7a45', f0: 0.05, spec: 0.9, shininess: 70, rim: 0.4, gloss: 0.6 },
16
+ feet: { color: '#e9683b', f0: 0.04, spec: 0.6, shininess: 40, rim: 0.3 },
17
+ mouth: { color: '#6b1a26', f0: 0.04, spec: 0.6, shininess: 40, rim: 0 },
18
+ tongue: { color: '#ff7f91', f0: 0.05, spec: 1, shininess: 60, rim: 0.2, gloss: 0.6 },
19
+ },
20
+ bones: [
21
+ { name: 'body', pivot: [0, 0, 0], drive: { rz: [['roll', 0.3]], rx: [['pitch', -0.12]] } },
22
+ { name: 'head', parent: 'body', pivot: [0, 0.62, 0], drive: { rx: [['pitch', -1]], ry: [['yaw', 0.9]], rz: [['roll', 0.8]] } },
23
+ /* the beak opens both ways: the jaw drops and the top lifts a little */
24
+ { name: 'beak', parent: 'head', pivot: [0, 0.14, 0.33], drive: { rx: [['talk', -0.24]] } },
25
+ { name: 'jaw', parent: 'head', pivot: [0, 0.14, 0.33], drive: { rx: [['talk', 0.8]] } },
26
+ { name: 'tuft', parent: 'head', pivot: [0, 0.5, 0.04], rest: { rx: 0.25 }, jiggle: { axis: [0, 1, 0], length: 0.14, freq: 3, damping: 0.14 } },
27
+ {
28
+ name: 'wingL', parent: 'body', pivot: [-0.38, 0.6, -0.02],
29
+ drive: { rz: [['flap', -1.5]] }, wave: { rz: [0.04, 0.8, 0] },
30
+ jiggle: { axis: [0, -1, 0], length: 0.3, freq: 3.2, damping: 0.3, maxAngle: 0.5 },
31
+ },
32
+ {
33
+ name: 'wingR', parent: 'body', pivot: [0.38, 0.6, -0.02],
34
+ drive: { rz: [['flap', 1.5]] }, wave: { rz: [-0.04, 0.8, 1.1] },
35
+ jiggle: { axis: [0, -1, 0], length: 0.3, freq: 3.2, damping: 0.3, maxAngle: 0.5 },
36
+ },
37
+ { name: 'tail', parent: 'body', pivot: [0, 0.3, -0.36], rest: { rx: -0.95 }, jiggle: { axis: [0, 1, 0], length: 0.18, freq: 2.6, damping: 0.18 } },
38
+ ],
39
+ parts: [
40
+ { bone: 'body', shape: 'ellipsoid', at: [0, 0.42, 0], radii: [0.45, 0.41, 0.42], material: 'feather' },
41
+ { bone: 'head', shape: 'sphere', at: [0, 0.18, 0.03], radius: 0.35, blend: 0.18, material: 'feather' },
42
+ /* a chick's beak in two halves that hinge apart. Each half is lined
43
+ with a slightly smaller dark copy, so its cut face reads as the inside
44
+ of the mouth; a dark throat fills the gap behind them */
45
+ { bone: 'head', shape: 'ellipsoid', at: [0, 0.14, 0.37], radii: [0.05, 0.03, 0.035], material: 'mouth' },
46
+ { bone: 'beak', shape: 'ellipsoid', at: [0, 0, 0.06], rot: [0.12, 0, 0], radii: [0.076, 0.056, 0.1], clip: { normal: [0, -1, 0] }, material: 'beak' },
47
+ { bone: 'beak', shape: 'ellipsoid', at: [0, 0, 0.06], rot: [0.12, 0, 0], radii: [0.064, 0.048, 0.088], clip: { normal: [0, -1, 0], offset: 0.003 }, material: 'mouth' },
48
+ { bone: 'jaw', shape: 'ellipsoid', at: [0, 0, 0.045], radii: [0.064, 0.04, 0.08], clip: { normal: [0, 1, 0] }, material: 'beak' },
49
+ { bone: 'jaw', shape: 'ellipsoid', at: [0, 0, 0.045], radii: [0.053, 0.032, 0.068], clip: { normal: [0, 1, 0], offset: 0.003 }, material: 'mouth' },
50
+ { bone: 'jaw', shape: 'ellipsoid', at: [0, 0.002, 0.04], radii: [0.034, 0.01, 0.042], material: 'tongue' },
51
+ /* a tuft of three feathers */
52
+ { bone: 'tuft', shape: 'roundCone', from: [0, -0.04, 0], to: [0.015, 0.12, 0.03], r1: 0.045, r2: 0.01, blend: 0.03, material: 'feather' },
53
+ { bone: 'tuft', shape: 'roundCone', from: [0, -0.04, -0.02], to: [-0.05, 0.08, -0.05], r1: 0.035, r2: 0.008, blend: 0.03, material: 'feather' },
54
+ { bone: 'tuft', shape: 'roundCone', from: [0, -0.04, -0.02], to: [0.06, 0.07, -0.04], r1: 0.03, r2: 0.008, blend: 0.03, material: 'feather' },
55
+ /* wings hinge at the shoulder and lie against the body */
56
+ { bone: 'wingL', shape: 'ellipsoid', at: [-0.02, -0.17, 0], rot: [0, 0, -0.18], radii: [0.08, 0.23, 0.2], blend: 0.02, material: 'wing' },
57
+ { bone: 'wingR', shape: 'ellipsoid', at: [0.02, -0.17, 0], rot: [0, 0, 0.18], radii: [0.08, 0.23, 0.2], blend: 0.02, material: 'wing' },
58
+ { bone: 'tail', shape: 'ellipsoid', at: [0, 0.1, 0], radii: [0.14, 0.12, 0.035], blend: 0.04, material: 'wing' },
59
+ /* three toes a foot */
60
+ { bone: 'root', shape: 'capsule', from: [-0.15, 0.03, 0.12], to: [-0.2, 0.025, 0.25], radius: 0.026, material: 'feet' },
61
+ { bone: 'root', shape: 'capsule', from: [-0.15, 0.03, 0.12], to: [-0.12, 0.025, 0.26], radius: 0.026, material: 'feet' },
62
+ { bone: 'root', shape: 'capsule', from: [-0.15, 0.03, 0.12], to: [-0.15, 0.06, 0.02], radius: 0.03, blend: 0.02, material: 'feet' },
63
+ { bone: 'root', shape: 'capsule', from: [0.15, 0.03, 0.12], to: [0.2, 0.025, 0.25], radius: 0.026, material: 'feet' },
64
+ { bone: 'root', shape: 'capsule', from: [0.15, 0.03, 0.12], to: [0.12, 0.025, 0.26], radius: 0.026, material: 'feet' },
65
+ { bone: 'root', shape: 'capsule', from: [0.15, 0.03, 0.12], to: [0.15, 0.06, 0.02], radius: 0.03, blend: 0.02, material: 'feet' },
66
+ ],
67
+ paints: [
68
+ { bone: 'body', on: ['feather'], kind: 'ellipse', at: [0, 0.3, 0], radii: [0.29, 0.28], color: '#fde7c0', soft: 0.07 },
69
+ { bone: 'head', on: ['feather'], kind: 'sphere', at: [-0.22, 0.08, 0.27], radius: 0.075, color: '#ff8c8c', soft: 0.6, opacity: 0.75 },
70
+ { bone: 'head', on: ['feather'], kind: 'sphere', at: [0.22, 0.08, 0.27], radius: 0.075, color: '#ff8c8c', soft: 0.6, opacity: 0.75 },
71
+ ],
72
+ eyes: {
73
+ kind: 'ball',
74
+ bone: 'head',
75
+ at: [[-0.14, 0.24, 0.3], [0.14, 0.24, 0.3]],
76
+ radius: 0.078,
77
+ iris: '#4a2a12',
78
+ irisSize: 0.72,
79
+ pupilSize: 0.42,
80
+ lid: 'feather',
81
+ },
82
+ anchors: {
83
+ top: { bone: 'head', at: [0.14, 0.5, 0.1] },
84
+ mouth: { bone: 'head', at: [0, 0.13, 0.47] },
85
+ ear: { bone: 'head', at: [-0.32, 0.22, 0] },
86
+ feet: { bone: 'root', at: [0, 0.02, 0.12] },
87
+ chest: { bone: 'body', at: [0, 0.45, 0.32] },
88
+ },
89
+ acting: {
90
+ idle: {
91
+ tail: { rx: [0, 0.14, 1.3, 0] },
92
+ },
93
+ /* a wing tip to the chin */
94
+ thinking: {
95
+ wingR: { rz: 1.05, rx: -0.95, ry: -0.35 },
96
+ tuft: { rx: 0.25 },
97
+ tail: { rx: [0, 0.08, 0.5, 0] },
98
+ },
99
+ /* a wing cupped by the ear, the tuft perked */
100
+ listening: {
101
+ wingL: { rz: -1.1, rx: -0.55 },
102
+ tuft: { rx: -0.4 },
103
+ head: { rz: 0.12 },
104
+ },
105
+ /* singing: chin up, wings fluttering, tail keeping time */
106
+ speaking: {
107
+ head: { rx: [-0.14, 0.05, 1.1, 0] },
108
+ wingL: { rz: [-0.18, 0.14, 2.3, 0] },
109
+ wingR: { rz: [0.18, 0.14, 2.3, 1.2] },
110
+ tail: { rx: [0, 0.22, 2.3, 0.5] },
111
+ },
112
+ /* fluffed up, head tucked, wings folded in front */
113
+ sleeping: {
114
+ wingL: { ry: 0.5, rz: 0.12 },
115
+ wingR: { ry: -0.5, rz: -0.12 },
116
+ tuft: { rx: 0.75 },
117
+ },
118
+ /* pecking away: wing tips tapping, head bobbing over the work */
119
+ working: {
120
+ wingL: { rz: [-0.4, 0.18, 6, 0], rx: -0.6 },
121
+ wingR: { rz: [0.4, 0.18, 6, Math.PI], rx: -0.6 },
122
+ head: { rx: [0.1, 0.07, 5.2, 0] },
123
+ },
124
+ /* feathers on end: wings stiff and trembling, tuft and tail up */
125
+ error: {
126
+ wingL: { rz: [-1.0, 0.1, 12, 0] },
127
+ wingR: { rz: [1.0, 0.1, 12, 1] },
128
+ tuft: { rx: -0.5 },
129
+ tail: { rx: -0.45 },
130
+ },
131
+ surprised: {
132
+ wingL: { rz: -1.7 },
133
+ wingR: { rz: 1.7 },
134
+ tuft: { rx: -0.6 },
135
+ tail: { rx: -0.5 },
136
+ },
137
+ celebrating: {
138
+ wingL: { rz: [-1.4, 0.5, 9, 0] },
139
+ wingR: { rz: [1.4, 0.5, 9, 0] },
140
+ tail: { rx: [0, 0.3, 6, 0] },
141
+ tuft: { rx: [0, 0.25, 6, 0] },
142
+ },
143
+ /* everything droops: wings, tuft, tail */
144
+ sad: {
145
+ wingL: { rz: 0.25 },
146
+ wingR: { rz: -0.25 },
147
+ tuft: { rx: 0.9 },
148
+ tail: { rx: 0.5 },
149
+ },
150
+ happy: {
151
+ wingL: { rz: [-0.9, 0.75, 7, 0] },
152
+ wingR: { rz: [0.9, 0.75, 7, 0] },
153
+ tail: { rx: [0, 0.3, 5, 0] },
154
+ tuft: { rx: [0, 0.2, 5, 0] },
155
+ },
156
+ },
157
+ fx: {
158
+ replace: ['syllable'],
159
+ /* it sings: a note on every other syllable */
160
+ syllable: [
161
+ { glyph: 'note', anchor: 'mouth', rate: 1, offset: [0.12, -0.03, 0.02], velocity: [0.2, 0.13, 0.05], jitter: 0.06, wobble: 0.07, life: [1.1, 1.5], size: [0.045, 0.075], rotation: -0.15, color: '#f08a3c' },
162
+ ],
163
+ happy: [{ glyph: 'note', anchor: 'mouth', rate: 1.6, velocity: [0, 0.24, 0.05], jitter: 0.25, wobble: 0.07, life: [1, 1.3], size: [0.04, 0.07], rotation: 0.15, color: '#e8664a' }],
164
+ 'enter:happy': [
165
+ { glyph: 'feather', anchor: 'chest', rate: 4, spread: 0.12, velocity: [0, 0.18, 0.12], jitter: 0.45, gravity: 0.12, drag: 1.4, wobble: 0.14, life: [1.8, 2.4], size: [0.05, 0.05], spin: 1.6, color: '#f6b04a' },
166
+ ],
167
+ },
168
+ };
169
+
170
+ export default pip;