Skip to main content

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 EnemyState component with StateSince for timing
  • Safe zone check: Use the callback pattern (setSafeZoneCallback)
  • Network sync: Add NeedsSync tag for automatic position broadcasting
  • Debug logging: Gate behind a debug flag