Scaffold a new ECS System following Conquest project conventions. AUTO-INVOKE when: (1) user asks to "create a system", "add a system", "I need a system that...", (2) new game logic needs to be wired into the ECS pipeline (movement, combat, spawning, state transitions), (3) after /new-ecs-component when the component needs processing logic. Generates the system skeleton with correct naming, [BurstCompile], [UpdateInGroup], and ISystem pattern. Always run /reuse-check FIRST. After creation, run /analyze-system and /no-magic-params.
/new-ecs-system <SystemName> [--group <SimulationSystemGroup|PresentationSystemGroup|...>] [--after <OtherSystem>] [--squad|--hero]
Before creating, invoke /reuse-check or manually search:
Glob: Assets/Scripts/**/*.System.cs
Search for systems with overlapping responsibility. If one exists, extend it rather than creating a new one.
Also read Assets/Scripts/Squads/SystemResponsibilities.md to see if the responsibility already belongs to an existing system.
| Domain | Location |
|---|
| Hero-related | Assets/Scripts/Hero/Systems/ |
| Squad/Unit-related | Assets/Scripts/Squads/Systems/ |
| Combat | Assets/Scripts/Combat/Systems/ (if exists) |
| Shared/Cross-domain | Assets/Scripts/Shared/ |
Reference the data flow from CLAUDE.md:
Input → SquadControlSystem → SquadOrderSystem → SquadFSMSystem
↓
UnitFormationStateSystem ← FormationSystem ──┘
↓
UnitFollowFormationSystem (movement only)
↓
SquadVisualManagementSystem → EntityVisualSync (per-unit)
Common groups:
SimulationSystemGroup — game logic (most systems go here)PresentationSystemGroup — visual/rendering systemsInitializationSystemGroup — setup systems (run once or infrequently)File naming: {Subject}.System.cs
using Unity.Burst;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Collections;
/// <summary>
/// [{SystemName}] — {One-line description of its single responsibility}.
/// Reads: {ComponentA}, {ComponentB}
/// Writes: {ComponentC}
/// </summary>
[BurstCompile]
[UpdateInGroup(typeof(SimulationSystemGroup))]
[UpdateAfter(typeof(PreviousSystem))] // if ordering is needed
public partial struct {SystemName}System : ISystem
{
[BurstCompile]
public void OnCreate(ref SystemState state)
{
// Require components so the system only runs when they exist
state.RequireForUpdate<{RequiredComponent}>();
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
// Use EntityCommandBuffer for structural changes
var ecb = SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>()
.CreateCommandBuffer(state.WorldUnmanaged);
// Schedule a job for Burst-compiled processing
new {SystemName}Job
{
// Pass job data
}.ScheduleParallel();
}
}
[BurstCompile]
public partial struct {SystemName}Job : IJobEntity
{
public EntityCommandBuffer.ParallelWriter Ecb;
public void Execute(Entity entity, [ChunkIndexInQuery] int chunkIndex,
ref {ComponentToWrite} writeTarget,
in {ComponentToRead} readSource)
{
// Pure logic — no side effects, no managed types
}
}
using Unity.Burst;
using Unity.Entities;
[UpdateInGroup(typeof(SimulationSystemGroup))]
public partial struct {SystemName}System : ISystem
{
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<{RequiredSingleton}>();
}
public void OnUpdate(ref SystemState state)
{
var singleton = SystemAPI.GetSingletonRW<{SingletonComponent}>();
// Operate on singleton
}
}
var config = SystemAPI.GetSingleton<{ConfigComponent}>();
// Use config.SomeValue instead of hardcoded values
Run /analyze-system <NewSystemName> to verify:
Run /no-magic-params <NewSystemFile> to verify no hardcoded values.
EntityVisualSync).ref — never store mutable state on the system struct itself (except ComponentLookup / EntityQuery cached in OnCreate).[BurstCompile] on both the system struct and the job struct whenever possible.[{SystemName}] prefix./no-magic-params).NavMeshAgent reference. If navigation intent needs to be communicated, write to an ECS component (e.g., NavAgentTarget) and let EntityVisualSync drive the agent.OnDestroy(ref SystemState state) to clean up.After writing the system file:
/analyze-system {SystemName} — verify single responsibility and data flow position/no-magic-params {SystemFile} — verify no hardcoded balance values/new-ecs-component + /new-authoring