Jobs & Burst¶
Trecs integrates with Unity's job system and Burst compiler for parallel, high-performance entity processing.
WrapAsJob — The Simplest Approach¶
Mark a static [ForEachEntity] method with [WrapAsJob] to generate a Burst-compiled parallel job:
public partial class ParticleMoveSystem : ISystem
{
[ForEachEntity(Tag = typeof(SampleTags.Particle))]
[WrapAsJob]
static void Execute(in Velocity velocity, ref Position position, in NativeWorldAccessor world)
{
position.Value += world.DeltaTime * velocity.Value;
}
}
The source generator creates the job struct, scheduling method, and dependency tracking automatically. The method must be static because it is called from inside a job and must use NativeWorldAccessor instead of WorldAccessor
Manual Job Structs¶
For more control, define a job struct yourself with a [ForEachEntity] Execute method:
public partial class ParticleJobSystem : ISystem
{
[BurstCompile]
partial struct MoveJob
{
public float DeltaTime;
[ForEachEntity(Tag = typeof(SampleTags.Particle))]
public readonly void Execute(in Velocity velocity, ref Position position)
{
position.Value += DeltaTime * velocity.Value;
}
}
public void Execute()
{
new MoveJob { DeltaTime = World.DeltaTime }.ScheduleParallel(World);
}
}
The Trecs Source Generator will add a ScheduleParallel extension method for your job struct that handles the iteration and component access.
This gives you control over the job struct fields (e.g., passing precomputed values like DeltaTime), while the source generator still handles scheduling and dependency tracking.
However note that you can also use [PassThroughArgument] on fields of a [WrapAsJob] method to achieve the same effect without defining a job struct.
NativeWorldAccessor¶
NativeWorldAccessor is the job-safe counterpart to WorldAccessor. It supports structural operations with a sortKey parameter for deterministic ordering:
// In a job:
nativeWorld.AddEntity<GameTags.Bullet>(sortKey: (uint)index)
.Set(new Position(pos));
nativeWorld.RemoveEntity(entityIndex);
nativeWorld.MoveTo<BallTags.Ball, BallTags.Resting>(entityIndex);
Sort Keys¶
When RequireDeterministicSubmission is enabled, sort keys determine the order structural operations are applied. Use entity IDs or loop indices as sort keys for reproducible results.
Thread Safety Rules¶
| Operation | Main Thread | Jobs |
|---|---|---|
| Read components | WorldAccessor |
NativeComponentBufferRead, NativeComponentLookupRead |
| Write components | WorldAccessor |
NativeComponentBufferWrite, NativeComponentLookupWrite |
| Add/remove entities | WorldAccessor (deferred) |
NativeWorldAccessor (deferred + sort key) |
| Move entities | WorldAccessor (deferred) |
NativeWorldAccessor (deferred + sort key) |
| Read sets | SetAccessor.Read |
NativeSetRead |
| Write sets | SetAccessor.Write |
NativeSetWrite |
Warning
WorldAccessor is main-thread only. Always use NativeWorldAccessor and native component types inside jobs.
For advanced job features — [FromWorld] auto-wiring, native component access types, native set operations, and external job tracking — see Advanced Job Features.