@kids-games/core 0.1.0 → 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Matt Atencio
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,282 @@
1
+ # @kids-games/core
2
+
3
+ Shared framework for [Kids Corner](https://kids.mattatencio.com) educational games (ages 2-6). Provides voice personas with pre-generated TTS audio, sound effects, celebration animations, reusable React components, and design tokens.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @kids-games/core
9
+ ```
10
+
11
+ Peer dependencies (install if not already present):
12
+
13
+ ```bash
14
+ npm install react@^19 react-dom@^19
15
+ ```
16
+
17
+ ## Modules
18
+
19
+ The package is split into five independently importable modules:
20
+
21
+ | Module | Import | Description |
22
+ |--------|--------|-------------|
23
+ | **Voice** | `@kids-games/core/voice` | Persona system, audio playback, React provider & hooks |
24
+ | **SFX** | `@kids-games/core/sfx` | Synthesized sound effects via Web Audio API |
25
+ | **Celebrations** | `@kids-games/core/celebrations` | Confetti particle system with physics |
26
+ | **Components** | `@kids-games/core/components` | Ready-to-use React UI components |
27
+ | **Tokens** | `@kids-games/core/tokens` | Design tokens (colors, spacing, touch targets) |
28
+
29
+ ---
30
+
31
+ ## Voice
32
+
33
+ Five kid-friendly personas, each mapped to an OpenAI TTS voice with a Web Speech API fallback:
34
+
35
+ | Persona | Voice | Character |
36
+ |---------|-------|-----------|
37
+ | Sunny | shimmer | Warm, encouraging guide |
38
+ | Bloop | fable | Silly, playful buddy |
39
+ | Maple | nova | Calm, nurturing mentor |
40
+ | Fizz | echo | Energetic, excited hype |
41
+ | Pip | alloy | Gentle, curious explorer |
42
+
43
+ ### Provider setup
44
+
45
+ Wrap your app (or game layout) with `KidsAudioProvider`:
46
+
47
+ ```tsx
48
+ import { KidsAudioProvider } from "@kids-games/core/voice";
49
+
50
+ export default function Layout({ children }) {
51
+ return (
52
+ <KidsAudioProvider storagePrefix="color-mixer" audioBasePath="/audio">
53
+ {children}
54
+ </KidsAudioProvider>
55
+ );
56
+ }
57
+ ```
58
+
59
+ ### Hooks
60
+
61
+ ```tsx
62
+ import { useVoice, usePersona, useSoundEffects, useCelebrate } from "@kids-games/core/voice";
63
+
64
+ function GameScreen() {
65
+ const { playPhrase, muted, toggleMute } = useVoice();
66
+ const persona = usePersona("sunny");
67
+ const { playCorrect, playIncorrect } = useSoundEffects();
68
+ const celebrate = useCelebrate("sunny");
69
+
70
+ const handleAnswer = (correct: boolean) => {
71
+ if (correct) {
72
+ playCorrect();
73
+ celebrate("big");
74
+ playPhrase("well-done", "sunny");
75
+ } else {
76
+ playIncorrect();
77
+ playPhrase("try-again", "sunny");
78
+ }
79
+ };
80
+
81
+ return <button onClick={() => handleAnswer(true)}>Answer</button>;
82
+ }
83
+ ```
84
+
85
+ ### Persona data
86
+
87
+ ```tsx
88
+ import { PERSONAS, getPersona, getRandomPhrase } from "@kids-games/core/voice";
89
+
90
+ const sunny = getPersona("sunny");
91
+ // { name: "Sunny", openaiVoice: "shimmer", ... }
92
+
93
+ const phrase = getRandomPhrase("sunny", "celebration");
94
+ // Random celebration phrase from Sunny's pool
95
+ ```
96
+
97
+ ---
98
+
99
+ ## SFX
100
+
101
+ Synthesized sound effects using the Web Audio API. No audio files needed.
102
+
103
+ ```tsx
104
+ import { playTap, playPop, playCorrect, playIncorrect, playWhoosh, playCelebrationChime } from "@kids-games/core/sfx";
105
+
106
+ // All functions take an AudioContext
107
+ const ctx = new AudioContext();
108
+ playTap(ctx);
109
+ playPop(ctx);
110
+ playCorrect(ctx);
111
+ playIncorrect(ctx);
112
+ playWhoosh(ctx);
113
+ playCelebrationChime(ctx);
114
+ ```
115
+
116
+ When using with the voice module, get the context from the provider:
117
+
118
+ ```tsx
119
+ const { getContext } = useVoice();
120
+ playTap(getContext());
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Celebrations
126
+
127
+ Confetti particle system with three intensity levels.
128
+
129
+ ```tsx
130
+ import { createConfettiBurst, tickConfetti } from "@kids-games/core/celebrations";
131
+ import { CELEBRATION_CONFIGS } from "@kids-games/core/celebrations";
132
+ import type { CelebrationLevel } from "@kids-games/core/components";
133
+
134
+ // Create particles
135
+ const config = CELEBRATION_CONFIGS["big"]; // small | medium | big
136
+ let particles = createConfettiBurst(config.particleCount);
137
+
138
+ // Animation loop
139
+ function animate() {
140
+ particles = tickConfetti(particles);
141
+ // render particles...
142
+ if (particles.length > 0) requestAnimationFrame(animate);
143
+ }
144
+ animate();
145
+ ```
146
+
147
+ Or use the ready-made component (see Components below).
148
+
149
+ ---
150
+
151
+ ## Components
152
+
153
+ ### CelebrationOverlay
154
+
155
+ Full-screen confetti overlay with auto-dismiss.
156
+
157
+ ```tsx
158
+ import { CelebrationOverlay } from "@kids-games/core/components";
159
+
160
+ <CelebrationOverlay
161
+ level="big" // "small" | "medium" | "big" | null
162
+ text="Great job!" // optional overlay text
163
+ onComplete={() => setLevel(null)}
164
+ />
165
+ ```
166
+
167
+ ### MuteButton
168
+
169
+ Floating mute/unmute toggle. Requires `KidsAudioProvider` as an ancestor.
170
+
171
+ ```tsx
172
+ import { MuteButton } from "@kids-games/core/components";
173
+
174
+ <MuteButton size={48} className="custom-class" />
175
+ ```
176
+
177
+ ### PersonaPicker
178
+
179
+ Tappable persona cards with localStorage persistence.
180
+
181
+ ```tsx
182
+ import { PersonaPicker } from "@kids-games/core/components";
183
+
184
+ <PersonaPicker
185
+ availablePersonas={["sunny", "bloop", "maple"]}
186
+ onSelect={(id) => setActivePersona(id)}
187
+ storageKey="my-game-persona"
188
+ />
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Tokens
194
+
195
+ Design tokens optimized for children ages 2-6.
196
+
197
+ ### Colors
198
+
199
+ ```tsx
200
+ import { COLORS } from "@kids-games/core/tokens";
201
+
202
+ COLORS.primary.red // "#FF6B6B"
203
+ COLORS.background.warm // "#FFF8E7"
204
+ COLORS.feedback.success // "#4CAF50"
205
+ COLORS.persona.sunny // "#FFD93D"
206
+ ```
207
+
208
+ ### Spacing
209
+
210
+ ```tsx
211
+ import { SPACING } from "@kids-games/core/tokens";
212
+
213
+ SPACING.touchTarget.min // 48 (WCAG minimum)
214
+ SPACING.touchTarget.recommended // 56 (toddler-friendly)
215
+ SPACING.touchTarget.large // 64 (primary actions)
216
+ SPACING.padding.md // 16
217
+ SPACING.gap.comfortable // 16
218
+ SPACING.radius.lg // 16
219
+ SPACING.fontSize.lg // 24
220
+ ```
221
+
222
+ ---
223
+
224
+ ## Generating Voice Audio
225
+
226
+ Each game defines its dialogue in a `voice-script.json` file. The generation script converts these to MP3 files using the OpenAI TTS API.
227
+
228
+ ### 1. Create a voice script
229
+
230
+ ```json
231
+ {
232
+ "lines": [
233
+ { "id": "welcome", "text": "Welcome to Color Mixer!", "persona": "sunny" },
234
+ { "id": "try-again", "text": "Oops, let's try that again!", "persona": "bloop" },
235
+ { "id": "well-done", "text": "Amazing job, you did it!", "persona": "sunny" }
236
+ ]
237
+ }
238
+ ```
239
+
240
+ Save this as `voice-script.json` in your game's root directory.
241
+
242
+ ### 2. Generate audio files
243
+
244
+ ```bash
245
+ OPENAI_API_KEY=sk-... npx tsx node_modules/@kids-games/core/scripts/generate-audio.ts ./
246
+ ```
247
+
248
+ Or from the monorepo root:
249
+
250
+ ```bash
251
+ OPENAI_API_KEY=sk-... npx tsx _core/scripts/generate-audio.ts ./my-game/
252
+ ```
253
+
254
+ This creates `public/audio/<persona>/<id>.mp3` files. Use `--force` to regenerate existing files.
255
+
256
+ ### 3. Reference in your provider
257
+
258
+ ```tsx
259
+ <KidsAudioProvider storagePrefix="my-game" audioBasePath="/audio">
260
+ ```
261
+
262
+ The player resolves audio as `{audioBasePath}/{persona}/{phraseId}.mp3`.
263
+
264
+ ---
265
+
266
+ ## TypeScript
267
+
268
+ All exports are fully typed. Key types:
269
+
270
+ ```tsx
271
+ import type {
272
+ PersonaId, // "sunny" | "bloop" | "maple" | "fizz" | "pip"
273
+ Persona, // Full persona config object
274
+ CelebrationLevel // "small" | "medium" | "big"
275
+ } from "@kids-games/core/voice";
276
+ ```
277
+
278
+ ---
279
+
280
+ ## License
281
+
282
+ [MIT](./LICENSE)
@@ -8,9 +8,18 @@ interface PersonaPickerProps {
8
8
  storageKey?: string;
9
9
  }
10
10
  /**
11
- * Simple character selector for kids. Shows available personas as tappable cards.
12
- * Persists selection to localStorage if storageKey provided.
13
- * Reports initial selection to parent on mount.
11
+ * Persona selector for kids games. Displays available personas as large, tappable
12
+ * cards with emoji avatars and color coding. Persists the user's choice to
13
+ * localStorage and reports the initial selection on mount.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * <PersonaPicker
18
+ * availablePersonas={["sunny", "bloop", "maple"]}
19
+ * onSelect={(id) => setActivePersona(id)}
20
+ * storageKey="color-mixer-persona"
21
+ * />
22
+ * ```
14
23
  */
15
24
  export declare function PersonaPicker({ availablePersonas, onSelect, storageKey, }: PersonaPickerProps): import("react/jsx-runtime").JSX.Element;
16
25
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"PersonaPicker.d.ts","sourceRoot":"","sources":["../../components/PersonaPicker.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,UAAU,kBAAkB;IAC1B,gDAAgD;IAChD,iBAAiB,EAAE,SAAS,EAAE,CAAC;IAC/B,qFAAqF;IACrF,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;IACzC,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAmBD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC5B,iBAAiB,EACjB,QAAQ,EACR,UAAU,GACX,EAAE,kBAAkB,2CAgEpB"}
1
+ {"version":3,"file":"PersonaPicker.d.ts","sourceRoot":"","sources":["../../components/PersonaPicker.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,UAAU,kBAAkB;IAC1B,gDAAgD;IAChD,iBAAiB,EAAE,SAAS,EAAE,CAAC;IAC/B,qFAAqF;IACrF,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;IACzC,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAmBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,EAC5B,iBAAiB,EACjB,QAAQ,EACR,UAAU,GACX,EAAE,kBAAkB,2CAgEpB"}
@@ -18,9 +18,18 @@ const PERSONA_COLORS = {
18
18
  pip: "#FFB6C1",
19
19
  };
20
20
  /**
21
- * Simple character selector for kids. Shows available personas as tappable cards.
22
- * Persists selection to localStorage if storageKey provided.
23
- * Reports initial selection to parent on mount.
21
+ * Persona selector for kids games. Displays available personas as large, tappable
22
+ * cards with emoji avatars and color coding. Persists the user's choice to
23
+ * localStorage and reports the initial selection on mount.
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * <PersonaPicker
28
+ * availablePersonas={["sunny", "bloop", "maple"]}
29
+ * onSelect={(id) => setActivePersona(id)}
30
+ * storageKey="color-mixer-persona"
31
+ * />
32
+ * ```
24
33
  */
25
34
  export function PersonaPicker({ availablePersonas, onSelect, storageKey, }) {
26
35
  const [selected, setSelected] = useState(availablePersonas[0]);
@@ -1 +1 @@
1
- {"version":3,"file":"PersonaPicker.js","sourceRoot":"","sources":["../../components/PersonaPicker.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PersonaPicker.js","sourceRoot":"","sources":["../../components/PersonaPicker.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  export { MuteButton } from "./MuteButton";
2
2
  export { CelebrationOverlay } from "./CelebrationOverlay";
3
3
  export { PersonaPicker } from "./PersonaPicker";
4
+ export type { CelebrationLevel } from "../voice/types";
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kids-games/core",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "description": "Shared framework for Kids Corner games — voice personas, audio playback, celebrations, UI components, and design tokens",
5
5
  "type": "module",
6
6
  "license": "MIT",