THREE.js and ECSY. You plant over 30 flower varieties, interact with wildlife, take in-VR photographs, and navigate using teleportation, snap turn, and joystick locomotion. The codebase uses ECS architecture, WebXR session management with desktop fallback, curved raycasting for plant placement, and a comprehensive asset pipeline with KTX2 compression.| File / Directory | Demonstrates | Key concepts |
|---|---|---|
src/index.js | Application entry point, THREE.js initialization, ECSY world creation | WebXR session creation, iwer device emulation fallback, BVH raycasting attachment, rendering loop setup |
src/js/ECSYConfig.js | Three-phase ECS system registration | Startup systems, after-load systems, after-ready systems for progressive feature initialization |
src/js/systems/core/ | Bootstrap, scene creation, rendering, input, player physics | WebXR lifecycle management, capsule-based player collision, gravity simulation |
src/js/systems/hands/ | Controller detection, hand model loading, bone-based animation | Context-aware hand poses per interaction mode, per-bone quaternion slerp |
src/js/systems/plants/ | Planting, growth, watering, picking | Curved raycasting to surfaces, seed projectile animation, PD spring dynamics for growth |
src/js/systems/fauna/ | Wildlife spawning, movement, animation | Bounded random movement, distance-based culling, skeleton and morph target animation |
src/js/systems/locomotion/ | Teleportation, snap turn, joystick movement, comfort vignette | Curved ray validation with obstacle detection, dynamic vignette for motion comfort |
src/js/systems/audio/ | Spatial audio with Howler.js | 3D positional audio, dynamics compressor, ambient sound creation |
src/js/systems/performance/ | Runtime performance optimization toggles | Shadow map control, render distance adjustment, framebuffer scaling |
src/js/systems/mesh/ | Auto-instancing and dynamic mesh optimization | Naming convention-based instancing (Name__001), per-plant dynamic instancing |
src/js/systems/xplat/ | Desktop keyboard and mouse control emulation | WASD and mouse look mapped to emulated WebXR controller inputs |
src/js/lib/ | Reusable rendering, collision, and audio utilities | Custom shaders, KD-tree spatial partitioning, curved raycaster, LOD with hysteresis |
src/js/components/ | Component schemas for ECSY entities | Game state machine, controller interface, planted item serialization |
asset_pipeline/ | GLTF model and texture compression pipeline | KTX2 basis compression, meshopt encoding, vertex quantization, incremental builds |
ECSY v0.4.2 to organize logic into 75+ systems and 70+ component classes. Systems use static queries to track entity changes, and singletons like THREEGlobalComponent bridge THREE.js objects into the ECS world. Three-phase registration in src/js/ECSYConfig.js ensures core systems initialize first, gameplay systems load after assets are ready, and audio systems activate last.immersive-vr session with local-floor and bounded-floor reference spaces in src/js/lib/VRButton.js. When navigator.xr does not support VR, src/index.js creates an XRDevice from the iwer library that emulates a Meta Quest 3, or Quest 3S at the WebXR API level. The XPlatControlSystem in src/js/systems/xplat/xplat.js maps keyboard and mouse inputs to the emulated controller state, so all ECS systems run identically on VR and desktop without branching code paths.ControllerInterface in src/js/lib/ControllerInterface.js wraps WebXR gamepad input into a clean API with edge detection (buttonJustPressed(), triggerJustReleased()), joystick angle interpretation, and haptic feedback. The VrInputSystem polls controller state each frame, and other systems query entities with VrControllerComponent to read normalized input.CurvedRaycaster in src/js/lib/objects/CurvedRaycaster.js projects a parabolic curve from the controller and tests intersection with scene meshes using three-mesh-bvh acceleration. The PlantingSystem validates that the intersection point lies on a planting surface and is not blocked by obstacles, then visualizes the landing zone with a green ring indicator. See src/js/systems/plants/PlantingSystem.js for the full validation logic.ModelOptimizeSystem automatically instances meshes that follow the naming convention Name__001, while LODWithHysteresis switches detail levels with a 5-unit threshold to prevent popping. The PerformanceOptionsSystem exposes runtime toggles for shadow updates, render distance, and framebuffer scale. See src/js/systems/performance/ and src/js/systems/mesh/ for the complete optimization implementations.asset_pipeline/asset_pipeline.js uses @gltf-transform to compress GLTF models through texture compression (KTX2 basis), geometry optimization (tangent generation, quantization), and GPU cache reordering (meshopt). The pipeline supports per-directory overrides and incremental builds that skip files where output is newer than source.PLANT_TYPES enum in src/js/Constants.js, and register growth parameters in the PlantGrowingSystem.MovableFaunaSystem in src/js/systems/fauna/MovableFaunaSystem.js with custom movement patterns or interaction triggers.GameStateComponent state machine in src/js/components/GameStateComponent.js and implement corresponding systems.