Skip to main content

ParticleManager

Central particle routing system that dispatches particle events to specialized sub-managers.

Constructor

Parameters:
  • scene: Three.js scene to add particle meshes to
Example:

Methods

register

Register a particle emitter with discriminated union config.
Parameters:
  • id: Unique identifier for the emitter
  • config: Particle configuration (WaterParticleConfig | GlowParticleConfig)
Example:

unregister

Unregister a particle emitter. No type hint required (ownership map resolves automatically).
Parameters:
  • id: Emitter identifier to remove
Example:

move

Move an existing emitter to a new position. No type hint required.
Parameters:
  • id: Emitter identifier to move
  • newPos: New world position
Example:

handleResourceEvent

Handle a resource event (e.g. RESOURCE_SPAWNED) and route to appropriate manager.
Parameters:
  • data: Event data with id, type, position
Example:

update

Drive all particle managers. Called once per frame.
Parameters:
  • dt: Delta time in seconds
  • camera: Three.js camera for billboard orientation
Example:

dispose

Dispose all particle managers and clean up GPU resources.
Example:

Types

ParticleConfig

Discriminated union of all particle configuration types.

WaterParticleConfig

Configuration for water-type particles (fishing spots).
Fishing Spot Variants:
  • fishing_spot_net: Calm, gentle ripples (4 splash, 3 bubble, 3 shimmer)
  • fishing_spot_bait: Medium activity (5 splash, 4 bubble, 4 shimmer)
  • fishing_spot_fly: Active, moving water (8 splash, 5 bubble, 5 shimmer)

GlowParticleConfig

Configuration for glow-type particles (altars, fires, torches).
Parameters:
  • preset: ‘altar’ | ‘fire’ | ‘torch’
  • color: Single hex (0x00ffff) or three-tone palette
  • meshRoot: Mesh for geometry-aware spark placement (altar preset)
  • modelScale: Scale of loaded model (default 1.0)
  • modelYOffset: Vertical offset applied to model (default 0)
Preset Particle Counts:
  • altar: 12 particles (samples mesh geometry)
  • fire: 8 particles (rising with spread)
  • torch: 6 particles (tight 0.08 spread)

ParticleResourceEvent

Lightweight event shape emitted by ResourceSystem.

WaterParticleManager

GPU-instanced fishing spot effects using 4 InstancedMeshes.

Methods

registerSpot

Register a fishing spot for particle rendering.

unregisterSpot

Unregister a fishing spot and free particle slots.

moveSpot

Move a fishing spot to a new position.

update

Per-frame particle animation update.

dispose

Dispose all GPU resources.

Particle Layers

Splash Layer:
  • Parabolic arc trajectories
  • 0.6-1.2s lifetime
  • 0.05-0.35m radial spread
  • 0.12-0.32m peak height
Bubble Layer:
  • Rising with lateral wobble
  • 1.2-2.5s lifetime
  • 0.04-0.24m radial spread
  • 0.3-0.55m rise height
Shimmer Layer:
  • Surface glints with twinkle
  • 1.5-3.0s lifetime
  • 0.15-0.6m radial spread
  • GPU-computed twinkle animation
Ripple Layer:
  • Expanding ring waves
  • Continuous loop (no lifetime)
  • 0.15-1.45m scale range
  • Phase-based opacity fade

GlowParticleManager

Instanced glow billboards for altars, fires, and torches.

Methods

registerGlow

Register a glow emitter.

unregisterGlow

Unregister a glow emitter.

moveGlow

Move a glow emitter to a new position.

update

Per-frame particle animation update.

dispose

Dispose all GPU resources.

Presets

Altar Preset:
  • 12 particles sampling mesh geometry vertices
  • Mesh-aware placement (requires meshRoot)
  • Upward rise with spread
  • Color: Cyan (0x00ffff) or custom
Fire Preset:
  • 8 particles rising with spread
  • Random radial distribution
  • Parabolic rise trajectories
  • Color: Orange-red gradient or custom
Torch Preset:
  • 6 particles with tight spread (0.08)
  • Concentrated flame effect
  • Minimal lateral movement
  • Color: Orange (0xff8800) or custom

Performance

Draw Call Reduction

Before:
After:

Memory Usage

Per Fishing Spot:
  • Before: ~500KB (150 meshes × ~3.3KB each)
  • After: ~5KB (particle slot data in shared buffers)
100 Fishing Spots:
  • Before: ~50MB
  • After: ~2MB (98% reduction)

FPS Impact

Reference Hardware (RTX 3060 Ti):
  • Before: 65-70 FPS with 10 fishing spots
  • After: 120 FPS with 10 fishing spots

Integration Example

Complete integration in ResourceSystem:

Vertex Buffer Budget

InstancedMesh has a maximum of 8 vertex attributes: Particle Layers (7 of 8):
  1. position (built-in)
  2. uv (built-in)
  3. instanceMatrix (built-in)
  4. spotPos (custom, vec3)
  5. ageLifetime (custom, vec2)
  6. angleRadius (custom, vec2)
  7. dynamics (custom, vec4)
Ripple Layer (5 of 8):
  1. position (built-in)
  2. uv (built-in)
  3. instanceMatrix (built-in)
  4. spotPos (custom, vec3)
  5. rippleParams (custom, vec2)
Adding more custom attributes requires removing existing ones or splitting into multiple InstancedMeshes.

See Also