DeltaNetcode 0.0.4

There is a newer version of this package available.
See the version list below for details.
dotnet add package DeltaNetcode --version 0.0.4
                    
NuGet\Install-Package DeltaNetcode -Version 0.0.4
                    
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="DeltaNetcode" Version="0.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DeltaNetcode" Version="0.0.4" />
                    
Directory.Packages.props
<PackageReference Include="DeltaNetcode" />
                    
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 DeltaNetcode --version 0.0.4
                    
#r "nuget: DeltaNetcode, 0.0.4"
                    
#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 DeltaNetcode@0.0.4
                    
#: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=DeltaNetcode&version=0.0.4
                    
Install as a Cake Addin
#tool nuget:?package=DeltaNetcode&version=0.0.4
                    
Install as a Cake Tool

DeltaNetcode

DeltaNetcode is an engine independent .NET library for sessions whose game state belongs to the application. The library provides command identity, typed registration, command validation and mutation stages, an in-memory journal, transport framing, session routing, and a fixed step rollback model. Applications provide payload encoding, simulation state serialization, authentication, transport, and game command handlers.

Command types

Commands can be non-null structs or classes. Register them explicitly, or mark them with [NetCommand] and use the generated registration list from the companion source generator. Generation supplies registrations; the application chooses when and which registrations to add. The analyzer reports an informational diagnostic for a name-derived ID and its code fix pins that ID into the attribute.

using Delta.Netcode;

[NetCommand(Id = 0x01784B1922C0A132UL, Predicted = true)]
public struct MoveCommand
{
    public int EntityId;
    public float X;
    public float Y;
}

var commands = new CommandRegistry();
foreach (ICommandRegistration registration in GeneratedCommands.Registrations)
{
    commands.Register(registration);
}

To register one generated command, pass GeneratedCommands.GetRegistration<MoveCommand>() to Register. Read its ID from the registry with commands.GetId<MoveCommand>().

An explicit ID is stable across type renames. ID 0 is reserved. The name-derived ID uses UTF-8 FNV-1a 64 over the CLR metadata full name, including namespace, nested type names, and generic arity.

Session model

The application implements ICommandPayloadHandler, ISimulation, and typed command handlers. RollbackSessionModel owns the fixed step history and calls each CommandEntry.Execute() before the matching simulation tick. Callers own the clock and invoke ISession.Tick(step) for discrete steps. CurrentStep reports the last applied step. VisitCommandType<TVisitor> dispatches a registered ID to a class or struct visitor; ReadAcceptedAfter(cursor) reads accepted replay records without exposing the journal.

SessionHost.Send<T> obtains the registered ID, session author and sequence. In SessionMode.Local and SessionMode.Server, it runs validation, scheduling and mutation before adding the final payload to the model. Server sessions broadcast the authoritative outcome. In SessionMode.Client, it sends a proposal through ITransport; commands marked with [NetCommand(Predicted = true)] are also scheduled in the local model. Accepted server outcomes replace predictions with the authoritative payload; rejected outcomes remove them and roll back the model. Other client commands wait for the server outcome before entering local simulation. SessionServer.Bind attaches an authenticated connection to a session and author. Feed transport messages to SessionServer.Receive; route outcomes through CommandProtocol.TryReadOutcome and SessionHost.ApplyOutcome.

SessionHost.Send serializes the payload immediately and retains the encoded bytes. Mutating a class command after Send does not change the queued or transmitted command.

var model = new RollbackSessionModel(simulation, initialStep: 0, historyDepth: 120);
var session = new SessionHost(
    new SessionStart(sessionId, authorId, protocolId, Step: 0, Seed: seed),
    commands,
    payloadHandler,
    model,
    new MemoryCommandJournal(),
    transport: transport,
    mode: SessionMode.Client);

session.Register<MoveCommand>(moveCommandId);
session.Register<MoveCommand>(movementValidator);
session.Register<MoveCommand>(movementMutator);
session.Register<MoveCommand>(movementExecutor);

CommandKey key = session.Send(new MoveCommand { EntityId = 7, X = 1, Y = 0 }, step: 12);
session.Tick(12);

Register validators, mutators and executors independently through ISession. The non-generic Register overload attaches a common validator. Mutators receive a transactional CommandPreparation for allocating stable IDs and seeds; only accepted commands commit its state. Accepted payload bytes are owned by the journal and reused during rollback.

CommandPreparationState seeds the ID allocator and deterministic seed stream. ReserveIds(count) allocates a contiguous range. Pass the first free ID from the loaded game state when creating the session.

SessionHost.CaptureSnapshot() asks the session model for a replayable history anchor. With RollbackSessionModel, this is the oldest retained rollback state; it can precede the model's current step so that late accepted commands remain replayable after restoration. ISessionModel.SaveReplayAnchor gives custom models the same integration point for their own history. Restore checks the session and protocol IDs, restores the model and command preparation state, and clears the old command journal.

The snapshot cursor combines the completed anchor step with the highest authoritative session order observed at capture time. The journal returns accepted records after the cursor in (Step, Order) order. This includes future commands accepted before the snapshot and commands accepted later within the retained rollback window. During network transfer, queue newly arriving outcomes until the snapshot and journal records have been applied.

SessionSnapshot snapshot = authority.CaptureSnapshot();
var snapshotBytes = new ArrayBufferWriter<byte>();
CommandProtocol.WriteSnapshot(snapshot, snapshotBytes);

// Send the snapshot frame, then replay these records on the restored client.
foreach (JournalRecord record in authority.ReadAcceptedAfter(snapshot.Cursor))
{
    var outcome = new CommandOutcome(record.Result, record.Header);
    client.ApplyOutcome(outcome, record.FinalPayload.Span);
}

Transport contract

CommandProtocol encodes proposals, cancellations, and outcomes as byte messages. It does not choose sockets, reliability, encryption, authentication, or packet batching. The application owns those choices through ITransport. The server trusts author identity only from the connection binding; the author field inside an incoming message is replaced before processing.

The built-in MemoryCommandJournal retains command outcomes and cancellation tombstones for the lifetime of the session. SessionSnapshot captures model state and command preparation state; applications choose where to persist or how to transport it. CommandProtocol frames snapshots but does not compress or fragment them.

Packages and examples

The DeltaNetcode NuGet package targets .NET Standard 2.1 and .NET 10 with its runtime, generator, analyzer and code fix. The Maze sample shows consumer usage.

Further reading

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.
  • .NETStandard 2.1

    • No dependencies.
  • net10.0

    • No dependencies.

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.5 0 10/10/2026
0.0.4 84 10/4/2026
0.0.3 86 10/4/2026
0.0.2 89 10/4/2026