Descent.RngKit.Abstractions
0.1.0
dotnet add package Descent.RngKit.Abstractions --version 0.1.0
NuGet\Install-Package Descent.RngKit.Abstractions -Version 0.1.0
<PackageReference Include="Descent.RngKit.Abstractions" Version="0.1.0" />
<PackageVersion Include="Descent.RngKit.Abstractions" Version="0.1.0" />
<PackageReference Include="Descent.RngKit.Abstractions" />
paket add Descent.RngKit.Abstractions --version 0.1.0
#r "nuget: Descent.RngKit.Abstractions, 0.1.0"
#:package Descent.RngKit.Abstractions@0.1.0
#addin nuget:?package=Descent.RngKit.Abstractions&version=0.1.0
#tool nuget:?package=Descent.RngKit.Abstractions&version=0.1.0
Descent.RngKit.Abstractions
Dependency-free contracts for Descent.RngKit — a zero-allocation, never-throw dice expression engine for high-concurrency virtual tabletops.
This package contains only interfaces and data contracts, with zero third-party dependencies. Reference it from your host application or plugin to integrate against stable seams without taking a dependency on the engine implementation.
dotnet add package Descent.RngKit.Abstractions --version 0.1.0
Pre-1.0. Below
1.0.0the public API is unstable by declaration — SemVer permits breaking changes in any0.xminor release — so pin an exact version rather than a floating range.
What's inside
The engine contract
| Type | Purpose |
|---|---|
IRngEngine |
RollAsync(formula, options, cancellationToken) — the single entry point |
RngRollOptions |
Per-roll configuration: host providers, dice chain, audit suppression, and the Items property bag for request-scoped state |
Host-supplied providers
Implement these to let expressions reach your game state. All are optional; an expression that needs a missing provider returns a clean error rather than throwing.
| Interface | Backs | Returns an error when missing |
|---|---|---|
IRandomProvider |
All randomness | — (the engine supplies a default) |
IVariableProvider |
@-prefixed variables (@str_mod, @target.armor), persistent counters |
VariableNotAvailable |
ITableProvider |
table(...), Markov matrices |
TableProviderNotMounted |
IDeckStateProvider |
draw, tutor, extract, mulligan |
DeckProviderNotMounted |
IHitLocationProvider |
hit_loc(...) |
HitLocationProviderNotMounted |
IScatterProvider |
scatter(...) |
falls back to a built-in compass |
Results and telemetry
| Type | Purpose |
|---|---|
RngAuditPacket |
The complete result: UUIDv7 audit id, total, per-node details, telemetry, and error information |
RandomNodeDetail |
One step of the roll — physical dice, display labels, subtotal, semantic flags, structured metadata |
SecurityTelemetry |
Execution time, AST depth, nodes evaluated, random numbers drawn |
RngErrorCode |
Structured error codes. Values are pinned and never reordered, so persisting them numerically is safe |
RngErrorDescriptor |
Severity, category, and retryability for an error — including codes your own ruleset defines |
RngErrorPosition |
Line, column, and offset of a syntax error, for editor squiggles |
IRngMetadata |
Marker for polymorphic per-node metadata (KeepDropMetadata, RerollMetadata, CriticalMetadata, SimulateMetadata, …). Carries [JsonPolymorphic] / [JsonDerivedType] discriminators, which have to be declared on the base type |
Serialization is a separate package
This package deliberately contains no serializer. It describes what a roll result is and takes no position on how you encode it, so a host on MessagePack, protobuf, or anything else carries no JSON dependency in its contract layer.
If you want JSON, add Descent.RngKit.Serialization,
which supplies the source-generated RngKitJsonContext. The [JsonPolymorphic] attributes above
stay here because a derived-type map has to live on the base type; they come from the inbox
System.Text.Json assembly, generate no code, and add no NuGet dependency.
Implementing IVariableProvider: complete synchronously
The methods return ValueTask<T>, but on the rolling path they should already be complete. The
evaluator is a single deep async chain, so a provider that genuinely suspends boxes a state machine in
every frame between the variable and RollAsync. Measured: about 849 bytes per variable when the
provider awaits real I/O, versus 81 when it returns a completed value.
// ✅ Completes synchronously — no state machine survives the call.
public ValueTask<int> GetVariableAsync(string key, int defaultValue = 0, CancellationToken ct = default)
=> new(_values.TryGetValue(key, out int v) ? v : defaultValue);
// ❌ Marking it `async` and awaiting the database reintroduces the boxing on every roll.
public async ValueTask<int> GetVariableAsync(string key, int defaultValue = 0, CancellationToken ct = default)
=> await _db.GetStatAsync(key, ct);
Load your data before rolling. The engine can tell you exactly what to load:
Expression.GetVariableRequirements() (in Descent.RngKit) reports every variable a parsed formula
may read, so the host can batch one query and hand the engine an immutable snapshot.
Why depend on this instead of the engine
A VTT plugin usually needs to describe a roll and read its result, not construct an engine. Taking only this package keeps your plugin free of the parser, the CSPRNG, and the caching layer — and lets the host decide which engine build and which rulesets are in play.
// Your plugin only needs the contract.
public sealed class CombatService(IRngEngine engine)
{
public async Task<int> ResolveAttackAsync(int bonus, CancellationToken ct)
{
var packet = await engine.RollAsync($"1d20+{bonus}", cancellationToken: ct);
return packet.IsSuccess ? packet.TotalValue : 0;
}
}
Stability
RngErrorCode members are append-only and their integer values are pinned by a test, so codes can be
stored in a database or sent over the wire safely. New members are added at the end; existing values
never move.
Links
- 📘 Syntax reference
- 🧩 Extending the engine
- 📦
Descent.RngKit— the engine - 📦
Descent.RngKit.Mechanics— the standard ruleset library - 📦
Descent.RngKit.Serialization— opt-inSystem.Text.Jsonsupport
MIT © DescentVTT Team
| Product | Versions 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. |
-
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 |
|---|