CommandGraph
The node-based visual scripting system that drives NPC and event behaviour — dialogs,
branches, item/money grants, warps, battles, quests and more. Each interactable actor
owns an ActorCommandGraph; the graph is authored in the editor and executed as a
coroutine at runtime.
A graph is an asset. Nothing in this path is compiled, which is why it works the same in the DLL tiers where you cannot open the source.
Namespace: OpenMon.MCE.Actors.CommandGraph
You normally build command graphs in the visual editor (see the
CommandGraph guide), not from C#. The runtime
surface below is what you touch when you extend the system with a custom node or
run a graph programmatically. The node types themselves (ShowDialog, GivePlayerItem,
TeleportPlayer, …) are authored assets — their fields are inspector-serialized, not a
code-facing API.
ActorCommandGraph
The container for one actor's graph.
[Serializable]
public class ActorCommandGraph
{
public bool IsRunning { get; }
[SerializeReference] public CommandNode RootNode;
[SerializeReference] public List<CommandNode> Nodes;
public bool IsGraphEmpty { get; }
public IEnumerator Run(CommandParameterData parameterData,
Action<bool> onLoopRunningUpdatedCallback = null);
public CommandNode CreateNode(Type type, Vector2 position = default);
public void DeleteNode(CommandNode node);
public void ConnectNodes(CommandNode parent, CommandNode child, int parentIndex);
public void RemoveConnection(CommandNode parent, CommandNode child, int parentIndex);
public List<CommandNode> GetChildren(CommandNode node);
}
IsRunning
Whether this graph is currently executing.
Type: bool (read-only)
RootNode
The entry CommandNode (a RootNode) execution starts from. Serialized by reference
so polymorphic node types round-trip.
Type: CommandNode
Nodes
Every node in the graph, including nodes not reachable from RootNode (kept so the
editor can persist orphaned/disconnected nodes).
Type: List<CommandNode>
IsGraphEmpty
true when there is no root node or the root has no children.
Type: bool (read-only)
Run(CommandParameterData parameterData, Action<bool> onLoopRunningUpdatedCallback = null)
Execute the graph. Sets IsRunning, then runs RootNode.RunCommandAndContinue,
threading a CommandParameterData context through every node.
Returns: IEnumerator — yield it from a coroutine.
CreateNode(Type type, Vector2 position = default) / DeleteNode / ConnectNodes / RemoveConnection
Editor-facing graph mutation: instantiate a node of a given CommandNode subclass,
remove it, and wire/unwire parent→child connections by output-port index.
CommandNode
The abstract base every node type derives from.
[Serializable]
public abstract class CommandNode : MonsterDatabaseData<CommandNode>
{
public bool IsRunning { get; }
public string name;
public string GUID;
public Vector2 Position;
public Action OnPortsUpdated;
public virtual IEnumerator RunCommandAndContinue(CommandParameterData parameterData);
protected abstract IEnumerator Run(CommandParameterData parameterData,
Action<CommandParameterData> callback);
public abstract List<string> GetInputPorts();
public abstract List<string> GetOutputPorts();
public abstract void AddChild(CommandNode child, int index);
public abstract void RemoveChild(CommandNode child, int index);
public abstract List<CommandNode> GetChildren();
public abstract List<CommandNode> GetIndexedChildren();
}
RunCommandAndContinue(CommandParameterData parameterData)
Runs this node (via the abstract Run) and then continues to its children. Handles
loop gating when the graph runs on a loop.
Run(CommandParameterData parameterData, Action<CommandParameterData> callback)
protected abstract — the actual work of a node. Override this in a custom node.
Call callback with the (possibly modified) parameter data when done.
GetInputPorts() / GetOutputPorts()
The named input/output ports the node exposes to the editor graph. A linear node has a single unnamed port on each side; a branch node exposes one output per branch.
Returns: List<string>.
SingleExecutionPathCommandNode
Most nodes derive from SingleExecutionPathCommandNode, a CommandNode with exactly
one output port (NextCommand). Branch nodes (If…, Switch…, While…) instead
expose multiple output ports.
public abstract class SingleExecutionPathCommandNode : CommandNode
{
public CommandNode NextCommand;
// GetOutputPorts() => one unnamed port; AddChild sets NextCommand.
}