MelangeDB.Protocol 0.1.0

dotnet add package MelangeDB.Protocol --version 0.1.0
                    
NuGet\Install-Package MelangeDB.Protocol -Version 0.1.0
                    
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="MelangeDB.Protocol" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MelangeDB.Protocol" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="MelangeDB.Protocol" />
                    
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 MelangeDB.Protocol --version 0.1.0
                    
#r "nuget: MelangeDB.Protocol, 0.1.0"
                    
#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 MelangeDB.Protocol@0.1.0
                    
#: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=MelangeDB.Protocol&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=MelangeDB.Protocol&version=0.1.0
                    
Install as a Cake Tool

MelangeDB

A C# alternative to SpacetimeDB: a store where your application logic runs inside the transaction boundary, and connected clients subscribe to live query results instead of polling an API.

Status: alpha, unreleased. The engine, transport, auth, scheduling, event bus, paged storage, Postgres tier, clustering, and typed client bindings are implemented and tested. Nothing is at 1.0 and the public API will break between versions. It has not yet been proven against a production workload — that's phase 11, the port of a live 82-table game.

MelangeDB exists to fix three specific things:

  • Clustering isn't an afterthought. Tables declare where they live; one writer per shard, one commit log per shard. And you define what a shard means — a contiguous world partitions by space, an MMO city shards into instances, and both are first-class.
  • Your dataset isn't pinned in RAM. Stores are projections of the log with their own paging and spill-to-disk. Your working set bounds memory, not your total set.
  • Dependency injection all the way down. MelangeDB is a NuGet package inside your host process, not a server you deploy. Reducers are DI-resolved classes, so IConfiguration, ILogger<T>, and IOptionsMonitor<T> are constructor-injected like anything else — Azure App Configuration and feature flags just work.

A first look

Define a table and a reducer. The reducer is an ordinary class; its dependencies are injected.

[Table(Public = true)]
public partial struct Player
{
    [PrimaryKey] public Identity Id;
    [Index]      public int RoomId;
    public float X, Y;
}

public sealed class MovementReducers(IOptionsMonitor<WorldSettings> settings)
{
    [Reducer]
    public void Move(ReducerContext ctx, float x, float y)
    {
        var player = ctx.Db.Player.Id.Find(ctx.Caller)
            ?? throw new RejectedException("not joined");

        if (settings.CurrentValue.FrozenWorld) throw new RejectedException("world is frozen");

        ctx.Db.Player.Update(player with { X = x, Y = y });
    }
}

Register it in any .NET host. Nothing else is wired up by hand — the generator discovers both:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddMelangeDb(melange => melange
    .UseHotStore(o => o.Path = "./data/hot")            // world state machine
    .AddPostgres(builder.Configuration                  // optional relational tier
        .GetConnectionString("Melange"))
    .AddTablesFrom(typeof(Player).Assembly)
    .AddReducersFrom(typeof(Program).Assembly));

var app = builder.Build();
app.UseWebSockets();
app.MapMelangeSocket();                                 // defaults to /melange
app.Run();

A client generates typed bindings from the server's exported schema, then calls the reducer and watches the results arrive live:

await using var client = new MelangeClient(new MelangeClientOptions
{
    Uri = new Uri("wss://localhost:5001/melange"),
    Token = tokenFromYourIdP,
});
await client.ConnectAsync();

var conn = new MelangeConnection(client);
conn.Db.Player.OnInsert += p => Console.WriteLine($"{p.Id} entered");
conn.Db.Player.OnUpdate += (_, p) => Console.WriteLine($"{p.Id} moved to {p.X},{p.Y}");

await conn.Db.Player.RoomId.SubscribeAsync(7);          // SELECT * FROM player WHERE room_id = 7
var lsn = await conn.Reducers.MoveAsync(12.0f, 4.5f);

Column and reducer names are checked by the compiler, not at runtime — a renamed column is a build error. See docs/CLIENT-BINDINGS.md for how the schema manifest gets there. A runnable version of all of this lives in samples/.

What works today

