job-dependency-chain
Wire every scheduled job into the system''s dependency chain via state.Dependency so the ECS scheduler can automatically enforce read/write ordering between systems without explicit sync points.
- License 许可
- MIT
- 最近更新
- 2026-07-25
- Stars
- ★ 8
- Forks
- 0
01 前言 Front Matter
- name
- job-dependency-chain
- tags
- [ "core", "jobs", "performance" ]
- metadata
- { "tier": 3, "internal-only": true }
- description
- Wire every scheduled job into the system''s dependency chain via state.Dependency so the ECS scheduler can automatically enforce read/write ordering between systems without explicit sync points.
03 SKILL.md 正文
Job Dependency Chain
Intent
Wire every scheduled job into the system's dependency chain via state.Dependency so the ECS scheduler can automatically enforce read/write ordering between systems without explicit sync points.
Use When
Every IJobEntity.Schedule / ScheduleParallel and IJobChunk.Schedule / ScheduleParallel call, without exception.
Avoid When
There is no "avoid when" — this is non-negotiable for every job schedule call.
Senior Pattern
- Pass current
state.Dependencyas the dependency parameter to Schedule/ScheduleParallel. - Assign the returned JobHandle back to
state.Dependency. - The ECS scheduler reads
state.Dependencyafter OnUpdate and wires it into the next system's input automatically. - Only call
state.Dependency.Complete()when main-thread access to job results is required in the same frame — this is an explicit sync point.
Code Template
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
// Chain: pass in, assign out — always.
state.Dependency = new PrepareJob { ... }
.ScheduleParallel(state.Dependency);
state.Dependency = new ConsumeJob { ... }
.Schedule(state.Dependency); // sequential after PrepareJob
// Only call Complete() when you MUST read results on main thread this frame:
// state.Dependency.Complete(); // explicit sync point — document why
}
Anti-Patterns
- Forgetting to assign
state.Dependency = job.Schedule(...)— silent data race, intermittent wrong results. - Calling
.Complete()at the end of every OnUpdate as "safety" — introduces a full sync point every frame, stalls all worker threads. - Scheduling two jobs in the same OnUpdate without chaining the first result into the second's dependency — jobs may race.
- Using a local JobHandle variable and never assigning it to state.Dependency — the dependency is lost.
Runtime Risks
- Missing chain: data race between systems — non-deterministic, hardware-dependent, extremely hard to debug.
- Unnecessary Complete(): worker thread stall every frame, frame time spike, CPU underutilization.
Performance Notes
Correct chaining allows the scheduler to run jobs from different systems in parallel when their read/write domains do not conflict. Breaking the chain forces serialisation. Never call Complete() without profiling evidence that the stall is acceptable.
Architecture Guidance
Treat state.Dependency as the system's contract with the scheduler. In = work I depend on completing. Out = work I have scheduled. Never break the contract silently.
04 同仓库更多 Skills
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.
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.
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.
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.
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.
valid_skill
A complete, well-formed test fixture skill for SkillHub validation testing. Covers basic task routing and code review for Unity projects.