SetNet.Dialogue
1.2.0
dotnet add package SetNet.Dialogue --version 1.2.0
NuGet\Install-Package SetNet.Dialogue -Version 1.2.0
<PackageReference Include="SetNet.Dialogue" Version="1.2.0" />
<PackageVersion Include="SetNet.Dialogue" Version="1.2.0" />
<PackageReference Include="SetNet.Dialogue" />
paket add SetNet.Dialogue --version 1.2.0
#r "nuget: SetNet.Dialogue, 1.2.0"
#:package SetNet.Dialogue@1.2.0
#addin nuget:?package=SetNet.Dialogue&version=1.2.0
#tool nuget:?package=SetNet.Dialogue&version=1.2.0
<p align="center"> <img src="https://raw.githubusercontent.com/Povstalez/SetNet/master/assets/icon.png" alt="SetNet" width="96"> </p>
SetNet.Dialogue
Server-authoritative branching dialogue for SetNet — conditional choices, side-effects, walked entirely on the server.
Build a DialogueTree of nodes, each with the NPC's line and a set of choices; a choice can carry an optional guard that hides it and an optional side-effect that fires when it's taken (grant a quest, set a flag). The client sees only the visible choices and picks one by index — all branching, guarding and state live server-side, so the client can't skip to a node it hasn't earned. Pairs naturally with SetNet.NPC capability hand-off ("dialogue:<id>"). Added by composition — no base class.
Install
dotnet add package SetNet
dotnet add package SetNet.Dialogue
Usage
Call DialogueRuntime.Enable() once at startup so the channel service is discovered.
// server — define a tree, then register it
DialogueRuntime.Enable();
var tree = DialogueTree.Create()
.Node("start", "Well met, traveller. What brings you here?",
new DialogueChoice("I seek the old ruins.", next: "ruins"),
new DialogueChoice("I'll take that quest.", next: "quest",
condition: ctx => !HasQuest(ctx.PlayerKey), // hidden once accepted
onChosen: ctx => GiveQuest(ctx.PlayerKey))) // side-effect
.Node("ruins", "Follow the river north.") // no choices → ends here
.Node("quest", "Slay the wolves and return.")
.Build();
server.UseDialogue().Define("elder", tree);
// client — walk it
DialogueRuntime.Enable();
var dialogue = client.UseDialogue();
DialogueNodeView node = await dialogue.StartAsync("elder");
while (!node.IsEnd)
{
Render(node.Text, node.Choices); // each choice has .Index and .Text
node = await dialogue.ChooseAsync(node.Choices[pick].Index);
}
API
Tree: DialogueTree.Create() → Builder — Node(id, text, params DialogueChoice[]), Start(id), Build().
DialogueChoice(text, next, condition?, onChosen?) where condition/onChosen take a DialogueContext (PlayerKey, Services, Blackboard).
Server: server.UseDialogue(DialogueOptions?) → DialogueServer — Define(dialogueId, DialogueTree).
Client: client.UseDialogue() → DialogueClient — StartAsync(dialogueId) / ChooseAsync(choiceIndex) → DialogueNodeView (NodeId, Text, IsEnd, Choices).
Options: DialogueOptions.PlayerKey, DialogueOptions.Services. DialogueRuntime.Enable() — one-time bootstrap.
Notes
- Rides the unified SetNet.Protocol messaging layer on the
Channels.Dialoguechannel (all modules share one envelope wire type,65447) — no per-module wire ids to reserve. The control protocol is hand-framedbyte[]; a failed op surfaces asDialogueException. - Server-authoritative. The server tracks each player's current node;
ChooseAsyncis validated against the visible choices at that node, so guards can't be bypassed and a client can't jump to an arbitrary node. - Guards run per-view. A choice's
Conditionis evaluated every time its node is shown — resolve app state (quests, inventory, flags) fromDialogueContext.Services(anIServiceProvideryou set viaDialogueOptions.Services), and stash per-conversation scratch inBlackboard. - Ends cleanly. A node with no choices (or a chosen choice whose
Nextis null) ends the conversation; the finalDialogueNodeViewhasIsEnd == true. A disconnect clears the active conversation. - Pairs with NPC. Have a
SetNet.NPCbehaviour return capability"dialogue:elder", then the client callsStartAsync("elder")— the NPC decides when to talk, this module decides what is said.
Documentation & source
- 🐙 https://github.com/Povstalez/SetNet — full catalog in docs/MODULES.md
License
MIT
| Product | Versions 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 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. |
| .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. |
-
.NETStandard 2.1
- SetNet (>= 1.2.0)
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 | 82 | 8/5/2026 |