Adding a New Enemy
Step-by-Step
1. Define the Entity Config
Add to enemies/shared/utils/enemy-registry.ts:
ShadowStalker: {
triggerRadius: 30,
chaseRadius: 50,
attackRange: 5,
speed: 4,
damage: 999, // instant kill
}
2. Create ECS Tag
Add to shared/ecs/components/tags/:
export const IsShadowStalker = world.component();
3. Write the Behavior System
Create shared/ecs/systems/server/shadow-stalker-behavior-system.ts:
export function shadowStalkerBehaviorSystem() {
for (const [entity] of world.query(IsShadowStalker, Position, EnemyState)) {
const state = world.get(entity, EnemyState);
// State machine logic here
}
}
4. Register in EnemyService
In enemy-service.ts, add a spawn function and register the behavior system in the heartbeat loop.
5. Add to Slot Generator
In enemy-slot-generator.ts, add spawn conditions:
case "Tense":
if (random.chance(0.2) && pacingInfo.trailMarker >= 5) {
enemies.push({ type: "ShadowStalker", count: 1 });
}
break;
6. Create the Model
Add a prefab model to ReplicatedStorage.Assets.Enemies.ShadowStalker.
7. Add Sound Effects
Define in enemies/shared/enemy-sounds.ts for spatial audio.
Key Patterns
- State machine: Use
EnemyStatecomponent withStateSincefor timing - Safe zone check: Use the callback pattern (
setSafeZoneCallback) - Network sync: Add
NeedsSynctag for automatic position broadcasting - Debug logging: Gate behind a debug flag