Last Updated: [Current Date] Status: Stable (Recent fixes applied to material registry)
The Candy World foliage system creates procedural vegetation using Three.js and TSL (Three Shading Language). It relies on a centralized material registry to ensure consistent styling and reactivity to music/weather.
src/foliage/common.js: The "Source of Truth." Contains shared resources (foliageMaterials), reactive object registries, and TSL material helpers (createClayMaterial).src/foliage/factories/*.js: (e.g.,flowers.js,trees.js) specialized functions that returnTHREE.Grouphierarchies.src/world/generation.js: Orchestrates spawning. It loadsassets/map.jsonfor fixed objects and runspopulateProceduralExtras()for random vegetation.
Issue: A common crash involves TypeError: Cannot read properties of undefined (reading 'clone').
Cause: Factory functions (e.g., createFiberOpticWillow) often try to clone materials like foliageMaterials.opticTip. If this key is missing from src/foliage/common.js, the app crashes during world generation.
Rule for Agents:
Before creating a new foliage type that relies on a shared material, YOU MUST add that material definition to the
foliageMaterialsobject insrc/foliage/common.js.
Ensure src/foliage/common.js always exports:
stem,trunk,vineflowerCenter,petallightBeam(used for glowing effects)opticCable,opticTip(used for Fiber Optic Willow)lotusRing(used for Subwoofer Lotus)
- Safe Adding: We use
safeAddFoliage(obj, isObstacle, radius)to register objects. This pushes them toanimatedFoliagearrays for the animation loop. - Map vs. Procedural:
- Map Data: Fixed positions from
map.json. - Procedural:
populateProceduralExtrasscatters flowers/trees. Current limitation: Uses pure random distribution, which can cause overlapping.
- Map Data: Fixed positions from
Objects are made "reactive" (bouncing to music, swaying in wind) via attachReactivity(group) in common.js.
- Tagging: Objects are tagged with
userData.animationType(e.g.,'wobble','fiberWhip'). - Execution:
src/foliage/animation.jsiterates throughreactiveObjectsand applies transforms based on audio data.
- Instancing: Currently, every flower is a unique
Group. We need to migrate high-frequency objects (like simple grass or basic flowers) toInstancedMeshfor performance. - Collision Optimization:
obstaclesarray is checked linearly. Need a QuadTree or spatial hash if object count exceeds 1000. - Poisson Disk Sampling: Replace
Math.random()ingeneration.jsto ensure even spacing of vegetation.
Note to Copilot/Jules: If the user reports a "spawn error" or "undefined clone," 99% of the time it is a missing entry in foliageMaterials inside src/foliage/common.js.