Branches under a game NPC line
Dialogue.AddBranch links a conversation made of your own lines into a game conversation, which is how you build a menu tree. The branch is a conversation written with DialogueAuthoring, so the rules for keys, lines, and putting it back on the Writing a conversation page apply to it. The overloads link your branch under the “anchor” line, and you give the anchor by its text or by its id. This part is experimental.
Dialogue links your branches into game conversations
You call AddBranch and keep the key it gives back, so you can call RemoveBranch with that key later.
public static class Dialogue
{
public static string AddBranch(string modId, string conversationTitle, string anchorText, ConversationDefinition branch);
public static string AddBranch(string modId, string conversationTitle, int anchorId, ConversationDefinition branch);
public static string AddBranch(string modId, string conversationTitle, string anchorText, ConversationDefinition branch, Action onPicked);
public static string AddBranch(string modId, string conversationTitle, int anchorId, ConversationDefinition branch, Action onPicked);
public static bool RemoveBranch(string modId, string key);
}
| Method | Returns | What it does |
|---|---|---|
AddBranch(modId, conversationTitle, anchorText, branch) | string | Links your branch under the anchor line, found by its text. Gives back the branch key. |
AddBranch(modId, conversationTitle, anchorId, branch) | string | Links your branch under the anchor line, found by its id. Gives back the branch key. |
AddBranch(modId, conversationTitle, anchorText, branch, onPicked) | string | The same, and runs onPicked when the player picks the branch. |
AddBranch(modId, conversationTitle, anchorId, branch, onPicked) | string | The same, and runs onPicked when the player picks the branch. |
RemoveBranch(modId, key) | bool | Removes one of your branches. false for another mod’s or an unknown key. |
Putting it together
This example adds a “Membership” menu under the line “What can I do for you?”. Its reply shows the days left and changes each visit. MembershipDaysLeft() stands for your own method that returns a whole number.
ConversationDefinition membership = new ConversationDefinition { Key = "membership" };
membership.Lines.Add(new ConversationLine { Key = "ask", Player = true, Text = "Membership", Next = new[] { "status" } });
membership.Lines.Add(new ConversationLine
{
Key = "status",
Text = "Your card is in order.",
TextCallback = () => "You have " + MembershipDaysLeft() + " days left.",
Next = new[] { "renew", "back" }
});
membership.Lines.Add(new ConversationLine { Key = "renew", Player = true, Text = "Renew for 30 days.", Script = "Variable[\"mymod_renew\"] = true" });
membership.Lines.Add(new ConversationLine { Key = "back", Player = true, Text = "Goodbye." });
string key = Dialogue.AddBranch(Mod.Id, "Shop.Greeting", "What can I do for you?", membership);
The tree is: the game’s line “What can I do for you?”, then your player choice “Membership”, then the character’s reply with the days left, then the two choices “Renew for 30 days.” and “Goodbye.”.
Things to know
- For a line that has a
TextCallback, the original written text is the callback’s markup, so use theanchorIdoverload for that line. The anchor is chosen the same way as forAddResponse, and the same refusals apply. - The branch starts at its first line. A player line gives the player a choice; a character line is played straight after the anchor. The anchor gets one link to that line, at the priority of its other player choices, and a character first line gets one tier below them by default: the game takes a character line before the player’s choices at the same tier, so the branch plays only when none of the choices above it can. Pass
priorityto place it yourself, or add aConditionto the line. - With
onPicked, your code runs when the player picks the branch. Adding the same branch again is still refused, so the firstonPickedstays. - When the conversation or the anchor is not loaded yet,
AddBranchgives back the key and links the branch as soon as both are there. You do not need to call it again. Dialogue.AddQuestTopicbuilds a topic like this for you and hangs it under the first character line of a conversation. It needs the conversation loaded when you call it, and refuses when it is not, unlikeAddBranch. Its rules are on the Dialogue authoring page.- The branch’s character lines are spoken by the anchor’s character, so their name and picture show.
branch.Speakermay benullor the name of that same character. AddBranchreturns a key, your mod id, a dot and eight characters. It comes from the conversation title, the anchor you asked for andbranch.Key, so it is the same whether the anchor was loaded at the time or not, and a second call with the same arguments is refused.- The branch’s own conversation title is your mod id, a dot and
branch.Key, so a key already in the game is refused withAlreadyExists, also when it is used under another anchor. - The framework puts the link back by itself after each scene load and each load of a save, as for responses.
RemoveBranchremoves the link and the branch’s conversation.Dialogue.RemoveAll(modId)andDialogueAuthoring.Clear(modId)also remove your branches, and keep any they cannot remove right now. You can’t remove a branch’s conversation withDialogueAuthoring.Remove.- Branches are never saved. A save made while a branch is in place loads fine without your mod.
Limits
AddBranchrefuses a branch whose speaker is not the anchor’s character. Any other name is refused.- Adding the same branch again is refused, so call
RemoveBranchfirst. A key already in the game is refused withAlreadyExists, also when it is used under another anchor. RemoveBranchreturnsfalsefor another mod’s key, an unknown key, while a save is loading or being written, when the dialogue system is not ready, and while any conversation is running. The player can reach a branch through another conversation’s link.AddBranchreturnsnulland logs the reason once when it is refused. That happens when the dialogue system is not ready, a save is loading or being written, the branch is not valid, the branch key isnarration, the anchor text is empty or only spaces, the anchor text is matched by more than one line, the anchor is not a character line or leads only to character lines, or the branch speaker is not the anchor’s character. A conversation or an anchor that is not loaded yet is not a refusal: the branch waits for it.- An empty
conversationTitlethrows anArgumentException. Anullbranchthrows anArgumentNullException, and an invalidmodIdthrows anArgumentException. - A branch cannot send the player back into the game’s conversation. A line without
Nextends the conversation, so in the example above “Goodbye.” ends the talk and the game’s menu is not shown again. Put any choice that should go back to the game’s menu in the game conversation itself, not in a branch.