8d48eb06b3d4a52999346f3c763d6c70a9acca63
## What changed - the-matrix/js/agents.js — complete face expression system on Timmy wizard ## Face geometry (all parented to head — follow head.rotation.z tilt) - White sclera eyes (MeshStandardMaterial f5f2e8, emissive 0x777777@0.10) replace old flat dark-blue eye spheres - Dark pupil spheres (MeshBasicMaterial 0x07070f) as children of each sclera; they scale with the parent eye for squint + animate independently for dilation - Mouth arc: TubeGeometry via QuadraticBezierCurve3; ctrlY = -smileAmount*0.065; rebuilt only when |smileDelta| > 0.016 (throttled, not per-frame GC) - All face meshes are children of `head` mesh — head.rotation.z carries every face feature naturally with the existing head-tilt animation ## FACE_TARGETS table (lidScale, pupilScale, smileAmount) - idle (contemplative): 0.44 / 0.90 / 0.08 — half-lid, neutral - active (curious): 0.92 / 1.25 / 0.38 — wide open + dilated pupils, smile - thinking (focused): 0.30 / 0.72 / 0.00 — narrow squint + constrict, flat mouth - working (attentive): 0.75 / 1.05 / 0.18 — alert/open eyes, slight grin ## setFaceEmotion(mood) — authoritative public API - Accepts task-spec names (contemplative|curious|focused|attentive) and internal names (idle|active|thinking|working) via MOOD_ALIASES - Sets timmy._overrideMood; persists across frames, takes precedence over deriveTimmyState() in updateAgents() - Call with null to clear override and return to automatic state-driven expressions ## Per-frame lerp (rate 0.055/frame) in updateAgents - Uses _overrideMood ?? deriveTimmyState() as effective mood - lidScale → eyeL.scale.y / eyeR.scale.y (squash for squint/wide-open) - pupilScale → pupilL/R.scale.setScalar() (uniform dilation) - smileAmount → drives thresholded TubeGeometry rebuild ## Lip-sync while speaking (1 Hz, range 0.20–0.60) - speechTimer > 0: smileTarget = 0.40 + sin(t*6.283)*0.20 - Returns to mood expression when timer expires ## Validation - Vite build: clean (14 modules, no errors) - testkit: 27/27 PASS (server restarted to clear rate-limit counters between runs)
Description
Timmy Tower World — sovereign AI agent economy
Languages
TypeScript
68.9%
JavaScript
15.5%
Shell
10.6%
HTML
4.5%
CSS
0.4%