EternalGarden.Rzeka.Dev 1.2.0

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

💦📜🏹 rzeka

.NET CI codecov NuGet

🌟📜 Important: This README is a glimpse into rzeka, not the manual. Full documentation in Wiki – API reference, threading model, Eris, attributes & error handling.

A reactive event bus for C# that tracks causality.

rzeka ("river" in Polish) is a single-threaded event bus built on Rx.NET. Components yeet typed events into the river and act on the events flowing through it, without holding references to each other.

What makes rzeka different from a typical event bus is causality tracking: every event carries a record of the events that caused it.

You can ask any event – o little rabbit! where did you come from? – and get its full casual chain – what fox's chasing glare or carrots allure brought you here?

Thanks to Eris (rzeka's built-in debugger) you can read the entire story of what's happening in your system – real-time, in a browser, while your game runs (both in a game engine and in a build!).

https://github.com/user-attachments/assets/de5e608b-5123-47dd-99c4-996be5ff5259

⚗️ rzeka is single-threaded by design. This constraint guarantees consistent circumstance tracking. Async operations are handled within defined boundaries (see Shuttle).

Status: rzeka was originally built for sanctuary, a 3D journaling software shipped on Unity. It is currently being refactored alongside sanctuary's port to Godot. The core API is stable. Eris UI and Godot integration are evolving.

🪞 The metaphor

rzeka uses a river, textile and magic themed naming system: events are Matter, transformations are Spells, and a spell's ingredient-readiness is its Mana. The spell-defining methods (Strand, Loom, Shuttle, Weave, Pluck) follow textile-production vocabulary. Eris, the debugger, borrows her name from the Greek goddess of discord.

The metaphor is consistent, and once you let it work its magic the API becomes self-describing. The full vocabulary lives in the Grimoire.

alternate text is missing from this package README image

A page from Witches by Daisuke Igarashi

💾 Installation

rzeka targets net8.0 and depends only on System.Reactive.

dotnet add package EternalGarden.Rzeka

For the optional browser-based Eris debugger (EternalGarden.Rzeka.Dev) and Godot's transitive-dependency quirks, go to the Installation page.

🌱 A taste

Summon one river at startup, then let typed events flow into it and react to them - no component holds a reference to any other. Here is a complete vertical slice: a witch is hexed, her ward weakens, its glow answers on screen.

using Rzeka;

// Events are Matter. Extend Matter to shape your own.
class HexCast : Matter
{
    public int Potency { get; }
    public HexCast(int potency) => Potency = potency;
}

// [HasState] matter remembers its last value and replays it to new subscribers.
[HasState]
class WardState : Matter
{
    public int Strength { get; }
    public WardState(int strength) => Strength = strength;
}

// Summon the river once, share its IRzeka reference with the systems that need it.
// mainThread is an IScheduler for your engine's main thread - see Getting Started.
IRzeka rzeka = new Spring().Create("Styx", mainThread);

// Collect your spells so you can let them all go together later.
CollectibleDisposable Q = new();

// Seed the ward at full strength.
rzeka.Pluck(this, new WardState(100));

// Strand: let every hex the enemy hurls flow into the river.
// OnHexCastAsObservable() is something using Observable.FromEvent() or similar
Q += rzeka.Strand(
    this,
    enemy.OnHexCastAsObservable().Select(hex => new HexCast(hex.Potency))
);

// Loom: weave each hex against the standing ward, conjuring its next state.
// The HexCast matter is the trigger - WithLatestFromMatter fires off the hexes, not the ward updates.
Q += rzeka.Loom<WardState, HexCast, WardState>(
    this,
    (ward, hexes) => hexes.WithLatestFromMatter(ward)
        .Select(t => new WardState(t.Item2.Strength - t.Item1.Potency))
);

// Weave: the path ending spell - read the ward, let its glow update in game.
Q += rzeka.Weave<WardState>(
    this,
    ward => ward.Subscribe(w => wardGlow.SetIntensity(w.Strength))
);

Every WardState here automatically remembers the HexCast that diminished it as a circumstance, so Eris can later show the whole causal chain. That automatic causality tracking is the core functionality of rzeka - the API and Matter pages cover it fully.

alternate text is missing from this package README image

📜🧚🏻‍♀️ rzeka code will make the characteristic waterfall 2D structures that go deep into your indentation while remaining very clear and readable. This depth might not be for everyone though. Personally I really prefer that to a 1D top-down wall of code-text, maybe you might like it too! Screenshot info: nvim, theme Aquavium, semitransparent background, CSharpier formatter.

📜🌱 Want a runnable project instead? See little-river, a tiny example Godot game built on rzeka.

🏹 Eris, the debugger

rzeka ships with a browser-based debugger that connects to your running game over WebSocket and shows matter flow and messages in real time – you don't need to build your own in-game UI! Eris records internally even in release builds (a feature to dump crash logs is underway). The WebSocket server is added only in dev builds via the EternalGarden.Rzeka.Dev package so you can easily strip it from your release builds.

Setup, the live UI, the demo, and structured logging via Whisper are all covered on the Eris page.

🔖 Crash reporting

When a spell fails in a player's game, the optional EternalGarden.Rzeka.Reporting package can send its causal story to a server: which matter led to the failure, which spells shaped it and when. Structure only, without the values inside your matter, and nothing is sent until the player agrees. The package just POSTs JSON; a reference backend on Azure lives in rzeka-reporting-azure.

Setup, consent, what a report contains and the privacy model are on the Crash Reporting page.

📜 License

See LICENSE.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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 was computed.  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

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
1.2.0 33 10/2/2026
1.1.3 112 8/16/2026
1.1.2 105 8/12/2026
1.1.1 122 6/12/2026
1.1.0 99 5/26/2026
1.0.2 104 5/17/2026
1.0.1 109 5/14/2026
1.0.0 106 5/14/2026