ADDENDUM (2026-06-30, v6+v7): De-monolith (v6): SimplifiedNPCSystem 934→183 (7 ECS systems +
_npcSharedseam →src/systems/) + GameScene 933→304 (6 render drivers +_sceneScratch→src/render/) fully dissolved; PositionTracker →src/systems/; Components.jsx ~1330 is the documented IRREDUCIBLEPlayeruseFrame controller (delegates all pure logic to 32game/*modules — do NOT split, Game-Loop-Isolation). Spell-VFX SOTA redesign (v7): each of the 4 spells is now a DISTINCT silhouette+motion+palette — new pure modulessrc/game/spellMotion.js(computeSpellMotionper-element motion grammar: roil/static/strobe/orbit) +src/render/spellGeometry.js(buildFireTeardropblackbody-ramp teardrop,buildIceShardsmerged solid crystal cluster; deterministic module-load static geometry);render/spellVfx.jsxrenderSilhouettebranches teardrop/shards/bolt(thin additive wire)/sigil(rune-wheel+duotone); data ingame/spellVisualProfiles.jsENERGY_PROFILE (addedmotion/midColor/glowShapefields). Weather (v7):game/weatherGate.jsgained pureprecipFor(weather,biome)— the state machine is nowclear↔stormwith the player's biome deciding rain/snow/dry; the 3 weather instancedMeshes carryfrustumCulled={false}. Visual gate 21→24 states (added spell-iceball/lightning/arcane cast frames).
⚠️ Doc-reality caveat (2026-05-31): the blueprint below is the pre-initiative Gemini-3.5-Flash self-description; the S0 audit found several "SOTA / verified" claims over-stated and parts of the architecture framing wrong (e.g. the miniplex ECS is load-bearing for mobs/loot/XP, NOT vestigial). Until this file is rewritten against reality, ground truth = gitmain+REALITY-AUDIT-2026-05-30.md+SOTA-INITIATIVE.md+docs/superpowers/specs/. The full reality-rewrite is a deferred task.
S2-A-M1 architectural addition (2026-06-02): an input-abstraction layer now exists —
src/input/inputState.jsis the single intent source-of-truth (getInput()/setIntent/setActive) that all player combat verbs gate on, decoupling KB+mouse from a future touch layer (activereplaces scattereddocument.pointerLockElement). New pure combat helpers live insrc/combat/(cone.jsisPointInCone,ribbonIndices.js). Melee now hits the boss (was spell-only); bossbossActiveis a single-source store value. NOTE:InputManager.jsxis a 2nd input path not yet migrated ontoinputState(S2-A-M2+ cleanup).
S2-B1 WILDHEART addition (2026-06-07) — the beast-transform Aspect (mechanics + look, merged
458bbb5): a pure transform state-machine (src/game/beastTransform.jsdecideTransform— charge→commit→duration→exit/cooldown; the store'sbeastFormActiveis the single active-truth, the SM owns only charge+timers) drives the single-writer form authority in the store (enterBeastForm/exitBeastForm; NO-PERMANENT-BEAST invariant — form is transient, never serialized, every exit path returns to human; death-edge drops form AND cancels any in-flight charge atomically). Derive-never-bake: per-form combat/locomotion/shape multipliers live in static tables (BEAST_FORMS,beastAvatarParts.jsFORM_PARTS) applied at the read site; base attrs + capsule never mutated; human = identity. The LOOK = a third-person reveal:src/game/transformCam.js(pure cam envelope, Components override, byte-identical on non-roar frames) +src/render/BeastAvatar.jsx(a RigidBody-child voxel avatar that self-gates to null unless beastFormActive/beastCharging → absent from all capture baselines; the ③·5 layered-emissive recipe) +src/game/beastMorph.js(pure 3-beat morph timing, capture-frozen to settled).MobToonMaterialgained a per-instancerimColor/rimStrength(mobs unaffected). Capture caveat: the in-world beast capture (spawnBeastTransformtest hook + capture.mjs roster loop) is non-deterministic under paused physics (RigidBody/render desync at an unsettled player) → the 4 beast frames are NOT gate-baselined; reliability is a tracked follow-up.
THE ASPECT-ERA ADDENDUM (2026-06-11 — B2/B3/B4 all shipped; the per-Aspect specs in docs/superpowers/specs/ are the detailed records): the game now runs on a 4×-proven ASPECT-META SCAFFOLD — per Aspect: a PURE state-machine module (
game/voidhand|soulbind|elemancer.js) + a pure dawn-bled METER (game/kinetic|soul|resonance.js; ferocity was the prototype) + an effect-less talent UNLOCK + an intent key (the verb row R/V/X/Z viainput/inputState.js) + single-slot TRANSIENT CHANNELS (game/*Channel.js— Game-Loop-Isolation seams between DOM listeners / useFrame SMs / render systems) + 15Hz ACCUMULATOR BRIDGES (world/SquadAISystem|ElementZoneSystem.jsx) + always- mounted transient renderers (world/SnareTetherSystem|ElementZoneRenderSystem.jsx, instanced pools, capture-frozen via now=0) + literal-token STATIC GATES (tests/gates/*-noremesh-gates×3 — voidhand/elemancer/beast; there is no soulbind one + wiring locks) + the sky-studio judge-fixture family (App.jsx test hooks, lanes x=0..240). Other load-bearing systems added post-blueprint: the kill bus w/ source attribution (game/mobKillBus.js— player/ally/ hazard), the allegiance seam (game/allegiance.js— the ONLY isMob→isAlly door), curated fusion (game/hybrids.js), weighted spawning (game/spawnWeights.js), the element-zone chemistry registry (game/elementZones.js), the panel/lock state machine (one pointerlockchange authority + error channel;ui/panelState.js). The blueprint BELOW remains the pre-initiative self-description — still awaiting the full reality-rewrite (deferred, tracked).
CURRENT-SESSION ADDENDUM (2026-06-15, HEAD eb924db — all SHIPPED to main): five self-validatable fronts landed since the Aspect-Era block. (1) P0 CAMERA: desktop mouse-look was DEAD (drei PointerLockControls, element-fragile + untestable in the pinned-camera harness) -> replaced with own
src/input/pointerLook.js(applyMouseLook/attachPointerLook) + the FIRST live-input gatenpm run test:look(scripts/visual/look-e2e.mjs). (2) MUSIC: ElevenLabs day/night/boss tracks (frontend/public/music/*.mp3) + smooth crossfade viasrc/ui/MusicPlayer.jsx; procedural pad/arp MUTED (SoundManagerPROC_MUSIC_GAIN=0), biome wind-bed kept -> the '4-Voice Procedural FM Synth Pad' section below is now muted-by-default. (3) TERRAIN flattened (terrain.worker.jsbaseHeight gentle plains + rare highland; 'Terrain height range 12-22' below is stale) + SUN mesh shrunk (radius 24->13). (4) TOUCH FRONT COMPLETE (iPad/iPhone), probe-exhausted -> the 'future touch layer' notes above are now BUILT: src/input/ adds touchDevice.js/touchHandlers.js/touchMath.js/verbRouter.js/useActiveInput.js; iOS cold-start bridged via enterPlay() in src/MenuSystem.jsx; QuestTracker touch-collapse (QuestSystem.jsx), spell-label whitespace-nowrap (HUD.jsx), compact SimpleExperienceBarTouch (SimpleExperienceSystem.jsx); deterministic scripts/visual/touch-probe.mjs; touch minimap JUDGED+SKIPPED. (5) OCEAN MILESTONE COMPLETE (plan docs/archive/2026-Q2/plans/2026-06-14-crafty-ocean-coast.md, 4 slices): brighter tropical-teal surface + sun-Fresnel sheen (Terrain.jsx); shore FOAM (un-merged the greedy mesher's water-top faces in terrain.worker.js -> per-cell shoreFoamFactor baked into color.g, read as vFoam, post-lighting white mix); depth-graded TOP surface (seabedDepthT -> color.b -> vDepthB shallow-teal->deep-navy); + ocean-coast capture state. New scripts/visual/ocean-probe.mjs + pov-probe.mjs. GATES NOW: 1182 unit tests, 20-state visual gate (added 'ocean-coast'), build clean. REMAINING = KEVIN-GATED only (redeploy crafty-sand.vercel.app, real-device iOS touch feel, music ear-check, ocean taste sign-off).
A 3D browser game built with React and Three.js, featuring Minecraft-style gameplay with block building, magic system, NPCs, and procedural terrain generation.
- Runtime: React 19, Three.js 0.172
- 3D Engine: @react-three/fiber 9.5, @react-three/drei 10.7
- Post-Processing: @react-three/postprocessing 3.0 (
postprocessingpeer) - Physics: @react-three/rapier 2.2 (Rapier WASM)
- Styling: Tailwind CSS 3.x, Framer Motion 12.x
- State: Zustand 5.x (global store), React hooks
- Build: Vite 6.x (migrated from CRA Feb 2026)
- UI Design System (S1-C COMPLETE, bold-flat): single SoT chain —
src/theme/tokens.js(semantic tokens) →src/theme/cssVars.js(--ui-*CSS vars viaapplyThemeVars()at boot +TW_COLORS/TW_SCALES) →tailwind.config.cjstheme.extendreferencing the vars (parity-tested bytests/theme/tailwind-wiring.test.js). Component primitives insrc/ui/primitives/— read the set from itsindex.jsrather than this line (there is no Tooltip; there ARE Slider and Modal;cnis deliberately not re-exported). ONE bold-flat language across the whole in-game UI (the legacy minecraft-bevel/glass/neon languages are gone;tests/gates/static-gates.test.jshard-asserts single-language + zero-emoji). i18n insrc/i18n/(t()/useT(), en default + lazy-CJK zh-CN). Icon system (M3): filled 2-tone game-icons (src/ui/primitives/gameIcons.js, 49 glyphs baked from game-icons.net CC BY 3.0 via the Iconify API) for game CONTENT + lucide-outline chrome for affordances; resolved by theIconprimitive's GAME_NAMES/CHROME maps. Item registrysrc/data/items.js= the single source for item name/icon/rarity (stable ids,getItemRarity/getItemIcon/getItemName/normalizeItemName); LOOT_TABLES/CHEST_LOOT/crafting use emoji-free names, with aloadWorldDatasave normalizer for legacy emoji keys. Zero emoji insrc/(hard-gated).CreditsScreen.jsxattributes game-icons.net + fonts. DEV-onlyPrimitivesShowcasegates the system via 2 visual-regression states.
- Procedural infinite terrain generation with chunks and biome variety
- Block placement and destruction with particle effects
- Magic system with 4 spell types (Fireball, Iceball, Lightning, Arcane) + Shield
- NPC/Mob system with 10 mob types (
game/mobTypes.js), AI movement, health bars, hostile chase AI - Day/night cycle
- Creative mode gameplay
- Player stats: health, mana, hunger with regeneration
- XP and leveling system with visual feedback
- Sound system with procedurally generated audio
- Save/Load — localStorage ONLY, no auth and no backend (
game/worldSaves.js; zero network calls in src/) - Animated main menu with particle effects
- Minimap HUD with mob tracking
- Quest system — 19 authored quests across 3 tiers PLUS an endless repeatable-bounty generator (
QuestSystem.jsx) - Loot drop system (mobs drop items on death)
- Treasure chests with random world spawning
- Achievement system with 12 badges and stats tracking
S1 Render Systems (Crafty → SOTA initiative — CURRENT, post-Gemini; supersedes the stale blueprint below for the render layer)
The render layer was rebuilt in S1 against the visual-direction spec (docs/superpowers/specs/2026-05-30-crafty-visual-direction-design.md), Vanguard+Toon. New/load-bearing modules (ground truth — all on main, gated by the deterministic visual-regression suite):
src/theme/tokens.js— design-token source of truth (explore/dusk/obsidian palettes, lerp-safe; magic + UI tokens). [S1-A]src/render/quality.js— device quality tiers (low/med/high); flagsao/godRays/bloomMipmap/shadowMapSize/renderDistance/weather/dprCap+charOutline(med+) /charRim(high). Capture forceshighfor hardware-independent baselines. [S1-A/B]src/devtest/— DEV-only test bridge (window.__craftyTest, tree-shaken in prod) + capture-determinism layer (captureMode.js: per-key seeded RNG, paused physics, pinned camera, frozen clock). [S1-A]src/render/mood.js+src/render/Atmosphere.jsx— continuousmood∈[0,2](explore→dusk→obsidian) via amoodRefsingleton;<Atmosphere>= camera-following gradient SkyDome + mood-lerped ambient/sun/fill/fog offtokens.PALETTE(replaced the inline<Sky>/fog/ternary lights). [M2a]src/render/characterStyle.js(pure) +src/render/MobToonMaterial.jsx(R3F wrapper) — the character render language: memoized 2-band toon gradientDataTexture, fresnel-rimonBeforeCompilepatch,OUTLINE/RIM/TOONconfig,flashableMaterialhit-flash allow-list. [M2b]- GameScene
<EffectComposer>— N8AO → GodRays (sun mesh) → HueSaturation → BrightnessContrast → Bloom → SMAA → ToneMappingNEUTRAL(ACES muted the stylized palette; the composer overridesgl.toneMapping, so tone mapping MUST be a composer effect) → Noise → Vignette. Terrain uses an in-shader sRGB decode (pow(rgb,2.2)) + amooddesaturation uniform. [M1/M2a]
Character render language (M2b): mobs = 2-band toon (body/head/legs/nose) + tier-gated fresnel rim + inverted-hull drei <Outlines> on ALL body parts; the per-frame hit-flash traversal is a positive material-type allow-list (Standard/Toon) so it flashes the toon body but skips the outline ShaderMaterial. Boss = outline on torso+neck ONLY, emissive attack-telegraph preserved (no toon), capture freeze-gate + DEV-only forceBossSpawn. Chests + pets outlined. drei <Outlines> thickness is screen-PIXELS at the default screenspace=false (not world units). Two deterministic capture states gate the look: character-closeup + boss-closeup. Static gates in tests/gates/character-render-gates.test.js.
Visual-regression gate: npm run test:visual (puppeteer + pixelmatch, 6% threshold, 20 states (2026-06-15, incl. ocean-coast/mobile/mob-bestiary)) — replaces the blind test_swarm.js; re-baseline per intended look change under forced high tier, human-reviewed.
/frontend/
├── index.html # Vite entry point
├── vite.config.js # Vite build config
├── postcss.config.cjs # PostCSS (Tailwind)
├── tailwind.config.cjs # Tailwind config
└── src/
├── App.jsx # Main app, Canvas, Minimap, Main Menu
├── App.css # Global styles, animations, glassmorphic panels
├── Components.jsx # Player, UI panels, block types
├── SimplifiedNPCSystem.jsx # Mob spawning, AI, chase behavior, combat
├── EnhancedMagicSystem.jsx # Spell projectiles, effects, hand visuals
├── GameSystems.jsx # Player stats (HP/MP/hunger), combat, UI bars
├── SimpleExperienceSystem.jsx # XP, leveling, visual gain/level-up effects
├── SoundManager.jsx # Procedural audio (combat, magic, ambient)
├── QuestSystem.jsx # Quests, loot drops, treasure chests, achievements
├── AdvancedGameFeatures.jsx # Survival mode, boss mob, pets, spell upgrades
├── OptimizedGrassSystem.jsx # Grass rendering optimization
├── AuthContext.jsx # Authentication state
├── AuthComponents.jsx # Auth UI components
├── WorldManager.jsx # World save/load
├── index.jsx # App entry point
├── index.css # Base CSS reset + Tailwind directives
├── store/useGameStore.jsx # Zustand global state store
├── utils/combat.js # Decoupled math solvers for RPG combat (melee, spell, armor)
├── workers/ai.worker.js # Web Worker for CPU-heavy AI pathfinding
├── world/Terrain.jsx # Terrain generation + Rapier physics colliders
├── world/Blocks.js # Block type definitions
├── ui/GamePanels.jsx # Extracted UI panel components
└── ui/DebugOverlay.jsx # Premium glassmorphic diagnostics & developer console overlay
| Key | Action |
|---|---|
| WASD | Move |
| Mouse | Look around (click to enable; own src/input/pointerLook.js, not drei PointerLockControls as of 2026-06-15) |
| F | Cast spell (melee is T) |
| 1-4 | Select spell type |
| E | Inventory |
| M | Magic |
| C | Crafting |
| B | Building |
| ESC | Settings |
| Space | Jump |
| Left Click | Break block |
| Right Click | Place block |
| Tab | Achievements panel |
| G | Open treasure chest |
| T | Melee attack |
| U | Talents & Aspect guide |
| Type | Color | Health | Behavior | Damage |
|---|---|---|---|---|
| Pig | Pink | 50 | Passive, wanders | — |
| Cow | Brown | 80 | Passive, wanders | — |
| Husk (zombie) | Green | 100 | Hostile, chases player | 10 |
| Skeleton | Beige | 80 | Hostile, chases player | 6 |
| Spider | Black | 60 | Hostile, chases player | 4 |
| Spell | Key | Damage | Mana Cost | Effect |
|---|---|---|---|---|
| Fireball | 1 | 50 | 15 | Fire projectile with gravity |
| Iceball | 2 | 40 | 12 | Ice projectile with gravity |
| Lightning | 3 | 75 | 25 | Fast electric strike |
| Arcane | 4 | 60 | 18 | Mystical energy blast (pierce + lifesteal) |
| — | — | — | NEVER BUILT as a spell. game/spells.js has exactly four. "Shield" exists only as offhand EQUIPMENT (game/equipment.js). |
| Block | Color | Notes |
|---|---|---|
| Grass | Green | Surface block |
| Dirt | Brown | Below grass |
| Stone | Gray | Underground |
| Wood | Brown | Tree trunks |
| Birch Wood | Cream | Birch tree trunks |
| Leaves | Dark Green | Tree canopy (3×3) |
| Sand | Tan | Terrain variety |
| Coal Ore | Dark | Underground, common |
| Iron Ore | Bronze | Underground, moderate |
| Gold Ore | Gold | Underground, rare |
| Diamond Ore | Cyan | Underground, very rare |
| Red Flower | Red | Scattered on grass |
| Yellow Flower | Gold | Scattered on grass |
| System | Details |
|---|---|
| Health | Hearts display, damage overlay on hit, death screen + respawn |
| Mana | 100 max, regenerates over time, spells consume per cast |
| Hunger | Chicken leg icons, depletes over time |
| XP | Level-based progression, visual +XP popups, level-up effect |
| Sound | Procedurally generated: footsteps, block place/break, combat, magic, ambient |
| Parameter | Value |
|---|---|
| CHUNK_SIZE | 16 blocks |
| RENDER_DISTANCE | 4 chunks |
| Terrain height range | 12-22 (STALE — flattened 2026-06-15: terrain.worker.js baseHeight gentle plains + rare highland) |
| Player height offset | 1.2 units |
| Initial spawn | (0, 100, 0) — game/playerSpawn.js |
| Physics gravity | -30 m/s² |
| Max mob distance | 100 units (despawn beyond) |
| Mob aggro range | 16 blocks |
| Mob melee range | 2.5 blocks |
| Minimap range | 60 world units |
| Cast cooldown | 333ms (3 casts/sec) |
| Jump velocity | 12.0 — game/locomotion.js |
| Gravity | -32.0/s, terminal -50.0 — game/locomotion.js |
| Chest spawn interval | 30 seconds |
| Chest proximity range | 3 blocks |
| Loot auto-collect delay | 2 seconds |
| Boss spawn level | Level 5 |
| Boss health | 700 HP — game/bossConfig.js |
| Boss XP reward | 600 XP — game/bossConfig.js |
| Max pets | 3 |
| Pet tame range | 4 blocks |
| Night hostile spawn rate | 70% |
| Night danger multiplier | 1.5× base |
- ✅ Mob variety (5 types with chase AI)
- ✅ Mob movement AI + hostile aggro
- ✅ E key Inventory (glassmorphic)
- ✅ M key Magic panel (glassmorphic)
- ✅ C key Crafting panel (glassmorphic)
- ✅ B key Building panel (glassmorphic)
- ✅ ESC key Settings (glassmorphic)
- ✅ F key spell casting (reliable)
- ✅ Spell selection (1-4)
- ✅ Mob health bars + damage numbers
- ✅ Continuous spawning
- ✅ Controls help panel
- ✅ Animated main menu
- ✅ Minimap with mob tracking
- ✅ Terrain variety (flowers, ores, birch trees)
- ✅ Player health/mana/hunger bars
- ✅ XP and leveling system
- ✅ Death screen + respawn
- ✅ Sound effects
- ✅ Block break/place mechanics
- ✅ Branding cleanup (no "Emergent" references)
- ✅ Jump mechanics (smooth consecutive jumps)
- ✅ Spell casting reliability (no visual skips)
- ✅ Quest tracker HUD
- ✅ Loot drops from mobs
- ✅ Treasure chest spawning and opening
- ✅ Achievement panel (Tab key)
- ✅ Notification popup system
- ✅ Survival mode (night danger escalation)
- ✅ Boss mob (Shadow Dragon at Level 5)
- ✅ Pet system (tame passive mobs)
- ✅ Spell upgrades (I → II → III)
- ✅ Night hostile spawn boost
- ✅ Rapier physics (terrain collision, gravity, player capsule)
- ✅ Camera horizontal initialization
- ✅ Vite build system (CRA migration)
- ✅ React 19 + Fiber 9 + Rapier 2.2 compatibility
To maintain 60+ FPS gameplay, all CPU-heavy pathfinding calculations are offloaded to a dedicated Web Worker (ai.worker.js).
- Dynamic Local Voxel Grids: For every active, aggroed hostile, the main thread samples a 9x9 local terrain height grid via Rapier physics raycasts (
getMobGroundLevel). This compact array is sent to the worker, avoiding the high cost of serializing global voxel maps. - Voxel A Solver*: Inside the worker, a custom 3D A* search is executed over the 9x9 grid, calculating 8-way diagonal pathways, slope scaling (caps climbs at 1.25 blocks), and gap-jumping.
- Cover Seeking Behavior Trees: Hosts tactical state-selection trees that monitor hostile health. If health falls below 25%, hostiles transition to cover-seeking state, using a 2D line-of-sight raycast solver (
hasLineOfSight) to locate cells behind high intervening block columns hidden from the player's sight, steering and moving 20% faster to hide behind them. Mobs in cover retreat render a glowing cyan wireframe shield aura on the main thread. - Pack Alert Aggro Linking: Mobs within a 12-unit radius are linked; alerting one mob pulls nearby pack cohorts into the combat cycle synchronously.
The Shadow Dragon boss event is designed to be highly immersive and visually spectacular while keeping main-thread overhead near zero.
- Direct Mesh Ref Mutations: The fireball projectiles, boss rotations, and expanding Lava Zone meshes are updated imperatively in the
useFramegame loop using Three.js mutable references, completely bypassing React virtual DOM diffing. - State Machine Transitions:
- Phase 1 (Flight Mode): Boss circles at Y=+13 units, launching home-targeted falling fireballs.
- Phase 2 (Grounded Rage): Boss lands, executing melee charges and Knockback Roars (applying physics impulses directly to the player capsule core). Unleashes roaring shockwaves that physically shatter and convert solid blocks in a 5-unit radius to Air (
0). - Phase 3 (Enraged Fire): Boss spawns Skeleton Cohorts, turns glowing red, and emits expanding damage-over-time Lava Zones with custom shader-like opacity fades, tearing down adjacent terrain blocks on impact to trigger instanced physical falling debris particles.
A dedicated pet command system (T key) allows the player to dynamically direct their tamed entities.
- Follow Mode: Pets circle the player orbitally, maintaining a close visual perimeter.
- Stay Mode: Pets anchor themselves to the current coordinates and guard the zone.
- Attack Mode: Pets sweep for active hostile entities (prioritizing the Shadow Dragon) and charge them to draw aggro and deal damage.
- State Management: When bridging React UI state with imperative 3D game loops (@react-three/fiber), prefer Zustand's
useStore.getState()over globals or polling for fast, non-reactive reads. Absolutely NEVER store non-serializable functions (likedamageMoborgrantXP) in Zustand; use the dedicatedGameMethods.jsmodule. - Component Design: Proactively decompose massive monolithic React orchestrator components into specialized layers (e.g.,
GameScene,HUD,InputManager) to prevent re-render cascading. UseuseShallowwhen subscribing to Zustand stores in UI layers. - 3D Interaction: For accurate block placement in 3D environments, always use physics engine raycasting (e.g., Rapier's
world.castRay) for precise intersections. Throttle these raycasts spatially and temporally to avoid 60Hz CPU spikes. - GPU Offloading: When animating hundreds of similar objects (e.g., grass swaying), never compute matrix math in a CPU
useFrame. Always useInstancedMeshcombined with customonBeforeCompilevertex shaders. - Physics Pooling: Never mount and unmount
<RigidBody>components dynamically during high-frequency events (like block breaking). Use<InstancedRigidBodies>and manipulate the transform matrices of a fixed pool of hidden bodies to simulate spawning.
To achieve SOTA browser-game combat feel, a comprehensive impact pipeline is implemented in SimplifiedNPCSystem.jsx:
- Directional Squash & Tilt: Mob geometries dynamically squash on the Y axis (peak at 15%) and stretch on the XZ plane, coupled with a 0.2 radian directional tilt away from the incoming hit vector. The deformation decays using high-frequency spring-dampers (
Math.exp(-delta * 12)). - Pooled Expanding Shockwaves: Flat circular rings spawn on hit coordinates, scaling to 4.5 units and fading opacity over 300ms. Color-coded per damage type (orange: Fire, cyan: Lightning, gold: Arcane, white: Melee).
- Canvas-Gradient Floating Damage: floating billboard text sprites render high-contrast dynamic linear gradients matched to spell colors (e.g., yellow-red for Fireball, cyan-blue for Lightning).
The player hands <StableMagicHands> in Components.jsx are upgraded with immersive visual feedback:
- Channeling Vibrations: Subtle high-frequency viewport vibrations (0.005 units at 65-95 Hz) are applied during casting to communicate raw power.
- Dynamic Casting PointLights: Real-time
<pointLight>source lights up the left hand during attack frames, throwing colored light bounces onto the surroundings. - Pulse-Pulsed Aura: Persistent aura pulses are driven at speed-factor 12 during casting and speed-factor 3 when idle.
Dynamic atmospheric immersion in GameScene.jsx:
-
Responsive FogEXP2: A dedicated
<EnvironmentalFog />component smoothly lerps scene fog color (#e0f7fa$\leftrightarrow$ #0a0a23) and density (0.007$\leftrightarrow$ 0.025) as the sun rises/sets. -
Seamless Skybox Blending: Copies the active fog color directly to
scene.backgroundon every frame, achieving perfect camera horizon blending.
4. 4-Voice Procedural FM Synth Pad (MUTED as of 2026-06-15 — PROC_MUSIC_GAIN=0; superseded by ElevenLabs tracks + crossfade in src/ui/MusicPlayer.jsx; biome wind-bed retained)
A premium, continuous soundscape synthesizer is built in SoundManager.jsx:
- Hybrid Timber: Employs sawtooth and triangle oscillators with warm low-pass filters.
- Filter Sweeps: Filter cutoff is swept continuously by a slow 0.08 Hz LFO.
- Step-Scheduled Transitions: Rotates chord progressions every 8 seconds with 3.5 seconds of portamento exponential glide. Dynamic chord libraries: Lydian progression (Day), mysterious Dorian progression (Night), and augmented chords (Boss).
To render high-fidelity, high-performance foliage, OptimizedGrassSystem.jsx utilizes an instanced mesh with vertex-level displacement:
- Global Uniform Binding: The player's 3D coordinates from the Zustand store are bound as a global uniform
playerPositioninto the shared grass material. - Quadratic Bending Shaders: In the
onBeforeCompilevertex shader, the distance from each instance to the player is calculated. Vertices are pushed away dynamically using a quadratic falloff equation, allowing grass to bend naturally as the player walks through it.
2. Bioluminescent Liquid Wave Shaders (OLD water shader only — 2026-06-15 ocean milestone added shore FOAM via color.g/vFoam + depth-grade via color.b/vDepthB; see src/world/oceanProfile.js)
Procedural fluid surface dynamics are compiled inside Terrain.jsx:
- Shared Material Architecture: All terrain chunks share a single custom standard material (
terrainMaterial), reducing draw calls and context pressure. - Wave Displacement: An
onBeforeCompilehook filters water vertices (color.b > 0.6 && color.r < 0.15) in the vertex shader, displacing height dynamically using high-frequency procedural wave equations. - Night Bioluminescence: In the fragment shader, a pulsating neon-blue glow is blended during Night cycles (
1.0 - timeOfDay), driven by time-pulsed noise equations.
Immersive atmospheric weather is implemented via a <WeatherSystem /> canvas component in GameScene.jsx:
- Instanced Bounding Boxes: Animates 400 raindrop boxes / 200 snow quads (base counts, each scaled by the tier
weathermultiplier — low 0.25 / med 0.6 / high 1.0) in a 40m box centred on the player.render/WeatherSystem.jsx. - Terrain Colliders: Particles query
getMobGroundLevelto snap, splatter, and reset upon hitting the ground, avoiding underground particle clipping. - Night Fireflies: Spawns 30 glowing firefly particles (base, tier-scaled) orbiting the player at night, fading out during the Day.
Procedural Web Audio routing is added to SpatialAudioController (GameScene.jsx):
- Delay-Feedback Graph: Routes spatial sounds into a lowpass filter, delay node (240ms), feedback gain loop (35% decay), and a dedicated wet gain controller.
- Depth-Based Modulation: Continually monitors camera height. When the player descends underground (
y < 10), the feedback wet gain scales up to produce a haunting cavern echo.
To support state-of-the-art visuals, dense graphics, and flawless 60+ FPS performance, terrain.worker.js incorporates a highly optimized, high-fidelity 3D Greedy Voxel Meshing compiler:
- Background Web Worker Thread: Offloads all heavy geometry calculations to a dedicated worker thread, keeping the main render thread free of GC pauses or CPU bottlenecks.
- Slice-and-Sweep Strategy: Sweeps each chunk along the X, Y, and Z axes. At each slice step, it evaluates visibility between adjacent blocks (culling solid-to-solid faces, while keeping solid-to-air, solid-to-water, and water-to-air faces).
- Coplanar Quad Merging: A 2D greedy sweep combines adjacent matching coplanar voxel faces into singular larger rectangular quads. A pre-allocated reusable mask buffer (
Uint16Array(4096)) prevents GC stutters. - CCW Winding Maps: Formulates accurate counter-clockwise (CCW) vertex coordinates and normal vectors for all 6 faces to preserve correct lighting computations.
- Liquid Separability: Keeps water blocks isolated from solid blocks during merging to preserve procedural fluid shader vertices and wave dynamics.
To deliver premium, industry-grade action RPG locomotion controls, Components.jsx integrates a WASM-native Rapier Kinematic Character Controller (KCC):
- Kinematic Position Body: Player physics body
typeis changed tokinematicPosition, granting absolute movement precision and rendering the character immune to erratic dynamic rigid-body sliding and jitter. - WASM-Native Collision Sweeps: Offloads all obstacle collision detection, wall sliding, and slope deceleration directly to the WASM physics layer via
controller.computeColliderMovement(...). - Automatic Step-Up Snapping: Employs built-in autostep parameters capping block step climbs at 1.05m and ground snapping at 0.5m, enabling the player to run up staircases, ridges, and slopes flawlessly.
- Dynamic Gravity & Trajectories: Tracks vertical velocity manually (
velocityY.current), applying constant gravity acceleration (-32.0 * delta) and cap parameters (-50.0terminal velocity) to simulate realistic jumping and falling curves. - Decayed Impulse Redirection: Overrides the standard
applyImpulsemethod directly on the player rigid body ref instance upon mount. Intercepts boss-inflicted combat knockbacks and channels them into a decoupled knockback velocity ref (knockbackVelocity), which decays smoothly using high-frequency exponential spring dampers.
To support AAA-grade detailed voxel graphics and interactive vegetation fields, the graphics system incorporates a custom high-performance WebGL2 DataArrayTexture pipeline:
-
Procedural Array Painting: Generates dynamic 32x32 pixel organic texture slices for 16 layers (
world/proceduralTextures.js: 0..9 base blocks · 10..13 ore tiles · 14 cobblestone · 15 glass) using deterministic sine/cosine noise offsets at startup (proceduralTextures.js), maintaining a 0-byte static file size asset footprint. -
Tiled UV Repeat Compilation: The worker
terrain.worker.jscalculates local UV coordinates matching CCW corners[0,0],[0,h],[w,h],[w,0]for each greedy quad of size$w \times h$ . By bindinguvattributes insideTerrain.jsx, textures tile perfectly tile-by-tile across merged faces without stretching. -
Vertex Color Layer Packing: Packs the raw
blockTypeinteger inside the geometry'scolor.rchannel. The fragment shader updates inonBeforeCompileread this coordinate on every frame, sampling the precise layer slice usingtexture(voxelTextures, vec3(fract(vUv.x), fract(vUv.y), layer)). -
Translucent Water Shading: Enables explicit transparency blending (
alpha = 0.75) for water block layers inside the fragment shader, revealing detailed sandy beaches underneath ocean shorelines. -
Instanced Multi-Entity Bending: Upgrades
OptimizedGrassSystem.jsxto bind anentityPositions[8]uniform array. The vertex shader loops through all active entity slots (player, pets, and mobs from the central Miniplex ECSworldsynced inuseFrame) to apply quadratic bent displacement vectors, creating a highly interactive world field.- Multi-Frequency Wind Sway: Synthesizes high and low frequency sine/cosine wind waves driven by instanced offsets to simulate realistic foliage rustling.
To deliver premium, sensory-rich combat loops, Components.jsx and GPUSparkSystem.jsx incorporate a modular SOTA Combat Graphics & FX engine:
- Fully GPU-Driven Billboarding Particles: Instantiates an optimized
<GPUSparkSystem />managing up to 1200 simultaneous embers. Employs a highly custom WebGL2ShaderMaterialthat handles gravity trajectory offsets, lifetime scaling size shrinkage, and view-space billboard rendering entirely on the GPU (mvPosition.xyz += pos;), reducing the CPU frame budget overhead to exactly 0ms. - Dynamic Camera-Local Ribbon Geometry: Tracks sword tip and base positions relative to the camera-space right arm group, compiling a dynamic triangle quad strip mesh geometry inside
useFrame. Uses a custom energy shader executing a linear length fadeout paired with soft width feathering and a glowing white-hot center core. - Stylized Bezier Sweep Swing Animation: Animates the player's right hand holding the weapon inside a sweeping, diagonal Bezier slash arc (moving right-to-left, tilted down) to convey visual weight and velocity, replacing the standard forward poke.
- Procedural 3D Weapon Model Branching: Conditionally renders detailed, multi-element group models for equipped weapons (
Stone Sword,Iron Sword,Diamond Sword,pickaxe) inside a modular<ProceduralWeapon />component. Meshes utilize flared guard wings, diamond-pointed tip extrusions, leather-wrapped hilts, and distinct metallic/emissive properties. - Critical Strike Sensory Pulses: Upgrades the hit registry in
damageMobto trigger high-velocity, color-coded GPU particle cascades (crimson/yellow for slashes, orange/gold for fireballs, cyan/silver for iceballs, fast neon-yellow/white for lightning, and purple/magenta for arcane spells) and visceral camera shakes. The critical floating damage numbers scale by 1.3x and apply high-frequency coordinate vibration shakes and cosine breathing scale pulses.
The first of the four S2-B Aspects: hold a roar → become an element-beast (the loaded spell picks the form: fire→comet, ice→bull, lightning→hawk, arcane→golem); a Ferocity meter banks by day-kills and is spent to transform in the night siege. Built M-by-M with per-milestone TDD + adversarial-review-before-merge (which caught a real blocking bug in M1 and M3, both lifecycle/death-edge state-coupling bugs). The premium VFX + beast meshes are M7 (gated on Kevin's locked look reference: "Hades silhouette + Genshin radiance, fused"); the mechanics below are art-free.
- Transactional collider hot-swap + the no-permanent-beast invariant (M1):
src/game/beasts.js(BEAST_FORMS= 4 distinct collider mass-shapes +BASE_CAPSULE+setColliderToForm/restoreBaseColliderhelpers). The store owns the single-writer form STATE (beastFormActive/activeBeastForm/enterBeastForm[returns did-enter]/exitBeastForm), kept transient (never serialized → load/respawn always returns to human).Components.jsxdoes the in-place RapiersetShape(handle preserved → no re-bind, ZERO voxel edits): ENTER is queued + consumed inuseFrame(atomic with the sweep + grow-depenetration), EXIT-restore is imperative at the death/load edge (must drain even while the dead-windowuseFrameearly-return is active). Verified by a real-Rapier-WASM integration test (1000-cycle handle-stability headless in vitest). - Bull physics gate (M2):
tests/integration/beast-collider-rapier.test.js+scripts/bench/bull-physics-bench.mjs— the larger forms cost ~9-12× base per KCC sweep in a pathological dense cluster but ~5-7% of a frame budget for one entity → acceptable; GPU FPS is a real-device check (memory/S2B1-M2-PERF.md). - Transform state machine + the roar verb (M3):
src/game/beastTransform.js(pure: hold-roar → anticipation charge → commit → 14s duration → exit → cooldown). Theroarverb is a REALuseFrameintent consumer (KeyR→setIntent('roar')→getInput().roar, the touch-ready input-abstraction), ticked above the dead-window early-return so a charge cancels at death.elementForSpellmaps the loaded spell to the form. - Kill-event fan-out bus (M3.5):
src/game/mobKillBus.js(subscribe/emit, per-subscriber isolation) replaced the single-slotstore.onMobKill(a last-writer-wins trap). Quests + Ferocity both subscribe; the kill-path emits once. The Aspect-meta kill scaffold (SOULBIND reuses it). - Ferocity economy (M4):
src/game/ferocity.js(pure: per-tier gradient passive<hostile<boss, clamp, the roar gate). Store slice (ferocityBanked/accrueFerocity/setFerocityBanked, persisted+clamped) + a day-only capture-guarded accrual hook (useFerocityAccrual, via the bus) + a dawn bleed-to-zero + the autosave-trigger + the roar gate (canEnter= a full bank, spend-on-success) + a HUD bar (aferocityferal token through tokens→cssVars→tailwind;StatBar kind='ferocity'; gated on>0so the capture states stay byte-identical). - Combat + locomotion re-skin (M5): per-form combat (
damageMult/cooldownMult) + locomotion (moveMult/gravityMult/jumpMult) multipliers extend the staticBEAST_FORMStable, applied AT the read site (derive-never-bake; human = identity no-op). Melee viaresolveFormMelee(rawDamage, element)->{dealt, sparkType}(damage × the form mult on top ofgetEffectiveAttributes(); spark derived from the LOCKED form element viaspellForElement, never the liveactiveSpell— so a mid-form spell-switch can't desync the spark from the body). Conerange/arcare NOT per-form (boss + mob hit-reg parity); cooldown ×cooldownMult(hit-reg-safe). Locomotion mults multiplyspeed/jump/gravity in the movementuseFrame(transientgetState); hawk = low-gravity hops, not flight.turnRateomitted (no seam in a camera-relative pointer-lock controller). The 4 forms are pairwise-distinct per axis (the two-axis sampler-trap defense); MOTION artifact inmemory/S2B1-M5-MOTION.md. - Talent unlock-gate (M6): the roar is a TALENT-gated signature ability.
src/game/talentTree.jsgains 2 effect-less wildheart nodes —wildheart_roar(pure unlock) +wildheart_endurance(an ability-LEVER: +3s form-duration/rank viaformDurationFor, read at the duration site, NOT the stat-fold).foldTalentEffectsnode-shape contract: signature/unlock/lever nodes omit.effect; the fold SKIPS them (the guard|| !node.effect— it previously hard-crashed on the unconditionalnode.effectdestructure, affecting all 4 Aspects + everygetEffectiveAttributes()); levers read their rank at their own math site. The roarcanEnterANDsunlockedTalents.wildheart_roar > 0with the full-bank gate (gates startCharge + commit).unlockedTalentsalready persists; the nodes surviverefundUnknownTalents. WILDHEART MECHANICS LAYER COMPLETE (M0-M6 + M3.5); M7-M8 = the LOOK (reference-locked VFX, judged in-world).