Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Forge/Statescript/Node.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,15 @@ internal virtual void Update(double deltaTime, GraphContext graphContext)
/// </summary>
/// <typeparam name="T">The type of port to create.</typeparam>
/// <param name="index">The index of the port.</param>
/// <param name="label">The editor-facing label for the port.</param>
/// <returns>The created port.</returns>
protected static T CreatePort<T>(byte index)
protected static T CreatePort<T>(byte index, string label = "")
where T : Port, new()
{
return new T
{
Index = index,
Label = label,
};
Comment thread
lextatic marked this conversation as resolved.
}

Expand Down
4 changes: 2 additions & 2 deletions Forge/Statescript/Nodes/ActionNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ internal override IEnumerable<int> GetReachableOutputPorts(byte inputPortIndex)
/// <inheritdoc/>
protected override void DefinePorts(List<InputPort> inputPorts, List<OutputPort> outputPorts)
{
inputPorts.Add(CreatePort<InputPort>(InputPort));
outputPorts.Add(CreatePort<EventPort>(OutputPort));
inputPorts.Add(CreatePort<InputPort>(InputPort, "Execute"));
outputPorts.Add(CreatePort<EventPort>(OutputPort, "Done"));
Comment thread
lextatic marked this conversation as resolved.
Outdated
}

/// <inheritdoc/>
Expand Down
6 changes: 3 additions & 3 deletions Forge/Statescript/Nodes/ConditionNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ internal override IEnumerable<int> GetReachableOutputPorts(byte inputPortIndex)
/// <inheritdoc/>
protected override void DefinePorts(List<InputPort> inputPorts, List<OutputPort> outputPorts)
{
inputPorts.Add(CreatePort<InputPort>(InputPort));
outputPorts.Add(CreatePort<EventPort>(TruePort));
outputPorts.Add(CreatePort<EventPort>(FalsePort));
inputPorts.Add(CreatePort<InputPort>(InputPort, "Condition"));
Comment thread
lextatic marked this conversation as resolved.
Outdated
outputPorts.Add(CreatePort<EventPort>(TruePort, "True"));
outputPorts.Add(CreatePort<EventPort>(FalsePort, "False"));
}

/// <inheritdoc/>
Expand Down
2 changes: 1 addition & 1 deletion Forge/Statescript/Nodes/EntryNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ internal override IEnumerable<int> GetReachableOutputPorts(byte inputPortIndex)
/// <inheritdoc/>
protected override void DefinePorts(List<InputPort> inputPorts, List<OutputPort> outputPorts)
{
outputPorts.Add(CreatePort<SubgraphPort>(OutputPort));
outputPorts.Add(CreatePort<SubgraphPort>(OutputPort, "Start"));
Comment thread
lextatic marked this conversation as resolved.
Outdated
}

/// <inheritdoc/>
Expand Down
2 changes: 1 addition & 1 deletion Forge/Statescript/Nodes/ExitNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal override IEnumerable<int> GetReachableOutputPorts(byte inputPortIndex)
/// <inheritdoc/>
protected override void DefinePorts(List<InputPort> inputPorts, List<OutputPort> outputPorts)
{
inputPorts.Add(CreatePort<InputPort>(InputPort));
inputPorts.Add(CreatePort<InputPort>(InputPort, "Stop"));
Comment thread
lextatic marked this conversation as resolved.
Outdated
}

/// <inheritdoc/>
Expand Down
2 changes: 1 addition & 1 deletion Forge/Statescript/Nodes/State/EffectNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class EffectNode : StateNode<EffectNodeContext>
protected override void DefinePorts(List<InputPort> inputPorts, List<OutputPort> outputPorts)
{
base.DefinePorts(inputPorts, outputPorts);
outputPorts.Add(CreatePort<EventPort>(OnEffectEndPort));
outputPorts.Add(CreatePort<EventPort>(OnEffectEndPort, "OnEffectEnd"));
}

/// <inheritdoc/>
Expand Down
2 changes: 1 addition & 1 deletion Forge/Statescript/Nodes/State/TimerNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class TimerNode : StateNode<TimerNodeContext>
protected override void DefinePorts(List<InputPort> inputPorts, List<OutputPort> outputPorts)
{
base.DefinePorts(inputPorts, outputPorts);
outputPorts.Add(CreatePort<EventPort>(OnTimerEndPort));
outputPorts.Add(CreatePort<EventPort>(OnTimerEndPort, "OnTimerEnd"));
}

