@joshtol/emotive-engine 3.4.0 → 3.4.2

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/README.md CHANGED
@@ -8,62 +8,59 @@
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE.md)
9
9
  [![Downloads](https://img.shields.io/npm/dm/@joshtol/emotive-engine.svg)](https://www.npmjs.com/package/@joshtol/emotive-engine)
10
10
 
11
- </div>
11
+ <img src="assets/previews/elemental-gestures.gif" alt="Emotive Engine — 8 elemental shaders, 160+ gestures" width="100%" />
12
12
 
13
- ## Table of Contents
14
-
15
- - [Quick Start](#30-second-quick-start)
16
- - [Features](#features)
17
- - [Demo Gallery](#demo-gallery)
18
- - [Installation](#installation)
19
- - [3D Assets (Models & Textures)](#3d-assets-models--textures)
20
- - [LLM Integration with feel()](#llm-integration-with-feel)
21
- - [Emotions](#emotions)
22
- - [Gestures](#gestures)
23
- - [Elemental Gestures (3D)](#elemental-gestures-3d)
24
- - [3D Geometries](#3d-geometries)
25
- - [Configuration](#configuration)
26
- - [API Reference](#api-reference)
27
- - [Running Locally](#running-locally)
28
- - [Browser Support](#browser-support)
29
- - [Multi-Instance Support](#multi-instance-support)
30
- - [Server-Side Rendering (SSR)](#server-side-rendering-ssr)
31
- - [Performance Tips](#performance-tips)
32
- - [License](#license)
13
+ Real-time character animation engine with **Canvas 2D** and **WebGL 3D**
14
+ rendering.<br/> 8 elemental shader systems. 160+ elemental gestures. One
15
+ replicable pattern.
33
16
 
34
- ---
17
+ **[Live Demo](https://joshtol.github.io/emotive-engine)** ·
18
+ **[Elemental Gestures Demo](https://joshtol.github.io/emotive-engine/examples/3d/elemental-gestures.html)**
19
+ · **[NPM](https://www.npmjs.com/package/@joshtol/emotive-engine)**
35
20
 
36
- ## 30-Second Quick Start
21
+ </div>
37
22
 
38
- ```javascript
39
- import { EmotiveMascot } from '@joshtol/emotive-engine';
23
+ ---
40
24
 
41
- const mascot = new EmotiveMascot();
42
- await mascot.init(document.getElementById('app'));
43
- mascot.start();
44
- mascot.feel('happy, bouncing'); // Natural language control!
45
- ```
25
+ ## Quick Start
46
26
 
47
27
  ```bash
48
28
  npm install @joshtol/emotive-engine
49
29
  ```
50
30
 
51
- [Live Demos](https://joshtol.github.io/emotive-engine) |
52
- [Full Documentation](#api-reference) |
53
- [LLM Integration](./docs/LLM_INTEGRATION.md)
31
+ ### 3D Mode (WebGL)
32
+
33
+ ```javascript
34
+ import { EmotiveMascot3D } from '@joshtol/emotive-engine/3d';
54
35
 
55
- <div align="center">
36
+ const mascot = new EmotiveMascot3D({
37
+ coreGeometry: 'crystal',
38
+ assetBasePath: '/assets', // self-hosted assets (see below)
39
+ });
56
40
 
57
- <img src="assets/previews/3d-demo.gif" alt="Emotive Engine 3D Demo" width="100%" />
41
+ mascot.init(document.getElementById('container'));
42
+ mascot.start();
58
43
 
59
- Real-time character animation engine with **Canvas 2D** and **WebGL 3D**
60
- rendering.
44
+ mascot.setEmotion('joy');
45
+ mascot.express('bounce');
46
+ mascot.morphTo('heart');
47
+ mascot.feel('happy, bouncing'); // Natural language control
48
+ ```
61
49
 
62
- [Live Demos](https://joshtol.github.io/emotive-engine) |
63
- [Documentation](#api-reference) |
64
- [NPM](https://www.npmjs.com/package/@joshtol/emotive-engine)
50
+ 3D mode requires Three.js: `npm install three`
65
51
 
66
- </div>
52
+ ### 2D Mode (Canvas)
53
+
54
+ ```javascript
55
+ import { EmotiveMascot } from '@joshtol/emotive-engine';
56
+
57
+ const mascot = new EmotiveMascot();
58
+ await mascot.init(document.getElementById('container'));
59
+ mascot.start();
60
+ mascot.feel('happy, bouncing');
61
+ ```
62
+
63
+ 2D mode has no dependencies and requires no external assets.
67
64
 
68
65
  ---
69
66
 
@@ -96,19 +93,14 @@ rendering.
96
93
  </tr>
97
94
  </table>
98
95
 
99
- **Shared across both modes:**
100
-
101
- - 15 emotional states with smooth transitions
102
- - 180+ base gestures including directional movements
103
- - **Natural language `feel()` API** for LLM integration
104
- - TypeScript definitions
105
- - Unified API
96
+ **Shared:** 15 emotions · 180+ gestures · Natural language `feel()` API ·
97
+ TypeScript definitions · Unified API
106
98
 
107
99
  ---
108
100
 
109
101
  ## Demo Gallery
110
102
 
111
- ### 3D WebGL Examples
103
+ ### 3D WebGL
112
104
 
113
105
  <table>
114
106
  <tr>
@@ -137,66 +129,70 @@ rendering.
137
129
  </tr>
138
130
  </table>
139
131
 
140
- ### 2D Canvas Examples
132
+ ### 2D Canvas
141
133
 
142
134
  <table>
143
135
  <tr>
144
136
  <td align="center" width="33%">
145
137
  <img src="assets/previews/hello-world.gif" alt="Hello World" width="100%" /><br/>
146
- <strong>Hello World</strong><br/>
147
- <sub>Minimal setup</sub>
138
+ <strong>Hello World</strong>
148
139
  </td>
149
140
  <td align="center" width="33%">
150
141
  <img src="assets/previews/basic-usage.gif" alt="Basic Usage" width="100%" /><br/>
151
- <strong>Basic Usage</strong><br/>
152
- <sub>Emotions and gestures</sub>
142
+ <strong>Basic Usage</strong>
153
143
  </td>
154
144
  <td align="center" width="33%">
155
145
  <img src="assets/previews/breathing.gif" alt="Breathing App" width="100%" /><br/>
156
- <strong>Breathing App</strong><br/>
157
- <sub>Guided breathing</sub>
146
+ <strong>Breathing App</strong>
158
147
  </td>
159
148
  </tr>
160
149
  <tr>
161
150
  <td align="center" width="33%">
162
151
  <img src="assets/previews/events.gif" alt="Events" width="100%" /><br/>
163
- <strong>Event Handling</strong><br/>
164
- <sub>Real-time monitoring</sub>
152
+ <strong>Event Handling</strong>
165
153
  </td>
166
154
  <td align="center" width="33%">
167
155
  <img src="assets/previews/rhythm.gif" alt="Rhythm Sync" width="100%" /><br/>
168
- <strong>Rhythm Sync</strong><br/>
169
- <sub>Beat detection</sub>
170
- </td>
171
- <td align="center" width="33%">
172
- <img src="assets/previews/claude-chat.gif" alt="Claude Chat" width="100%" /><br/>
173
- <strong>LLM Integration</strong><br/>
174
- <sub>Claude sentiment analysis</sub>
156
+ <strong>Rhythm Sync</strong>
175
157
  </td>
176
158
  </tr>
177
159
  </table>
178
160
 
179
161
  ---
180
162
 
181
- ## Installation
163
+ ## 3D Assets
182
164
 
183
- ```bash
184
- npm install @joshtol/emotive-engine
165
+ The npm package ships **JavaScript only**. GLB models, textures, and HDRI maps
166
+ must be self-hosted (~24 MB). They live in `assets/` in this repository.
167
+
168
+ ```javascript
169
+ new EmotiveMascot3D({
170
+ assetBasePath: '/assets', // wherever you host the assets folder
171
+ });
185
172
  ```
186
173
 
187
- **3D mode requires Three.js** as a peer dependency:
174
+ | Hosting Option | `assetBasePath` |
175
+ | --------------------- | --------------------------------------------------- |
176
+ | **Copy to `public/`** | `'/assets'` |
177
+ | **CDN / S3** | `'https://cdn.example.com/emotive-engine/assets'` |
178
+ | **GitHub Pages** | `'https://joshtol.github.io/emotive-engine/assets'` |
188
179
 
189
- ```bash
190
- npm install three
191
180
  ```
181
+ <assetBasePath>/
182
+ ├── models/Elements/ # GLB models for elemental effects
183
+ ├── textures/ # Crystal, Moon, Sun textures
184
+ └── hdri/ # Environment maps (optional)
185
+ ```
186
+
187
+ ---
192
188
 
193
- Or via CDN:
189
+ ## CDN Usage
194
190
 
195
191
  ```html
196
- <!-- 2D Engine (UMD, no dependencies) -->
192
+ <!-- 2D (UMD, no dependencies) -->
197
193
  <script src="https://unpkg.com/@joshtol/emotive-engine/dist/emotive-mascot.umd.js"></script>
198
194
 
199
- <!-- 3D Engine (ESM requires import map for Three.js) -->
195
+ <!-- 3D (ESM, requires Three.js import map) -->
200
196
  <script type="importmap">
201
197
  {
202
198
  "imports": {
@@ -211,343 +207,15 @@ Or via CDN:
211
207
 
212
208
  ---
213
209
 
214
- ## 3D Assets (Models & Textures)
215
-
216
- The npm package ships **JavaScript only** — GLB models, textures, and HDRI maps
217
- are **not** included to keep the package lean (~4 MB vs ~28 MB).
218
-
219
- The assets live in the repository under `assets/models/` and `assets/textures/`.
220
- To use 3D mode, self-host them and point the engine at your copy:
221
-
222
- ```javascript
223
- const mascot = new EmotiveMascot3D({
224
- coreGeometry: 'crystal',
225
- assetBasePath: '/assets', // wherever you host the assets folder
226
- });
227
- ```
228
-
229
- ### Hosting Options
230
-
231
- | Option | Example `assetBasePath` |
232
- | --------------------- | ------------------------------------------------------------------------ |
233
- | **Copy to `public/`** | `'/assets'` |
234
- | **CDN / S3** | `'https://cdn.example.com/emotive-engine/assets'` |
235
- | **GitHub Pages** | `'https://joshtol.github.io/emotive-engine/assets'` |
236
- | **unpkg (repo)** | `'https://raw.githubusercontent.com/joshtol/emotive-engine/main/assets'` |
237
-
238
- The expected directory structure under your `assetBasePath`:
239
-
240
- ```
241
- <assetBasePath>/
242
- ├── models/
243
- │ └── Elements/ # GLB models for elemental effects
244
- ├── textures/
245
- │ ├── Crystal/ # Crystal & heart geometry textures
246
- │ ├── Moon/ # Moon geometry textures
247
- │ └── Sun/ # Sun geometry textures
248
- └── hdri/ # Environment maps (optional, enhances reflections)
249
- ```
250
-
251
- > Assets are available in the repository under `assets/` and `public/hdri/`.
252
-
253
- > **2D mode does not require any external assets** — it works out of the box.
254
-
255
- ---
256
-
257
- ## Quick Start
258
-
259
- ### 3D Mode (WebGL)
260
-
261
- ```javascript
262
- import { EmotiveMascot3D } from '@joshtol/emotive-engine/3d';
263
-
264
- const mascot = new EmotiveMascot3D({
265
- coreGeometry: 'crystal', // crystal, diamond, heart, moon, rough, sphere, star, sun
266
- assetBasePath: '/assets', // path to self-hosted assets (see 3D Assets section)
267
- enableParticles: true,
268
- enablePostProcessing: true,
269
- });
270
-
271
- mascot.init(document.getElementById('container'));
272
- mascot.start();
273
-
274
- // Control emotions and gestures
275
- mascot.setEmotion('joy');
276
- mascot.express('bounce');
277
- mascot.morphTo('heart');
278
- ```
210
+ ## Documentation
279
211
 
280
- ### 2D Mode (Canvas)
281
-
282
- ```javascript
283
- import { EmotiveMascot } from '@joshtol/emotive-engine';
284
-
285
- const mascot = new EmotiveMascot({
286
- canvasId: 'mascot',
287
- defaultEmotion: 'neutral',
288
- });
289
-
290
- await mascot.init(document.getElementById('container'));
291
- mascot.start();
292
-
293
- // Same API as 3D
294
- mascot.setEmotion('joy');
295
- mascot.express('bounce');
296
- ```
297
-
298
- ---
299
-
300
- ## LLM Integration with feel()
301
-
302
- The `feel()` method lets LLMs control the mascot using natural language:
303
-
304
- ```javascript
305
- // Simple emotion
306
- mascot.feel('happy');
307
-
308
- // Emotion with gesture
309
- mascot.feel('curious, leaning in');
310
-
311
- // With undertone modifier
312
- mascot.feel('happy but nervous');
313
-
314
- // With shape morph
315
- mascot.feel('loving, heart shape, sparkle');
316
-
317
- // With intensity
318
- mascot.feel('very angry, shaking');
319
- ```
320
-
321
- The engine parses ~1400 synonyms to understand natural expressions. For full
322
- documentation, see [LLM Integration Guide](./docs/LLM_INTEGRATION.md).
323
-
324
- ### LLM System Prompt Example
325
-
326
- ```
327
- After each response, output: FEEL: <emotion>, <gesture>
328
-
329
- Examples:
330
- - Greeting: FEEL: happy, wave
331
- - Thinking: FEEL: focused, leaning in
332
- - Celebrating: FEEL: euphoric, star shape, sparkle
333
- ```
334
-
335
- ---
336
-
337
- ## Emotions
338
-
339
- 15 built-in emotional states with unique visual characteristics:
340
-
341
- | Emotion | Description | Emotion | Description |
342
- | ----------- | ---------------- | ---------- | -------------- |
343
- | `neutral` | Default calm | `joy` | Happy, upbeat |
344
- | `calm` | Peaceful | `love` | Affectionate |
345
- | `excited` | High energy | `euphoria` | Peak happiness |
346
- | `sadness` | Melancholy | `anger` | Frustrated |
347
- | `fear` | Anxious | `surprise` | Startled |
348
- | `disgust` | Repulsed | `focused` | Concentrated |
349
- | `suspicion` | Wary | `resting` | Idle/sleep |
350
- | `glitch` | Digital artifact | | |
351
-
352
- ```javascript
353
- mascot.setEmotion('joy');
354
- mascot.setEmotion('calm', 'peaceful'); // with undertone
355
- ```
356
-
357
- ---
358
-
359
- ## Gestures
360
-
361
- 180+ base gestures in multiple categories:
362
-
363
- **Motion:** `bounce`, `pulse`, `shake`, `nod`, `sway`, `float`, `wiggle`, `lean`
364
-
365
- **Transform:** `spin`, `spinLeft`, `spinRight`, `jump`, `morph`, `stretch`,
366
- `tilt`, `twist`
367
-
368
- **Effects:** `wave`, `flicker`, `burst`, `flash`, `glow`, `breathe`, `expand`
369
-
370
- **Directional (Dance):**
371
-
372
- - `stepLeft`, `stepRight`, `stepUp`, `stepDown` - Quick 1-beat weight shifts
373
- - `slideLeft`, `slideRight` - Smooth 2-beat glides
374
- - `leanLeft`, `leanRight` - Body tilts
375
- - `kickLeft`, `kickRight` - Side kicks
376
-
377
- **Directional (Storytelling):**
378
-
379
- - `floatUp`, `floatDown`, `floatLeft`, `floatRight` - Ethereal drift
380
- - `pointUp`, `pointDown`, `pointLeft`, `pointRight` - Indication
381
-
382
- ```javascript
383
- mascot.express('bounce');
384
- mascot.express('stepLeft'); // Directional dance move
385
- mascot.chain('bounce > spin > pulse'); // Sequential
386
- mascot.chain('sway+breathe+float'); // Simultaneous
387
- mascot.feel('look to the stars'); // Natural language → pointUp
388
- ```
389
-
390
- ---
391
-
392
- ## Elemental Gestures (3D)
393
-
394
- The elemental bundle adds **160+ gestures** across 8 elements, each with custom
395
- GLSL shaders, instanced GPU models, and per-element bloom thresholds:
396
-
397
- | Element | Gestures | Key Effects |
398
- | --------------- | -------- | ------------------------------------------ |
399
- | **Fire** | 19 | Additive flame stacking, decoupled alpha |
400
- | **Water** | 20 | Splash rings, flow dynamics |
401
- | **Ice** | 16 | Voronoi cracks, subsurface refraction |
402
- | **Electricity** | 22 | 3D Voronoi bolts, lightning flash mechanic |
403
- | **Earth** | 22 | Petrify, rumble, quake effects |
404
- | **Nature** | 21 | Entangle, bloom, seed burst |
405
- | **Light** | 23 | Purify, beacon, ascend |
406
- | **Void** | 17 | Singularity, drain, corruption |
407
-
408
- ```javascript
409
- // Import from the elementals bundle — includes all 8 elements + 160+ gestures
410
- import { EmotiveMascot3D } from '@joshtol/emotive-engine/3d-elementals';
411
-
412
- mascot.express('firecrown');
413
- mascot.express('icevortex');
414
- mascot.express('zap');
415
- ```
416
-
417
- > Elemental gestures require the 3D assets to be self-hosted — see
418
- > [3D Assets](#3d-assets-models--textures).
419
-
420
- ---
421
-
422
- ## 3D Geometries
423
-
424
- | Geometry | Description | Shader |
425
- | --------- | ------------------------- | ------------------------ |
426
- | `crystal` | Faceted hexagonal crystal | Subsurface scattering |
427
- | `diamond` | Brilliant-cut diamond | Subsurface scattering |
428
- | `heart` | Heart-shaped crystal | Subsurface scattering |
429
- | `moon` | Realistic lunar surface | Custom phase shader |
430
- | `rough` | Rough organic crystal | Subsurface scattering |
431
- | `sphere` | Smooth sphere | Standard PBR |
432
- | `star` | Five-pointed star | Subsurface scattering |
433
- | `sun` | Solar sphere with corona | Emissive + corona layers |
434
-
435
- ```javascript
436
- mascot.morphTo('heart'); // Runtime geometry morphing
437
- ```
438
-
439
- ### Moon Phase Control
440
-
441
- ```javascript
442
- import { setMoonPhase, MOON_PHASES } from '@joshtol/emotive-engine/3d';
443
-
444
- setMoonPhase(mascot.core3D, MOON_PHASES.FULL);
445
- setMoonPhase(mascot.core3D, MOON_PHASES.CRESCENT_WAXING);
446
-
447
- // All phases: NEW, CRESCENT_WAXING, FIRST_QUARTER, GIBBOUS_WAXING,
448
- // FULL, GIBBOUS_WANING, LAST_QUARTER, CRESCENT_WANING
449
- ```
450
-
451
- ### Eclipse Effects
452
-
453
- ```javascript
454
- // Solar eclipse (animated transition)
455
- mascot.startSolarEclipse({ type: 'total' }); // 'total' or 'annular'
456
-
457
- // Lunar eclipse (blood moon)
458
- mascot.startLunarEclipse({ type: 'total' }); // 'total', 'partial', or 'penumbral'
459
- ```
460
-
461
- ---
462
-
463
- ## Configuration
464
-
465
- ### 3D Options
466
-
467
- ```javascript
468
- new EmotiveMascot3D({
469
- // Geometry
470
- coreGeometry: 'crystal', // crystal, diamond, heart, moon, rough, sphere, star, sun
471
- assetBasePath: '/assets',
472
-
473
- // Rendering
474
- enableParticles: true,
475
- enablePostProcessing: true, // Bloom effects
476
- enableShadows: false,
477
-
478
- // Camera
479
- enableControls: true, // Orbit controls
480
- autoRotate: true,
481
- cameraDistance: 3,
482
-
483
- // Animation
484
- enableBlinking: true,
485
- enableBreathing: true,
486
- targetFPS: 60,
487
- });
488
- ```
489
-
490
- ### 2D Options
491
-
492
- ```javascript
493
- new EmotiveMascot({
494
- canvasId: 'mascot',
495
- targetFPS: 60,
496
- enableParticles: true,
497
- maxParticles: 300,
498
- adaptive: true, // Auto quality adjustment
499
- });
500
- ```
501
-
502
- ---
503
-
504
- ## API Reference
505
-
506
- ### Core Methods (Both Modes)
507
-
508
- ```javascript
509
- // Lifecycle
510
- mascot.init(container);
511
- mascot.start();
512
- mascot.stop();
513
- mascot.destroy();
514
-
515
- // Natural language control (LLM-friendly)
516
- mascot.feel('happy, bouncing');
517
- mascot.feel('curious, leaning in');
518
-
519
- // Emotions
520
- mascot.setEmotion(name);
521
- mascot.setEmotion(name, undertone);
522
-
523
- // Gestures
524
- mascot.express(gesture);
525
- mascot.chain('gesture1 > gesture2');
526
-
527
- // Shapes
528
- mascot.morphTo(shape);
529
- ```
530
-
531
- ### 3D-Specific Methods
532
-
533
- ```javascript
534
- // Toggle features
535
- mascot.enableParticles();
536
- mascot.disableParticles();
537
- mascot.enableAutoRotate();
538
- mascot.disableAutoRotate();
539
-
540
- // Camera
541
- mascot.setCameraPreset('front'); // front, side, top, angle
542
-
543
- // Ambient Groove (rhythm-synced idle animation)
544
- mascot.setGroove('groove1'); // Subtle, elegant (default)
545
- mascot.setGroove('groove2'); // Energetic, bouncy
546
- mascot.setGroove('groove3'); // Smooth, flowing
547
- mascot.setGroove('groove2', { bars: 2 }); // Morph over 2 bars
548
- mascot.enableGroove();
549
- mascot.disableGroove();
550
- ```
212
+ | Doc | Description |
213
+ | ------------------------------------------------ | ------------------------------------------------------------------ |
214
+ | **[API Reference](./docs/API.md)** | All methods, configuration options, emotions, gestures, geometries |
215
+ | **[LLM Integration](./docs/LLM_INTEGRATION.md)** | Natural language `feel()` API, system prompt examples |
216
+ | **[Gestures](./docs/GESTURES.md)** | Full gesture catalog (180+ base + 160+ elemental) |
217
+ | **[Quick Reference](./docs/QUICK_REFERENCE.md)** | Cheat sheet for emotions, undertones, and common patterns |
218
+ | **[Architecture](./docs/ARCHITECTURE.md)** | Internal design and rendering pipeline |
551
219
 
552
220
  ---
553
221
 
@@ -556,132 +224,15 @@ mascot.disableGroove();
556
224
  ```bash
557
225
  git clone https://github.com/joshtol/emotive-engine.git
558
226
  cd emotive-engine
559
- npm install
560
- npm run build
561
- npm run local
562
-
563
- # Open http://localhost:3001
564
- ```
565
-
566
- Or view the [live demo gallery](https://joshtol.github.io/emotive-engine).
567
-
568
- ---
569
-
570
- ## Browser Support
571
-
572
- | Browser | Version |
573
- | -------------- | ------- |
574
- | Chrome/Edge | 90+ |
575
- | Firefox | 88+ |
576
- | Safari | 14+ |
577
- | iOS Safari | 14+ |
578
- | Chrome Android | 90+ |
579
-
580
- 3D mode requires WebGL 2.0 support.
581
-
582
- ---
583
-
584
- ## Multi-Instance Support
585
-
586
- Multiple mascots can run independently on the same page. Each instance has its
587
- own animation loop, emotion state, and resources.
588
-
589
- ```javascript
590
- import { EmotiveMascot3D } from '@joshtol/emotive-engine/3d';
591
-
592
- // Create two independent mascots
593
- const mascot1 = new EmotiveMascot3D({ coreGeometry: 'crystal' });
594
- const mascot2 = new EmotiveMascot3D({ coreGeometry: 'moon' });
595
-
596
- mascot1.init(document.getElementById('container-1'));
597
- mascot2.init(document.getElementById('container-2'));
598
-
599
- mascot1.start();
600
- mascot2.start();
601
-
602
- // Control independently
603
- mascot1.setEmotion('joy');
604
- mascot2.setEmotion('calm');
605
-
606
- // Stop one without affecting the other
607
- mascot1.stop();
608
- mascot2.express('bounce'); // Still running
227
+ npm install && npm run build && npm run local
228
+ # http://localhost:3001
609
229
  ```
610
230
 
611
- See the
612
- [dual mascot demo](https://joshtol.github.io/emotive-engine/examples/3d/dual-mascot-test.html)
613
- for a live example.
614
-
615
- ---
616
-
617
- ## Server-Side Rendering (SSR)
618
-
619
- The engine requires a browser environment. For SSR frameworks, use dynamic
620
- imports:
621
-
622
- ### Next.js
623
-
624
- ```javascript
625
- import dynamic from 'next/dynamic';
626
-
627
- const MascotComponent = dynamic(
628
- () =>
629
- import('@joshtol/emotive-engine/3d').then(mod => {
630
- // Initialize after dynamic import
631
- const mascot = new mod.EmotiveMascot3D({ coreGeometry: 'crystal' });
632
- return { default: () => <div ref={el => el && mascot.init(el)} /> };
633
- }),
634
- { ssr: false }
635
- );
636
- ```
637
-
638
- ### Nuxt 3
639
-
640
- ```vue
641
- <template>
642
- <ClientOnly>
643
- <div ref="container" />
644
- </ClientOnly>
645
- </template>
646
-
647
- <script setup>
648
- const container = ref(null);
649
-
650
- onMounted(async () => {
651
- const { EmotiveMascot3D } = await import('@joshtol/emotive-engine/3d');
652
- const mascot = new EmotiveMascot3D({ coreGeometry: 'crystal' });
653
- mascot.init(container.value);
654
- mascot.start();
655
- });
656
- </script>
657
- ```
658
-
659
- ### SSR Detection Helper
660
-
661
- ```javascript
662
- import { isSSR } from '@joshtol/emotive-engine/3d';
663
-
664
- if (!isSSR()) {
665
- // Safe to initialize mascot
666
- }
667
- ```
668
-
669
- ---
670
-
671
- ## Performance Tips
672
-
673
- - Disable post-processing on mobile for 60fps
674
- - Use `enableShadows: false` unless needed
675
- - Lower `maxParticles` on constrained devices
676
- - 2D mode is lighter weight for simple use cases
677
-
678
231
  ---
679
232
 
680
233
  ## License
681
234
 
682
- MIT License - see [LICENSE.md](./LICENSE.md)
683
-
684
- ---
235
+ MIT see [LICENSE.md](./LICENSE.md)
685
236
 
686
237
  <div align="center">
687
238