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 compiled editions (Starter, Indie and Pro), 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.
}
CommandParameterData
The execution context threaded through every node during a run — the surface a custom node reads from and writes to.
public class CommandParameterData
{
public ActorCommandGraph Graph;
public GameObject Owner;
public Actor Actor;
public MCECharacterController.Direction PlayerDirection;
public PlayerCharacter PlayerCharacter;
public GlobalGameData GlobalGameData;
public MCESettings MCESettings;
public MonsterDatabaseInstance MonsterDatabase;
public IBattleLauncher BattleLauncher;
public ILocalizer Localizer;
public IConfigurationManager ConfigurationManager;
public IInputManager InputManager;
public PlayerTeleporter Teleporter;
public SavegameManager SavegameManager;
public MapSceneLauncher MapSceneLauncher;
public TimeManager TimeManager;
public QuestManager QuestManager;
public TradeManager TradeManager;
public bool UsingMove;
public MonsterInstance MoveUser;
public Move Move;
public bool IsRunningOnLoop;
public ICommandParameter[] ExtraParams;
public Action<CommandCallbackParams> Callback;
}
Built-in node categories
Nodes are grouped by folder under Actors/CommandGraph/. Representative types:
| Category | Example nodes |
|---|---|
| Dialogs | ShowDialog, ShowChoiceDialog, ShowSignDialog, NextDialog |
| Items | GivePlayerItem, GivePlayerMoney, IfPlayerHasItem, ChooseItemDialog |
| Monsters | GiveMonsters, HealPlayerRoster, ChooseMonsterDialog, ChangeMonsterNickname |
| Battles | SingleWildFight, SingleTrainerFight, DoubleWildFight, StartTowerRun |
| Badges | GiveBadge, IfPlayerHasBadge |
| Dex | GiveDex, RegisterMonsterAsSeen, IfDexIsComplete |
| Quests | StartQuest, CompleteQuest, ProgressQuestObjective, IfCompletedQuest |
| Variables | SetBoolVariable, SetIntVariable, IfBool, IfCondition, WhileBool |
| Utils | TeleportPlayer, WaitTime, AutoSaveIfEnabled, SwitchTimeOfDay |
| Animations | Move, Look, LookAtPlayer, WalkToPlayer, FadeScreenToBlack |
| Shops / Trade | BuyInShop, SellInShop, TradeSelectedMonster |
Writing a custom node
using System;
using System.Collections;
using System.Collections.Generic;
using OpenMon.MCE.Actors.CommandGraph;
namespace MyGame.Events
{
[Serializable]
public class LogStepsTaken : SingleExecutionPathCommandNode
{
protected override IEnumerator Run(CommandParameterData parameterData,
Action<CommandParameterData> callback)
{
// Read from the shared context threaded through the graph.
uint steps = parameterData.GlobalGameData.StepsTaken;
UnityEngine.Debug.Log($"Player has taken {steps} steps.");
callback(parameterData);
yield break;
}
}
}