/// <inheritdoc/>
Expand Down
12 changes: 6 additions & 6 deletions Forge/Statescript/Nodes/StateNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,12 @@ protected virtual void OnUpdate(double deltaTime, GraphContext graphContext)
/// <inheritdoc/>
protected override void DefinePorts(List<InputPort> inputPorts, List<OutputPort> outputPorts)
{
inputPorts.Add(CreatePort<InputPort>(InputPort));
inputPorts.Add(CreatePort<InputPort>(AbortPort));
outputPorts.Add(CreatePort<EventPort>(OnActivatePort));
outputPorts.Add(CreatePort<EventPort>(OnDeactivatePort));
outputPorts.Add(CreatePort<EventPort>(OnAbortPort));
outputPorts.Add(CreatePort<SubgraphPort>(SubgraphPort));
inputPorts.Add(CreatePort<InputPort>(InputPort, "Begin"));
Comment thread
lextatic marked this conversation as resolved.
Outdated
inputPorts.Add(CreatePort<InputPort>(AbortPort, "Abort"));
outputPorts.Add(CreatePort<EventPort>(OnActivatePort, "OnActivate"));
outputPorts.Add(CreatePort<EventPort>(OnDeactivatePort, "OnDeactivate"));
outputPorts.Add(CreatePort<EventPort>(OnAbortPort, "OnAbort"));
outputPorts.Add(CreatePort<SubgraphPort>(SubgraphPort, "Subgraph"));
}

/// <inheritdoc/>
Expand Down
5 changes: 5 additions & 0 deletions Forge/Statescript/Port.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ public abstract class Port
/// Gets or sets the index of this port.
/// </summary>
public byte Index { get; set; }

/// <summary>
/// Gets or sets the editor-facing label for this port.
/// </summary>
public string Label { get; set; } = string.Empty;
}
6 changes: 6 additions & 0 deletions docs/statescript/nodes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ Carries **both** regular messages and disable-subgraph signals. Used by the Entr

Receives messages from connected output ports and notifies the owning node.

## Port Labels

Port labels are defined by the runtime node, not by editor-specific discovery code. Built-in nodes already provide labels for their standard ports automatically.

If a custom node adds extra flow ports, create them with `CreatePort<T>(index, "Label")` so editor integrations can surface the intended port name consistently without plugin-specific hard-coding.

## Graph Construction

Nodes are added to a graph with `AddNode()` and wired together with `AddConnection()`:
Expand Down
12 changes: 12 additions & 0 deletions docs/statescript/nodes/state/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ public class WaitForTagNode : StateNode<WaitForTagNodeContext>

Use `DeactivateNode(graphContext)` for simple deactivation, or `DeactivateNodeAndEmitMessage(graphContext, portIds)` to emit custom event port messages before deactivation.

If your state node defines additional event or subgraph ports, override `DefinePorts`, call `base.DefinePorts(...)`, and create each custom port with an explicit label:

```csharp
protected override void DefinePorts(List<InputPort> inputPorts, List<OutputPort> outputPorts)
{
base.DefinePorts(inputPorts, outputPorts);
outputPorts.Add(CreatePort<EventPort>(OnFinishedPort, "OnFinished"));
}
```

That label becomes the canonical port name surfaced by editor integrations such as Forge for Godot.

## Built-in State Nodes

| Node | Description |
Expand Down
2 changes: 2 additions & 0 deletions docs/statescript/subgraphs.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ Entry → TimerA(10s)

Custom state nodes can define additional Subgraph ports and control them independently while the node remains active. This is one of the most powerful patterns in Statescript.

When defining extra Event or Subgraph ports for these nodes, assign explicit labels with `CreatePort<T>(index, "Label")`. Editor integrations use those runtime labels when rendering custom ports.

For example, a combat stance node could have two Subgraph ports, one for each stance. While active, the node switches between stances by disabling one subgraph and activating the other:

```
Expand Down
2 changes: 2 additions & 0 deletions docs/statescript/templates/action-node-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
|-------|------|------|-------------|
| 0 | Output | Event | Emits after execution. |

> Port names should match the labels defined in code via `CreatePort<T>(index, "Label")`.

## Parameters

**Input Properties:**
Expand Down
2 changes: 2 additions & 0 deletions docs/statescript/templates/condition-node-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
| 0 | True | Event | Emits if the test returns `true`. |
| 1 | False | Event | Emits if the test returns `false`. |

> Port names should match the labels defined in code via `CreatePort<T>(index, "Label")`.

## Parameters

**Input Properties:**
Expand Down
1 change: 1 addition & 0 deletions docs/statescript/templates/state-node-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
| {4+} | {Custom} | {Event or Subgraph} | {Description of additional ports.} |

> Remove the custom port rows if the node defines no additional ports beyond the standard four.
> Port names should match the labels defined in code via `CreatePort<T>(index, "Label")`.

## Parameters

Expand Down
Loading