Enemy System
Enemies are managed through the ECS (see ECS System) with spawning orchestrated by EnemyService.
Enemy Types
Hostile Entities
| Entity | Damage | Speed | Behavior |
|---|---|---|---|
| FlowerTrap | 20 | 10 | Weeping Angel — can't move while observed |
| PathMonster | Instant kill | 36 | Charges down path, must hide to survive |
| TreeBranchSnatcher | 20 | 40 | Drop attack from above |
| RootSnare | 20 + 3s immobilize | 0 | Ground trap |
| GigglingBush | Kill (50% chance) | 0 | 50/50 lethal/harmless |
| Watcher | Instant kill | 6 | Boss — hunts off-path players |
Neutral Entities
- NeutralFlowerTrap — Same appearance as hostile, never attacks
- NeutralRootSnare — Visible roots, safe to step over
- LostQuirkymal — Downed character to rescue (30s timer)
- MimicEntity — Appears as Lost Quirkymal, attacks rescuers
Spawning
Enemy slots are generated per chunk based on pacing:
const pacingInfo = pacingManager.getPacingForChunk(chunkIndex);
const slots = enemySlotGenerator.generate(pacingInfo);
Spawn Rules by Phase
| Phase | Flower Trap | Path Monster | Snatcher | Root Snare | Bush |
|---|---|---|---|---|---|
| Calm | 25% chance | - | - | - | - |
| Tense | 35% | 50% | 30% (marker 3+) | - | - |
| Challenge | 60% | - | 40% (marker 5+) | 30% (marker 7+) | 20% (marker 10+) |
| SafeZone | None | None | None | None | None |
Petal Palette
FlowerTrap colors are generated per session using petal-colors.ts. Both hostile and neutral traps share the same color pool — players can't distinguish by color alone.
Enemy Registry
enemy-registry.ts defines detection ranges and behaviors:
FlowerTrap: { triggerRadius: 16, chaseRadius: 50, attackRange: 5 }
PathMonster: { triggerRadius: 40, speed: 36 }
Watcher: { triggerRadius: 60, speed: 6 }
RootSnare: { triggerRadius: 3, speed: 0 } // trap
PathMonster Sweep
PathMonsters follow the global path node array:
- Pick direction (forward or backward)
- Sweep through nodes at 36 studs/sec
- Kill any unhiding player within 8 studs
- Despawn at +2 chunks from player
Watcher Boss
- Spawns when player is off-path for 30+ seconds
- Follows path nodes toward player
- Direct pursuit when close
- Cannot enter safe zones
- Debug logs gated behind
WatcherLogsflag