DeltaECS.Systems 0.0.51

dotnet add package DeltaECS.Systems --version 0.0.51
                    
NuGet\Install-Package DeltaECS.Systems -Version 0.0.51
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="DeltaECS.Systems" Version="0.0.51" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DeltaECS.Systems" Version="0.0.51" />
                    
Directory.Packages.props
<PackageReference Include="DeltaECS.Systems" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add DeltaECS.Systems --version 0.0.51
                    
#r "nuget: DeltaECS.Systems, 0.0.51"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package DeltaECS.Systems@0.0.51
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=DeltaECS.Systems&version=0.0.51
                    
Install as a Cake Addin
#tool nuget:?package=DeltaECS.Systems&version=0.0.51
                    
Install as a Cake Tool

DeltaECS.Systems

DeltaECS.Systems runs world-bound systems in deterministic dependency batches. Systems that access different component ids can run together. Systems that write the same component can also run together when their query scopes match disjoint archetypes; structural and unknown world access forms an exclusive phase.

The package contains the runtime contract and scheduler. When a system is declared as a top-level partial class, the DeltaECS generator collects its generated API calls and supplies the Access property automatically. Typed ForEach calls that use a query stored in a readonly field keep their component accesses scoped to that query. The scheduler compares the queries' matching archetypes when it builds the schedule. Keep an explicit Access property when access is dynamic or comes from an external source. The generator treats explicit ComponentId selectors and calls outside the generated API as unknown access; declare their actual component ids and query scopes explicitly if you want the scheduler to distinguish those accesses.

Iteration calls return reusable deferred operations. Create one once and call Invoke() from each system tick so the query plan and generated route stay prepared between ticks.

using Delta.ECS;
using Delta.ECS.Systems;

using var world = new World();
world.Layouts.Register<Velocity>(new SchemaId(1));
world.Layouts.Register<Position>(new SchemaId(2));

Query movementQuery = world.WhereAll<Position, Velocity>();
Entity mover = world.Create<Position>();
world.Add(mover, new Velocity());

using var scheduler = new SystemScheduler(world);
var movement = new MovementSystem(movementQuery) { World = world };
scheduler.Add(movement);
scheduler.Tick();

public partial class MovementSystem : ISystem
{
    private readonly Query _query;
    private IOperation? _operation;

    public World World { get; init; } = null!;

    public MovementSystem(Query query) => _query = query;

    public void Tick()
    {
        _operation ??= World.ForEach(in _query,
            static (ref Position p, in Velocity v) => p.X += v.X);
        _operation.Invoke();
    }
}

public struct Position { public float X; }
public struct Velocity { public float X; }

SystemAccess uses the ComponentId values registered in the system's world. Adds, Removes, entity creation/destruction, unknown access and nested use of the DeltaECS parallel executor are exclusive to keep immediate world mutation safe. The scheduler compiles its graph when systems are added or removed and reuses the resulting batches on subsequent ticks when dependency-aware scheduling is enabled. If a system creates an archetype that changes a query's matching set, the scheduler runs the rest of that tick serially and rebuilds the optimized schedule on the next tick.

For systems with an explicit Access property, use SystemQueryAccess to declare component ids within a query scope. This lets the scheduler run two systems that write the same component together when their queries match different archetypes:

public SystemAccess Access => new(
    queryAccesses: new[]
    {
        new SystemQueryAccess(
            in _query,
            writes: stackalloc ComponentId[] { _positionId })
    },
    readsTopology: true);

Unscoped reads, writes and stamp reads remain world-wide and conflict with the same component in any query scope. Query filters over overlay tags do not separate archetypes, so they remain conservative when both queries can visit the same archetype.

Use an open generic functor in a system

Open generic functors can select their closed type with registered component ids. This is useful for reusable operations such as copying a component into a matching History<T> row. Register the generic component once, then call the generated functor overload from Tick:

using Delta.ECS;
using Delta.ECS.Systems;

using var world = new World();
ComponentId positionId = world.Layouts.Register<Position>(new SchemaId(10));
ComponentId historyId = world.Layouts.Register(typeof(History<>), positionId, new SchemaId(11));
Entity entity = world.Create(positionId, historyId);
world.GetRef<Position>(entity, positionId).X = 4f;
Query query = world.WhereAll(positionId, historyId);

using var scheduler = new SystemScheduler(world);
scheduler.Add(new CaptureHistorySystem(world, query, positionId, historyId));
scheduler.Tick();

public struct Position { public float X; }

public struct CaptureHistory<T> : IForEach
{
    public void Invoke(ref History<T> history, in T value) => history.Value = value;
}

public struct History<T> { public T Value; }

public sealed class CaptureHistorySystem : ISystem
{
    private readonly Query _query;
    private readonly ComponentId _positionId;
    private readonly SystemAccess _access;
    private IOperation? _captureOperation;

    public CaptureHistorySystem(World world, Query query, ComponentId positionId, ComponentId historyId)
    {
        World = world;
        _query = query;
        _positionId = positionId;
        _access = new SystemAccess(
            queryAccesses: new[]
            {
                new SystemQueryAccess(
                    in query,
                    reads: stackalloc ComponentId[] { positionId },
                    writes: stackalloc ComponentId[] { historyId })
            },
            readsTopology: true);
    }

    public World World { get; init; }
    public SystemAccess Access => _access;

    public void Tick()
    {
        _captureOperation ??= World.ForEach(in _query, _positionId, typeof(CaptureHistory<>));
        _captureOperation.Invoke();
    }
}

The open functor API uses the generator package and works inside scheduled systems like the typed ForEach forms. Because its ComponentId arguments select generic types at runtime, automatic access analysis cannot safely infer the selected rows. Declare SystemAccess explicitly with the corresponding IDs when the scheduler may run this system alongside independent systems; if access metadata is generated, this call is conservatively treated as unknown and runs in an exclusive phase. SystemAccess accepts explicit ReadOnlySpan<ComponentId> lists and copies them when constructed.

To run every system sequentially in registration order, disable schedule optimization:

using var scheduler = new SystemScheduler(world, optimizeSchedule: false);

Linear mode does not inspect system access metadata or create scheduler worker threads. WorkerCount is 1 in this mode.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.51 0 10/11/2026
0.0.50 0 10/11/2026
0.0.49 36 10/11/2026
0.0.48 51 10/10/2026
0.0.47 43 10/10/2026
0.0.46 47 10/9/2026
0.0.45 46 10/9/2026
0.0.44 40 10/9/2026
0.0.43 50 10/8/2026
0.0.42 47 10/8/2026
0.0.41 73 10/5/2026
0.0.40 88 10/4/2026
0.0.39 97 10/4/2026
0.0.38 92 10/3/2026
0.0.37 90 10/3/2026
0.0.36 87 10/2/2026
0.0.35 93 10/2/2026
0.0.34 85 10/2/2026
0.0.33 90 9/30/2026
0.0.32 104 9/22/2026