AGENT SKILL

wave8-ecb-system-group-mismatch

Identify and fix bugs caused by using an ECB from the wrong system group, resulting in structural change commands executing at the wrong frame boundary.

License 许可
MIT
最近更新
2026-07-25
Stars
★ 8
Forks
0

01 前言 Front Matter

name
wave8-ecb-system-group-mismatch
tags
[ "ecb", "antipattern", "debug" ]
metadata
{ "tier": 3, "internal-only": true }
description
Identify and fix bugs caused by using an ECB from the wrong system group, resulting in structural change commands executing at the wrong frame boundary.

03 SKILL.md 正文

ECB System Group Mismatch — Wrong Playback Timing

Intent

Identify and fix bugs caused by using an ECB from the wrong system group, resulting in structural change commands executing at the wrong frame boundary.

Use When

  • Diagnosing one-frame-late structural changes, components appearing/disappearing unexpectedly, or ECB playback order bugs
  • Code review of any system that records ECB commands to an ECBSystem singleton

Avoid When

  • Using a manually created ECB with explicit Playback — group mismatch only affects ECBSystem-owned buffers, not manual ECBs

Senior Pattern

// WRONG — EndSimulationECBSystem from within FixedStepSimulationSystemGroup:
// Commands play back after SimulationSystemGroup ends (variable rate), not after FixedStep ends
[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
public partial struct FixedPhysicsReactionSystem : ISystem
{
    public void OnUpdate(ref SystemState state)
    {
        // Wrong ECB system — playback happens at wrong frame boundary:
        var ecbSystem = SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>();
        var ecb = ecbSystem.CreateCommandBuffer(state.WorldUnmanaged);
    }
}

// CORRECT — use the ECB system matching the enclosing group:
[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
public partial struct FixedPhysicsReactionSystem : ISystem
{
    public void OnUpdate(ref SystemState state)
    {
        var ecbSystem = SystemAPI.GetSingleton<EndFixedStepSimulationEntityCommandBufferSystem.Singleton>();
        var ecb = ecbSystem.CreateCommandBuffer(state.WorldUnmanaged);
        // Commands play back at end of FixedStepSimulationSystemGroup — correct timing
    }
}

ECB System Selection Guide

Enclosing System Group Correct ECB System
InitializationSystemGroup BeginInitializationEntityCommandBufferSystem or EndInitializationEntityCommandBufferSystem
SimulationSystemGroup BeginSimulationEntityCommandBufferSystem or EndSimulationEntityCommandBufferSystem
FixedStepSimulationSystemGroup EndFixedStepSimulationEntityCommandBufferSystem
PresentationSystemGroup EndPresentationEntityCommandBufferSystem

Anti-Patterns

  • Always using EndSimulationEntityCommandBufferSystem regardless of enclosing group — one-frame-late bugs in FixedStep systems; structural changes visible at wrong simulation tick.
  • Mixing Begin and End ECB systems within the same system — playback order ambiguity; both valid individually but inter-system ordering breaks down.
  • Using an ECB from a different World — throws InvalidOperationException at playback.
  • Forgetting that FixedStepSimulationSystemGroup runs multiple times per rendered frame — using EndSimulation ECB means commands from tick N play back after SimulationSystemGroup, not between tick N and tick N+1.

Runtime Risks

  • Wrong ECB group causes structural changes to apply at the wrong system group boundary — one or more ticks late.
  • In FixedStep scenarios, this can produce a one-rendered-frame delay that is difficult to reproduce deterministically (depends on whether the fixed group ran once or twice that frame).
  • Silent correctness bug: no exception, just wrong frame-of-effect for spawning, destroying, and component changes.

Performance Notes

  • No performance difference between ECB systems — correctness is the only concern here.
  • Wrong ECB system choice does not cause measurable performance impact; it causes logical correctness failures.

Architecture Guidance

  • Hard rule: match ECB system to enclosing system group.
  • When the choice is non-obvious (e.g., Begin vs End within the same group), document which ECB system is used and why at the system declaration.
  • For systems inside FixedStepSimulationSystemGroup, EndFixedStepSimulationEntityCommandBufferSystem is almost always correct.

Related Skills

[[ecb-system-timing]], [[wave5-fixed-step-simulation-system-group]], [[wave8-wrong-system-group-fixed-timestep]], [[entity-command-buffer]]

04 同仓库更多 Skills

dyCuong03
dyCuong03/unity-agent-team

dots-update-groups

How to choose the right ECS system group and ordering so per-frame and per-fixed-step work is deterministic and never races its own readers. Covers InitializationSystemGroup / SimulationSystemGroup / PresentationSystemGroup / FixedStepSimulationSystemGroup / VariableRateSimulationSystemGroup, UpdateBefore / UpdateAfter peer ordering, OrderFirst / OrderLast group-boundary placement, RateManager, and the cross-group ordering trap. Use when adding an ISystem, fixing "value visible one frame late" bugs, or coupling simulation to a fixed timestep.

★ 8
dyCuong03
dyCuong03/unity-agent-team

dots-transform-patterns

The Entities 1.x transform model — LocalTransform (writable input) vs LocalToWorld (system-owned matrix), Parent/Child hierarchy, reparenting cost, uniform vs non-uniform scale (PostTransformMatrix), and when to opt out with custom transform systems. Use when designing parent/child hierarchies, runtime reparenting (mount/dismount/socket), or choosing transform components at the Baker boundary.

★ 8
dyCuong03
dyCuong03/unity-agent-team

dots-singleton-patterns

Model cross-system shared configuration and game state as a single-entity component with a strict single-writer contract. Covers RequireForUpdate gating, SystemAPI.GetSingleton / GetSingletonRW / HasSingleton / TryGetSingleton, bake-time vs runtime-created vs ECB-system singletons, the "exactly one entity" runtime invariant, and the single-writer rule. Use when designing frame-stable global config, shared mutable state, or any component intended to exist on exactly one entity.

律师与法务
★ 8
dyCuong03
dyCuong03/unity-agent-team

dots-hybrid-bridge

The one-way bridge between DOTS-owned runtime state and Unity-owned presentation. Covers UnityObjectRef for managed asset refs in components, the DOTS-writes / Unity-reads ownership rule, when to use managed IComponentData vs UnityObjectRef vs CompanionComponent, baker-bridge vs runtime-bridge, and SubScene boundary rules. Use when an entity must reference Unity assets (Mesh, Material, AudioClip, ScriptableObject), a MonoBehaviour view must read entity state, or input/UI must trigger ECS work.

★ 8
dyCuong03
dyCuong03/unity-agent-team

dots-event-driven-ecs

Model one-frame events and external requests in ECS without dual ownership, polling, or persistent state leaks. Covers request-tag pattern with ECB, enableable command components (no structural change), event buffers (IBufferElementData), explicit consumer ownership, one-frame latency rules, and the banned C# event / UnityEvent / static bus anti-patterns. Use when input/UI/network must trigger ECS work, when a one-frame signal fans out to N consumers (damage, hit, collision), or when state changes must be processed exactly once.

★ 8
dyCuong03
dyCuong03/unity-agent-team

valid_skill

A complete, well-formed test fixture skill for SkillHub validation testing. Covers basic task routing and code review for Unity projects.

代码审查测试与质量
★ 8