# Action Graph Editor

> The Action Graph editor shows a character's moves as cards: wire them, fold in another graph, copy a transition onto many moves, and watch the graph run in play.

Markdown version of https://rigbak.com/docs/universal-player-combat/action-graph-editor, a page of the Universal Player Combat documentation. Link that page when citing it.

## Add a third hit and watch it run (3 minutes)

1. **Open the graph**

   This quick start builds on `AG_MyFirstGraph` from the [Action Graph](https://rigbak.com/docs/universal-player-combat/action-graph) quick start, still on the demo's fists.

   Double-click **AG_MyFirstGraph** in the Content Browser to open it.
2. **Add a card**

   Right-click the empty canvas, **Add Action Node**. In the Details panel, set its **Node Name** to `Light 3` and its **Montage** to `AM_Attack_Light`.
3. **Wire it**

   Drag from **Light 2**'s right edge to **Light 3**'s left edge. A transition router appears on the wire with one entry on **Input Pressed**; pick `UPC.Input.LightAttack` on its row.

   Graph nodes:

   - **ROOT**
   - **Light 1** (montage AM_Attack_Light)
   - **Light 2** (montage AM_Attack_Light)
   - **Light 3** (montage AM_Attack_Light)

   Connections:

   - ROOT to Light 1, through UPC.Input.LightAttack (pressed)
   - Light 1 to Light 2, through UPC.Input.LightAttack (pressed)
   - Light 2 to Light 3, through UPC.Input.LightAttack (pressed)

   *AG_MyFirstGraph with Light 3 added: a third light attack press, after Light 2, plays it.*
4. **Press Play and watch**

   Keep the graph open, play `LVL_UPC_Demo`, click, then click again as each swing's window opens. The editor follows the first character running the graph, and each card turns green while it plays.

---

## Reading a card

Graph nodes:

- **ROOT**
- **Light 1** (montage AM_Attack_Light)
- **Recovery** (custom payload; Delay Seconds 0.4)
- **None** (nothing to run)
- **AG_UPC_Shield** (sub graph; Req: UPC.Equipment.Shielded)
- **UPC.Input.Guard (Interrupt)** (alias; All actions except Root)
- **To Root** (ends the action and returns to Root)
- **Light 2** (montage AM_Attack_Light; has a warning)

*The card kinds. Top row: Root, a montage action, an action running another payload, an action with nothing to run. Bottom: a sub graph (another graph folded in), an alias (one transition copied onto many actions), a To Root card (back to idle), and an action with a warning on it.*

| Outline | The action |
| --- | --- |
| Light blue | Plays a montage. |
| Violet | Runs another payload, such as Delay or Hold. |
| Gray | Has no payload, so it ends the moment it starts. |
| Amber, with a warning badge | Has a problem; hover the badge to read it. |
| Green | Is the move the watched character plays. |

A montage card draws its montage's timeline: a green **Chain** bar per UPC Action Window, an orange **Hit** bar per melee trace window, and a yellow line at **Cancel Window Start** when the node **Can be Cancelled**. Some payload settings, such as **Montage**, show and edit on the card. **ROOT** has no settings or input pin and cannot be deleted or duplicated.

---

## Wiring moves together

A drag from one card to another adds a **transition router**; a second drag from the same card joins it. Each router row is one transition, with its input tag picked on the row and its own output pin to retarget it; Action Completed rows read `Auto`, Action Failed rows `Failed`. [Action Graph](https://rigbak.com/docs/universal-player-combat/action-graph#the-transitions-settings) covers each entry's settings.

Graph nodes:

- **Light 1** (montage AM_Attack_Light)
- **Light 2** (montage AM_Attack_Light)
- **Heavy** (montage AM_Heavy)
- **Out Of Breath** (montage AM_Tired)

Connections:

- Light 1 to Light 2, through UPC.Input.LightAttack (pressed)
- Light 1 to Heavy, through UPC.Input.HeavyAttack (pressed)
- Light 1 to Out Of Breath, through Failed

*One router, three entries. Each row is one transition with an output pin of its own: green for an input, gray for Action Completed, red for Action Failed.*

The canvas menu adds each card kind: **Add Action Node**, **Add Transition Router** (for wiring by hand), **Add Sub Graph**, **Add Alias**, **Add Return To Root** (a **To Root** card, which ends a move to idle) and **Add Reroute Node**. A wire dropped on empty canvas opens the menu, and the card you pick arrives wired.

### Tidy wires with reroute dots

Double-click a wire, or pick **Add Reroute Node**, and drag the dot where the wire should run. Deleting a dot, or Alt-clicking it, joins its wire again.

---

## Fold one graph into another

A **sub graph** card folds a whole graph in, such as a shield's guard moves, shared by each weapon drawn beside the shield.

1. Right-click the canvas, **Add Sub Graph**, and set **Sub Graph Asset**, or drop an Action Graph on the canvas.
2. Wire into its **In** pin each action of this graph the folded moves may start from (ROOT for moves from idle). The transitions leaving the source graph's ROOT are copied onto those actions: with Light 1 wired in, the guard press that leads from the shield graph's ROOT to Guard Hold also leads there from Light 1.
3. Optionally wire its **Return** pin to an action of this graph. It catches only the source moves that end on a **To Root** card, such as a block's release; they lead to that action. A source move that ends with no link at all returns to this graph's ROOT.

In the picture: Guard during Light 1 plays the imported Guard Hold; releasing arrives at Recovery, the action on the Return pin.

Graph nodes:

- **ROOT**
- **Light 1** (montage AM_Attack_Light)
- **AG_UPC_Shield** (sub graph; Req: UPC.Equipment.Shielded)
- **Recovery** (custom payload)

Connections:

- ROOT to AG_UPC_Shield
- Light 1 to AG_UPC_Shield
- AG_UPC_Shield to Recovery

*ROOT and Light 1 wired into In, Return wired to Recovery. The shield graph's moves start from idle and from Light 1 while the drawn shield applies its tag.*

**Details panel: Sub Graph** (instanced object, in AG_MySword)

**Category: Sub Graph**

| Property | Value |
| --- | --- |
| Sub Graph Asset | AG_UPC_Shield |
| Entry Required Tags | UPC.Equipment.Shielded |
| Entry Blocked Tags | no tags |
| Priority Bias | 0 |

*Entry Required Tags and Entry Blocked Tags join every entry transition the sub graph adds; Priority Bias adds to their priority.*

| Setting | Does |
| --- | --- |
| **Entry Required Tags** | Tags the character must carry for the entries to fire, such as the drawn shield's tag. A move already playing keeps going when the tag goes. |
| **Entry Blocked Tags** | Tags that deny the entries while carried. |
| **Priority Bias** | Added to each entry's priority. On a tie this graph's own transition wins; raise it to let the sub graph win. |

> **Warning**
>
> The fold is a copy taken at compile. After its source changes, the card reads `STALE: source changed, recompile` until this graph compiles again (**Compile**, a save or Play). Compile and save a new source in its own editor first, or it brings nothing.

---

## Copy one transition onto many moves

An **alias** gives one move many ways in, such as a parry out of every step of a combo.

1. Right-click the canvas, **Add Alias**.
2. Drag from its output pin to the target action, and set the input, timing and conditions on the router entry that appears.
3. Select the alias and tick its source actions, or **Apply To All Actions**.

Graph nodes:

- **Light 1** (montage AM_Attack_Light)
- **Light 2** (montage AM_Attack_Light)
- **Light 3** (montage AM_Attack_Light)
- **UPC.Input.Guard (Interrupt)** (alias; 3 actions)
- **Parry** (montage AM_Parry)

Connections:

- UPC.Input.Guard (Interrupt) to Parry, through UPC.Input.Guard (pressed)

*One alias with Light 1, Light 2 and Light 3 ticked. Compiling copies its one transition onto all three, so a parry is reachable from every step of the combo.*

**Details panel: Alias** (instanced object, in AG_MyFirstGraph)

**Category: Alias**

| Property | Value |
| --- | --- |
| Apply To All Actions | false |
| Source Actions | buttons: Select All, None |
| ROOT | false |
| Light 1 | true |
| Light 2 | true |
| Light 3 | true |
| Parry | false |

*Tick the actions the alias's transition should be copied onto. Turn on Apply To All Actions instead to cover every action, including ones a sub graph brings in.*

**Apply To All Actions** keeps the move reachable as the graph grows. With it on, **Include Root** (on) adds ROOT too; the alias's own target is always left out.

---

## Compile, check and save

A **compile** turns cards and wires into the moves a character runs. Press **Compile**, or save the graph.

Toolbar: Compile (needs attention), Refresh

Graph nodes:

- **ROOT**
- **Light 1** (montage AM_Attack_Light)
- **Light 2** (montage AM_Attack_Light; has a warning)

Connections:

- ROOT to Light 1, through UPC.Input.LightAttack (pressed)

*An edit leaves a compile owed, and the Compile button asks for attention until the graph compiles. Light 2's warning is the last compile's answer, shown until the next one.*

| Compile badge | Means |
| --- | --- |
| Question mark | Uncompiled edits, or a changed sub graph source, have not reached the moves. Compile, save or press Play. |
| Warning sign | Compiled; the **Validation** tab lists something to look at. |
| Green check | Compiled, with nothing to report. |

Findings stay until the next compile: a badge on the card, a row per card in the **Validation** tab that jumps to the card, and whole-graph checks in the **Message Log** tab. All are warnings; none stops a save or Play. [Troubleshooting](https://rigbak.com/docs/universal-player-combat/action-graph-editor#troubleshooting) lists each card message with its fix.

---

## Watch a character run the graph

Toolbar: Compile, Refresh

Debugging BP_UPC_Character_C_0.

Graph nodes:

- **ROOT**
- **Dodge** (montage AM_UPC_DodgeBack; Cooldown 1/2, 0.8 s; running)
- **Light 1** (montage AM_Attack_Light)

*BP_UPC_Character_C_0 picked in Debug, standing in Dodge: its Cooldown gate has one of two charges ready, and the other returns in 0.8 seconds.*

During Play In Editor, **Debug**, above the canvas, lists the characters running this graph or one folding it in, and follows the first until play stops; pick another to follow it. An imported move lights the whole sub graph card. Each gate on a card shows a live row ([Gates, Costs and Cooldowns](https://rigbak.com/docs/universal-player-combat/gates-costs-cooldowns)), such as `1/2, 0.8 s` for a cooldown (1 of 2 charges ready, the next in 0.8 s), green while open and amber while shut. **Refresh** rebuilds the timelines and the list.

> **Warning**
>
> Compiling during play after adding or deleting cards, or changing a sub graph, can leave a running character on the wrong move. Restart Play In Editor or hand the graph to the character again; the Message Log warns when it happens.

---

<details>
<summary>Cards and wires in detail (Advanced)</summary>

- A card row is the Details panel's property: an edit on either side is one edit and one undo, and a row hides when the panel would. A row whose show-or-hide rule the card cannot read stays visible, and the Universal Player Combat message log names it once.
- A montage card names its montage, or `(no montage)`; the timeline's seconds follow the node's **Play Rate**, the montage's rate and **Section Name**, and a double-click on the thumbnail opens the montage. **Use Custom Color**, under **Appearance**, colors a card; a warning outline outranks it, and a running card's green outranks the warning but keeps its badge.
- Right-click a card for **Delete**, **Cut**, **Copy**, **Duplicate** and **Break Node Links**; every card takes a comment bubble. The editor refuses, as you drag, a router into a router, an input into an input, a wire into an alias and a wire out of a To Root card.
- Dots chain, copy, paste and undo like cards; a wire drawn into or out of one can change a route, so it owes a compile.
- A router with a warning draws its wires red. The Message Log tab holds whole-graph checks: two costs on one vital, a gate that cannot open or close, a stale sub graph.
- A C++ payload property reaches the card with `meta = (UPCNodeInline)`; `UPCNodeThumbnail` adds a thumbnail, `UPCNodeCount` an array's length.

</details>

<details>
<summary>To Root, sub graphs and aliases in detail (Advanced)</summary>

- **To Root** ends a move with no animation to end on, such as a Hold block's release. Inside a folded graph it leads wherever the parent routes the sub graph's returns. One nothing wires into warns.
- Imported actions take the source's name in front (`AG_UPC_Shield.Guard Hold`) and its input buffer rule. Double-click a sub graph card to open the source; a stale card turns brown.
- A graph cannot fold in itself: the editor refuses a drop on its own canvas, and a pick in **Sub Graph Asset** or a chain leading back at compile.
- The source Root's Action Completed and Action Failed transitions stay behind, with a warning. A card with nothing in its In pin, or a source with no transitions out of its Root, warns too.
- Alias copies join each action after its own wires and imports, so a hand-wired transition wins a tie. An action already wired with the same input, moment, priority and tags (no conditions on either) keeps its wire and the alias skips it, warning; so does a ticked action that is the target.
- The alias card reads `All actions`, `All actions except Root`, `3 actions`, or `No sources` in red. One with no outgoing wire, no sources or a deleted source warns; a deleted source shows a **Missing action** row with **Clear**.

</details>

<details>
<summary>When the editor compiles (Advanced)</summary>

- Undo and redo compile the open graph; opening a graph compiles nothing.
- A duplicate of a graph owing a compile owes it too, and its next save or Play runs it, editor open or not.
- Compiling an unchanged graph leaves it unmodified, asking for no save.
- Each save writes the graph's checks to the **Universal Player Combat** Message Log listing with no popup, and drops any transition to a deleted card, saying so there.
- **Validate Assets** runs no checks on an Action Graph.

</details>

<details>
<summary>Multiplayer and dedicated servers (Multiplayer)</summary>

The Debug list reads every Play In Editor world and names each character's machine, such as `(Server)` or `(Client 1)`. A dedicated server launched as a process of its own has no world in the editor; the over-head overlay covers every machine.

</details>

<details>
<summary>Troubleshooting (Advanced)</summary>

| The card says | Fix |
| --- | --- |
| ...not wired to a target action. | Drag that row's pin to an action or a To Root card. |
| ...has no Input Tag | Pick the input on the router row. |
| Ambiguous: input '...' shares priority... | Give one of the two a higher **Priority** or a condition. |
| ...has no source action and is unreachable. | Wire an action into the router, or delete it. |
| ...more than one Action Completed route... | Keep one Auto route out of the action, and one Failed. |

**A card shows no gate rows**

Gate rows come from what the character runs, so a card shows a line in their place when the two disagree: `Compile this graph to see its gates live.` after an edit, `Recompile the graph importing this one to see gates live.` for a stale sub graph, and `Imported more than once; debug from the graph importing it.` when two sub graph cards fold in one graph. A pasted card shows nothing live until the graph compiles.

</details>

---

Previous page: [Action Graph](https://rigbak.com/docs/universal-player-combat/action-graph). Next page: [Gates, Costs and Cooldowns](https://rigbak.com/docs/universal-player-combat/gates-costs-cooldowns)