Area State
Transactions, write sets, commit log, crash recovery Shipped (01)
Source generator, DI host integration, compile-time diagnostics Shipped (02)
WebSocket transport, subscriptions with live deltas, resume-not-refetch Shipped (03)
JWT identity, connect tickets, row and column policies, rate limits Shipped (04)
Scheduled reducers (timers as rows), lifecycle reducers Shipped (05)
Transactional event bus over the log as an outbox Shipped (06)
Paged hot store on FASTER, residency tiers, snapshots, compaction Shipped (07)
Postgres relational tier, ad-hoc SQL with aggregates Shipped (08)
Clustering: placement, hub/shard roles, instancing Shipped (09)
Clustering: spatial sharding, seamless handoff Shipped (10)
Typed client bindings, schema manifest, melange CLI Shipped (12)
Production validation against a live game Outstanding (11)

Deliberately out of scope: joins in subscriptions, an unreliable/UDP transport, and a sandbox for reducer code. Each is argued in docs/DESIGN.md rather than left as an omission.

Docs

  • docs/GLOSSARY.md — every noun and what it means here. Start here if the vocabulary isn't landing; it leads with the terms that sound alike and aren't.
  • docs/DESIGN.md — the architecture, the trade-offs it accepts, and the open questions.
  • docs/CONFIGURATION.md — every setting MelangeDB exposes. New config items are added here in the same change that introduces them.
  • docs/CLUSTERING.md — the four table placements, hub/shard node roles, and why you define the sharding function rather than MelangeDB.
  • docs/OBSERVABILITY.md — the span and metric register. OpenTelemetry from the first commit, with no OpenTelemetry dependency in core.
  • docs/THREAT-MODEL.md — what a server can enforce against an untrusted client, and what it deliberately doesn't. (To report a vulnerability, see SECURITY.md.)
  • docs/CLIENT-BINDINGS.md — the typed-binding surface and how generation works.
  • docs/LOAD-TESTING.md — the load rig, what it measures, and the recorded numbers.
  • docs/ROADMAP.md — what shipped in each phase, the decisions each one settled, and what's left.
  • docs/REFERENCE-WORKLOAD.md — the design audited against a live 82-table SpacetimeDB game, as a reality check on scope.
  • docs/RELEASING.md — how the packages are versioned and published.

Layout

Project Purpose
src/MelangeDB.Abstractions Attributes, identities, core interfaces. Dependency-free.
src/MelangeDB.Core Schema model, write sets, transactions, commit log, dispatcher, appliers.
src/MelangeDB.Protocol The wire format: frames, MessagePack codecs, reducer argument encoding.
src/MelangeDB.Storage.Faster IHotStore over a hybrid log with spill-to-disk.
src/MelangeDB.Storage.Postgres Optional relational projection.
src/MelangeDB.Server WebSocket transport, subscription engine, auth.
src/MelangeDB.Client C# client.
src/MelangeDB.Cluster Hub and shard node roles, placement routing, handoff.
src/MelangeDB.CodeGen Roslyn generator: registrations, serializers, typed clients.
src/MelangeDB.OpenTelemetry Optional: registers MelangeDB's signal names with OpenTelemetry.
src/MelangeDB.Cli The melange dotnet tool — schema export and tooling.
tools/MelangeDB.LoadTest The load rig behind the recorded performance numbers.
samples/ A worker-service host and a console client that talk to each other.

Building

Requires the .NET 10 SDK.

dotnet build
dotnet test

The Postgres and cluster suites use Testcontainers and need a working Docker daemon. See CONTRIBUTING.md for the full test story, including which suites run only locally and why.

Contributing

Issues and pull requests are welcome — see CONTRIBUTING.md for the build, the test bar, and the documentation conventions this repo holds itself to. Participation is governed by the Code of Conduct.

License

MIT © Tyler Loy

Product Compatible and additional computed target framework versions.
.NET 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on MelangeDB.Protocol:

Package Downloads
MelangeDB.Server

WebSocket transport, subscription engine, and identity/auth integration. Hosted inside the developer's own ASP.NET Core app.

MelangeDB.Cluster

Clustering: hub and shard node roles, per-shard engines and commit logs, the membership store, the gateway, explicit handoff, and the distributed event transport.

MelangeDB.Client

C# client: connects, calls reducers, and maintains subscribed row sets locally.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 116 8/3/2026