This repository has been archived on 2026-03-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
token-gated-economy/attached_assets
alexpaynex 7f402c5c7f feat(task-21): Timmy face expressions + emotion engine
## What changed
- the-matrix/js/agents.js fully rewritten with face expression system

## Face geometry
- Replaced flat dark-blue eye spheres with white sclera (MeshStandardMaterial,
  emissive 0x777777@0.10, roughness 0.55) + dark pupils (MeshBasicMaterial 0x07070f)
  as child meshes of sclera
- Eyes are now children of the head mesh (not the group) so they naturally
  follow head.rotation.z tilts driven by the existing animation loop
- Mouth added as a canvas Sprite (128x32, always faces camera) parented to the
  group so it bobs with Timmy's body; drawn via quadraticCurveTo bezier arc

## Emotion → face parameter mapping (FACE_TARGETS table)
- idle (contemplative): lidScale=0.44, smileAmount=0.08  — half-lid, neutral
- active (curious):     lidScale=0.92, smileAmount=0.38  — wide eyes, smile
- thinking (focused):   lidScale=0.30, smileAmount=-0.06 — squint, flat mouth
- working (attentive):  lidScale=0.22, smileAmount=0.18  — very squint, slight grin

## Per-frame lerp (updateAgents)
- faceParams lerped toward faceTarget at rate 0.055/frame (smooth, no snap)
- eyeL.scale.y / eyeR.scale.y driven by faceParams.lidScale (squash = squint)
- Mouth canvas redrawn only when |smileDelta| > 0.016 or speakingChanged
  (avoids unnecessary texture uploads every frame)

## Lip-sync while speaking
- While speechTimer > 0: smileTarget = 0.28 + sin(t*6.283)*0.22 (~1 Hz)
- _drawMouth() renders two-lip "open mouth" shape when speaking=true
- Returns to mood expression when speechTimer expires

## Validation
- Vite build: clean (14 modules, 529 kB bundle, no errors)
- testkit: 27/27 PASS (no regressions)
- No out-of-scope changes (backend untouched)
2026-03-19 03:04:17 +00:00
..