Skip to content

Latest commit

 

History

History
375 lines (317 loc) · 41.1 KB

File metadata and controls

375 lines (317 loc) · 41.1 KB

Crafty - 3D Minecraft-Style Browser Game

ADDENDUM (2026-06-30, v6+v7): De-monolith (v6): SimplifiedNPCSystem 934→183 (7 ECS systems + _npcShared seam → src/systems/) + GameScene 933→304 (6 render drivers + _sceneScratchsrc/render/) fully dissolved; PositionTracker → src/systems/; Components.jsx ~1330 is the documented IRREDUCIBLE Player useFrame controller (delegates all pure logic to 32 game/* 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 modules src/game/spellMotion.js (computeSpellMotion per-element motion grammar: roil/static/strobe/orbit) + src/render/spellGeometry.js (buildFireTeardrop blackbody-ramp teardrop, buildIceShards merged solid crystal cluster; deterministic module-load static geometry); render/spellVfx.jsx renderSilhouette branches teardrop/shards/bolt(thin additive wire)/sigil(rune-wheel+duotone); data in game/spellVisualProfiles.js ENERGY_PROFILE (added motion/midColor/glowShape fields). Weather (v7): game/weatherGate.js gained pure precipFor(weather,biome) — the state machine is now clear↔storm with the player's biome deciding rain/snow/dry; the 3 weather instancedMeshes carry frustumCulled={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 = git main + 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.js is the single intent source-of-truth (getInput()/setIntent/setActive) that all player combat verbs gate on, decoupling KB+mouse from a future touch layer (active replaces scattered document.pointerLockElement). New pure combat helpers live in src/combat/ (cone.js isPointInCone, ribbonIndices.js). Melee now hits the boss (was spell-only); boss bossActive is a single-source store value. NOTE: InputManager.jsx is a 2nd input path not yet migrated onto inputState (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.js decideTransform — charge→commit→duration→exit/cooldown; the store's beastFormActive is 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.js FORM_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). MobToonMaterial gained a per-instance rimColor/rimStrength (mobs unaffected). Capture caveat: the in-world beast capture (spawnBeastTransform test 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 via input/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 gate npm run test:look (scripts/visual/look-e2e.mjs). (2) MUSIC: ElevenLabs day/night/boss tracks (frontend/public/music/*.mp3) + smooth crossfade via src/ui/MusicPlayer.jsx; procedural pad/arp MUTED (SoundManager PROC_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.js baseHeight 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).

Project Overview

A 3D browser game built with React and Three.js, featuring Minecraft-style gameplay with block building, magic system, NPCs, and procedural terrain generation.

Tech Stack

  • 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 (postprocessing peer)
  • 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 via applyThemeVars() at boot + TW_COLORS/TW_SCALES) → tailwind.config.cjs theme.extend referencing the vars (parity-tested by tests/theme/tailwind-wiring.test.js). Component primitives in src/ui/primitives/ — read the set from its index.js rather than this line (there is no Tooltip; there ARE Slider and Modal; cn is 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.js hard-asserts single-language + zero-emoji). i18n in src/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 the Icon primitive's GAME_NAMES/CHROME maps. Item registry src/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 a loadWorldData save normalizer for legacy emoji keys. Zero emoji in src/ (hard-gated). CreditsScreen.jsx attributes game-icons.net + fonts. DEV-only PrimitivesShowcase gates the system via 2 visual-regression states.

Core Features

  • 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); flags ao/godRays/bloomMipmap/shadowMapSize/renderDistance/weather/dprCap + charOutline (med+) / charRim (high). Capture forces high for 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 — continuous mood∈[0,2] (explore→dusk→obsidian) via a moodRef singleton; <Atmosphere> = camera-following gradient SkyDome + mood-lerped ambient/sun/fill/fog off tokens.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 gradient DataTexture, fresnel-rim onBeforeCompile patch, OUTLINE/RIM/TOON config, flashableMaterial hit-flash allow-list. [M2b]
  • GameScene <EffectComposer> — N8AO → GodRays (sun mesh) → HueSaturation → BrightnessContrast → Bloom → SMAA → ToneMapping NEUTRAL (ACES muted the stylized palette; the composer overrides gl.toneMapping, so tone mapping MUST be a composer effect) → Noise → Vignette. Terrain uses an in-shader sRGB decode (pow(rgb,2.2)) + a mood desaturation 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.

Architecture

/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

Controls

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

Mob Types

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 Types

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)
Shield NEVER BUILT as a spell. game/spells.js has exactly four. "Shield" exists only as offhand EQUIPMENT (game/equipment.js).

Block Types

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

Player Systems

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

Key Configuration

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

Testing Status

  • ✅ 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

RPG Overhaul Architecture (SOTA Systems)

1. 3D Voxel-Height Aware Pathfinding Worker

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.

2. Stateful 3-Phase Epic Boss Event (Shadow Dragon)

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 useFrame game 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.

3. Keyboard Pet Commands Interface

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.

AI Structural Laws

  • 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 (like damageMob or grantXP) in Zustand; use the dedicated GameMethods.js module.
  • Component Design: Proactively decompose massive monolithic React orchestrator components into specialized layers (e.g., GameScene, HUD, InputManager) to prevent re-render cascading. Use useShallow when 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 use InstancedMesh combined with custom onBeforeCompile vertex 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.

Interactive SOTA Overhaul (May 2026)

1. Visceral Combat Impact Engine

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).

2. Spell-Casting Hands & Aura Visuals

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.

3. Atmospheric Day/Night Fog

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.background on 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).

SOTA Visuals, Volumetric Weather & Cavern Acoustics (May 2026)

1. Interactive GPU Grass Displacement

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 playerPosition into the shared grass material.
  • Quadratic Bending Shaders: In the onBeforeCompile vertex 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 onBeforeCompile hook 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.

3. Volumetric Weather Systems & Night Fireflies

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 weather multiplier — low 0.25 / med 0.6 / high 1.0) in a 40m box centred on the player. render/WeatherSystem.jsx.
  • Terrain Colliders: Particles query getMobGroundLevel to 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.

4. Cavern Acoustics & Depth-Based Reverb

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.

SOTA 3D Greedy Voxel Mesher (May 2026)

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.

SOTA Rapier Kinematic Character Controller (May 2026)

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 type is changed to kinematicPosition, 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.0 terminal velocity) to simulate realistic jumping and falling curves.
  • Decayed Impulse Redirection: Overrides the standard applyImpulse method 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.

SOTA WebGL2 DataArrayTexture Voxel Texturing & Wind Foliage (May 2026)

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.js calculates local UV coordinates matching CCW corners [0,0], [0,h], [w,h], [w,0] for each greedy quad of size $w \times h$. By binding uv attributes inside Terrain.jsx, textures tile perfectly tile-by-tile across merged faces without stretching.
  • Vertex Color Layer Packing: Packs the raw blockType integer inside the geometry's color.r channel. The fragment shader updates in onBeforeCompile read this coordinate on every frame, sampling the precise layer slice using texture(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.jsx to bind an entityPositions[8] uniform array. The vertex shader loops through all active entity slots (player, pets, and mobs from the central Miniplex ECS world synced in useFrame) 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.

SOTA Melee Trails, Procedural Swords & GPU Sparks (May 2026)

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 WebGL2 ShaderMaterial that 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 damageMob to 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.

S2-B1 WILDHEART — Beast-Transform Aspect (June 2026) — the LEAD signature Aspect

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/restoreBaseCollider helpers). 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.jsx does the in-place Rapier setShape (handle preserved → no re-bind, ZERO voxel edits): ENTER is queued + consumed in useFrame (atomic with the sweep + grow-depenetration), EXIT-restore is imperative at the death/load edge (must drain even while the dead-window useFrame early-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). The roar verb is a REAL useFrame intent consumer (KeyRsetIntent('roar')getInput().roar, the touch-ready input-abstraction), ticked above the dead-window early-return so a charge cancels at death. elementForSpell maps 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-slot store.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 (a ferocity feral token through tokens→cssVars→tailwind; StatBar kind='ferocity'; gated on >0 so the capture states stay byte-identical).
  • Combat + locomotion re-skin (M5): per-form combat (damageMult/cooldownMult) + locomotion (moveMult/gravityMult/jumpMult) multipliers extend the static BEAST_FORMS table, applied AT the read site (derive-never-bake; human = identity no-op). Melee via resolveFormMelee(rawDamage, element) -> {dealt, sparkType} (damage × the form mult on top of getEffectiveAttributes(); spark derived from the LOCKED form element via spellForElement, never the live activeSpell — so a mid-form spell-switch can't desync the spark from the body). Cone range/arc are NOT per-form (boss + mob hit-reg parity); cooldown × cooldownMult (hit-reg-safe). Locomotion mults multiply speed/jump/gravity in the movement useFrame (transient getState); hawk = low-gravity hops, not flight. turnRate omitted (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 in memory/S2B1-M5-MOTION.md.
  • Talent unlock-gate (M6): the roar is a TALENT-gated signature ability. src/game/talentTree.js gains 2 effect-less wildheart nodes — wildheart_roar (pure unlock) + wildheart_endurance (an ability-LEVER: +3s form-duration/rank via formDurationFor, read at the duration site, NOT the stat-fold). foldTalentEffects node-shape contract: signature/unlock/lever nodes omit .effect; the fold SKIPS them (the guard || !node.effect — it previously hard-crashed on the unconditional node.effect destructure, affecting all 4 Aspects + every getEffectiveAttributes()); levers read their rank at their own math site. The roar canEnter ANDs unlockedTalents.wildheart_roar > 0 with the full-bank gate (gates startCharge + commit). unlockedTalents already persists; the nodes survive refundUnknownTalents. WILDHEART MECHANICS LAYER COMPLETE (M0-M6 + M3.5); M7-M8 = the LOOK (reference-locked VFX, judged in-world).