unity-dots

v2026.09.24

Unity DOTS — Entities 1.x, Burst-compiled jobs, IJobChunk / IJobEntity, NativeArray / NativeList, SystemBase vs ISystem, baking GameObject to entity, hybrid components. USE WHEN: massive entity counts (RTS, swarms, particles-as-entities), data-oriented refactor of hot simulations, deterministic netcode targets, Burst-friendly math. DO NOT USE FOR: regular GameObject gameplay (use `unity-core`); rendering (DOTS uses Entities Graphics — link from `unity-rendering`); networking with NGO (use `unity-netcode`).

GitHub
Install command
npx skhub add claude-dev-suite/unity-dots
Markdown
SKILL.md

Unity DOTS / ECS (Entities 1.x)

When (and when not)

DOTS shines with lots of similar things doing lots of similar work: 10k+ units, particle-as-entity sim, deterministic physics for netcode. For typical character-based gameplay (a player, ~10 enemies, UI) classic GameObjects + MonoBehaviour are simpler and fast enough.

Mixing both: hybrid mode — GameObjects for hero/UI, ECS for swarms.

Components

public struct Position : IComponentData { public float3 Value; }
public struct Velocity : IComponentData { public float3 Value; }
public struct Health   : IComponentData { public float Value; }
public struct Enemy    : IComponentData {} // tag

public struct Inventory : IBufferElementData {     // dynamic buffer
    public Entity Item;
    public int    Count;
}

All IComponentData are blittable structs (no reference types directly).

Systems — ISystem (preferred over SystemBase for Burst)

[BurstCompile]
public partial struct MoveSystem : ISystem {
    public void OnUpdate(ref SystemState state) {
        float dt = SystemAPI.Time.DeltaTime;
        new MoveJob { DeltaTime = dt }.ScheduleParallel();
    }
}

[BurstCompile]
public partial struct MoveJob : IJobEntity {
    public float DeltaTime;
    void Execute(ref Position pos, in Velocity vel) {
        pos.Value += vel.Value * DeltaTime;
    }
}

partial struct lets Unity generate the iteration boilerplate at compile time.

Querying

foreach (var (transform, velocity) in
         SystemAPI.Query<RefRW<Position>, RefRO<Velocity>>().WithAll<Enemy>()) {
    transform.ValueRW.Value += velocity.ValueRO.Value * dt;
}

RefRW = read/write, RefRO = read-only (better job scheduling).

Baking — GameObject → Entity

public class EnemyAuthoring : MonoBehaviour {
    public float Speed;
}
public class EnemyBaker : Baker<EnemyAuthoring> {
    public override void Bake(EnemyAuthoring authoring) {
        var e = GetEntity(TransformUsageFlags.Dynamic);
        AddComponent(e, new Velocity { Value = new float3(0, 0, authoring.Speed) });
        AddComponent<Enemy>(e);
    }
}

Designers tweak in Inspector; baking turns Authoring components into Entity components at subscene conversion time.

Sub Scenes

Big static worlds → put in a SubScene asset, baked offline → loaded by streaming. Smaller content/dynamic spawning → spawn at runtime via EntityManager.CreateEntity.

Anti-patterns

Anti-patternFix
Storing Entity references in class MonoBehaviourUse bridge ScriptableObject + lookup, or hybrid component
EntityManager.CreateEntity per frame from main threadUse EntityCommandBuffer.ParallelWriter from a job
Mixing managed types in IComponentDataUse IComponentData blittable + companion class component if absolutely needed
Forgetting Burst attribute[BurstCompile] on systems & jobs — verify in Burst Inspector
Heavy EntityQuery per frameCache via state.GetEntityQuery in OnCreate

Production checklist

  • DOTS used only where it beats GameObject perf measurably
  • All hot systems Burst-compiled
  • EntityCommandBuffer used for structural changes
  • SubScenes for static content
  • Authoring components reviewed by designers
  • Determinism verified if ECS feeds netcode
Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

MIT

Source path

skills/gamedev/unity-dots

Default branch

main

Latest commit

9496306

Tree SHA

fe4e2f1