# Paired Actions

> A paired action is one move two or more characters play together, such as an execution, a counter or a grab: each fills a role with its own montage, and all line up around one spot on the ground.

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

## Set it up (10 minutes)

1. **Create a Paired Action**

   Create a **Paired Action** named `Paired_MyExecution` and double-click it to open the [pairing editor](https://rigbak.com/docs/universal-player-combat/pairing-editor).

   Create the asset: right-click in the Content Browser, choose **UPC > Paired > Paired Action**, and name it **Paired_MyExecution**.

   *Right-click in the Content Browser, UPC, Paired, Paired Action.*
2. **Add two roles**

   In **Roles**, click **Add Role** twice and name them `Attacker` and `Victim` ([Pairing Editor](https://rigbak.com/docs/universal-player-combat/pairing-editor) covers the star and renaming). The **anchor** is the spot on the ground the roles line up around. A placed spot's own location and facing are the anchor ([The anchor](https://rigbak.com/docs/universal-player-combat/paired-actions#the-anchor)). In Details, set the Attacker's **Montage** to `AM_UPC_Unarmed_Execute_Attacker_B` and the Victim's to `AM_UPC_Unarmed_Execute_Victim_B`.

   *Interactive diagram on the page: The first role added becomes the anchor and carries the star. F2 or a right-click renames a role; the right-click menu also holds Set as Anchor and Delete.*
3. **Line them up**

   Click **Derive Offsets**: the Victim's ring moves to where the montages place it. If it stays, drag the Victim's stand-in until the poses meet. Save.
4. **Put it in the level**

   Make a Blueprint Actor `BP_ExecutionSpot` with **UPC Paired Action Spot** (**Paired Action** `Paired_MyExecution`) and **UPC Paired Action Interactable** (**Instigator Role** `Attacker`). Place it, drop the demo's `BP_UPC_PairedDummy` (`Showcase/Paired`) on the Victim's ring, and add a **Placed Role Actors** entry `Victim` naming it.

   Components panel of **BP_ExecutionSpot**:

   - UPC Paired Action Spot (add)
   - UPC Paired Action Interactable (add)

   *What plays and where, and a prompt to join it.*

   **Details panel: UPC Paired Action Interactable** (component, in BP_ExecutionSpot)

   **Category: UPC > Paired Action**

   | Property | Value |
   | --- | --- |
   | Spot Component Tag | None |
   | Instigator Role | Attacker |
   | Placed Role Actors | 1 Map element |
   | Placed Role Actors > key Victim | BP_UPC_PairedDummy |
   | Cancel Active on Conflict | false (advanced) |

   *Its own option row, Play Paired Action, ships filled in. Keep its Option Id and leave its Payload empty.*
5. **Press Play**

   Stand on the Attacker's ring and press **E** at **Take Part as Attacker**: the dummy glides onto its ring and the two play the execution.

---

## Ways to play it

Every character taking part, a prop filling a role included, needs an ability system component and fills one role.

| From | Use | Picks the characters |
| --- | --- | --- |
| A spot in the level | **UPC Paired Action Spot** and **UPC Paired Action Interactable** | Whoever presses Interact, plus actors you name. |
| A move | The **Play Paired Action** payload on an action graph node | A search as the node runs. |
| A button of its own | A Blueprint child of `UPCPairedActionTriggerAbility` | A search on the press. |
| Blueprint | **Try Run Paired Action** and its siblings, or **Play Paired Action** | A search, or the characters you hand it. |

### In the level

Its rings show in the editor, and in play with **Draw in Game**. The interactable gives **Instigator Role** to whoever presses Interact and the other roles to **Placed Role Actors**, or **Set Role Actor** (server, on a replicating actor) for a spawned character. Edit its **Play Paired Action** row's prompt and button, keeping the Option Id and empty payload. **On Prepare Play** fires on the server before the action starts, to hand over a weapon the action shows.

### An execution on a stunned enemy

1. Duplicate `Paired_MyExecution` as `Paired_MyStunExecution` and select **Victim**:

   - **Required Actor Tags** `UPC.State.Staggered`, which the demo's stun holds, so only a stunned enemy fits.
   - **Tags During Action**, add `UPC.State.Intangible`, so other swings pass through the victim.
   - Tick **Stand Down Actions on Join**: the enemy stops what it was doing the moment it joins.
2. On the Action tab, set **Release Rule** to **When All Finish**: the victim stays in the action, untouchable, until the Attacker's part ends too.
3. In the player's action graph, add a node with the **Play Paired Action** payload, **Paired Action** `Paired_MyStunExecution`, **Owner Role Id** `Attacker`.
4. Wire Root to it on `UPC.Input.Execute` ([Action Graph](https://rigbak.com/docs/universal-player-combat/action-graph)).

The demo's sword and unarmed items carry `IA_UPC_Execute`. An enemy of your own needs Pawn collision and an enabled **UPC Targetable** ([Who it picks](https://rigbak.com/docs/universal-player-combat/paired-actions#who-it-picks)), and must hold `UPC.State.Staggered` while stunned.

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

**Category: Execution**

| Property | Value |
| --- | --- |
| Payload | Play Paired Action |
| Payload > Source | Paired Action |
| Payload > Paired Action | Paired_MyStunExecution |
| Payload > Owner Role Id | Attacker |
| Payload > Target Teams | Enemies Only |
| Payload > Primary Picker | None |
| Payload > Gather Radius | 400 |
| Payload > Gather Arc Degrees | 180 |
| Payload > Play Rate Override | 0.0 |
| Payload > Cancel Active on Conflict | false |

*Source Paired Action plays the one move named here with whoever fits it. Source Paired Action Sets swaps these rows for a Paired Action Sets list.*

On the press, the node looks within **Gather Radius** (400 cm) and **Gather Arc Degrees** (180) for an enemy (**Target Teams**, Enemies Only) that fits the Victim role ([Who it picks](https://rigbak.com/docs/universal-player-combat/paired-actions#who-it-picks)) and stands within the action's **Max Slot Distance** (200 cm by default, 0 accepts any) of its slot; an enemy inside the radius but farther from its slot is rejected. Finding none, it refuses and **Action Failed** runs. The node ends as the paired action starts. The action itself then keeps both characters until each role is released ([Release Rule](https://rigbak.com/docs/universal-player-combat/paired-actions#the-anchor)).

### A counter: sets and the Paired Action Available condition

A counter answers an enemy's swing: Guard pressed while a counterable blow comes in plays a paired move, and a guard otherwise. A **Paired Action Set** holds the moves, one row per move with the situation it answers.

1. **The move.** Duplicate the demo's `Paired_UPC_Unarmed_Counter_A` (`Demo/Weapons/Unarmed/Animations`) as `Paired_MyCounter`. Its roles are `Defender`, the player, and `Attacker`, the enemy whose swing it catches. The demo's Attacker role ticks **Sync with Current**, so the move takes over the swing already playing; a copy keeps it (the Sync with Current drawer below covers your own).
2. **The set.** Create `PairedActionSet_MyCounters` and add a row: **Action** `Paired_MyCounter`, **Owner Role Id** `Defender`, **Required Target Tags** `UPC.Attack.Counterable`, **Priority** 10. A telegraph window holds an attack's tags on the attacker as it winds up, so the row answers counterable blows only; the demo's Freeflow punches carry the tag ([Patterns](https://rigbak.com/docs/universal-player-combat/patterns#a-counter)).
3. **The button.** Wire Guard out of idle twice:

| Transition | Priority | Condition | Leads to |
| --- | --- | --- | --- |
| First | Higher | [Paired Action Available](https://rigbak.com/docs/universal-player-combat/action-graph#branch-on-more-than-the-button), naming `PairedActionSet_MyCounters` | A node with the **Play Paired Action** payload: **Source** **Paired Action Sets**, the same set |
| Second | Lower | None | The guard node |

Create the asset: right-click in the Content Browser, choose **UPC > Paired > Paired Action Set**, and name it **PairedActionSet_MyCounters**.

*Right-click in the Content Browser, UPC, Paired, Paired Action Set.*

**Details panel: PairedActionSet_MyCounters** (data asset, in Content Browser)

**Category: Paired Actions**

| Property | Value |
| --- | --- |
| Options | 1 Array element |
| Options > Index [0] > Action | Paired_MyCounter |
| Options > Index [0] > Owner Role Id | Defender |
| Options > Index [0] > Required Target Tags | UPC.Attack.Counterable |
| Options > Index [0] > Priority | 10 |

*One row: the move and the situation it answers. The row's other settings keep their defaults.*

<details>
<summary>Sync with Current (Advanced)</summary>

The demo counter ticks **Sync with Current** on its Attacker role, so the paired move takes over the swing already playing. For your own, tick it on the enemy's role and put a **UPC Paired Sync Marker** named as the role's **Sync Marker** (`Sync`) on the swing's caught frame and the matching frame of the paired montage. Pressed late, the paired montages run up to 4 times faster until the frames meet; pressed early, the action waits while the other roles glide in. A swing with no marker uses its next melee trace window or its telegraph countdown.

- One role may sync, joining no later than its marker. Set its montage **Blend In** to 0 (validation's Fix does it), since the handoff is a cut.
- A marker the paired montage lacks plays the action unaligned, with one warning.

</details>

<details>
<summary>When several rows fit (Advanced)</summary>

1. The highest **Priority** wins; a lower row plays only when nothing above it fits.
2. Among rows of that priority, the best fit wins: the row whose farthest character stands closest to its slot (where its **Offset Location** and **Offset Rotation** put it, under [Roles](https://rigbak.com/docs/universal-player-combat/paired-actions#roles)). A row whose cast stands beyond the action's **Max Slot Distance** (200 cm) does not fit at all.
3. Rows within **Fit Epsilon** (25 cm) of that best fit count as equal, and **Weight** draws among them. A **Fit Epsilon** of 0 plays the best fit with no draw.

Say rows A (Weight 1) and B (Weight 3) share Priority 10. At 60 cm and 75 cm from their slots both sit within 25 cm of the best, so B plays three times in four; at 60 cm and 120 cm, A always plays. A Priority 20 row that fits beats both.

</details>

<details>
<summary>Check a set covers every attack (Advanced)</summary>

Set **Coverage Root** on the set to a root of attack tags, such as `UPC.Attack.Counterable`: **Coverage** under it lists each tag beneath that root no row answers, a counter nobody wrote. Editor only; clear it to stop checking.

</details>

#### One action, a different animation for each enemy type

Put a tag of your own, such as `Enemy.Type.Heavy`, in the heavy enemy's [Character Tags](https://rigbak.com/docs/universal-player-combat/combat-styles#tags-the-character-always-carries). In the set, add a row above the generic one with a higher **Priority**, **Required Target Tags** `Enemy.Type.Heavy` and that enemy's own **Action**. The generic row, requiring none, stays last for every other enemy.

### From a button of its own

Make a Blueprint child of `UPCPairedActionTriggerAbility`, fill **Actions** with your sets, and grant it on an **Input Tag** such as `UPC.Input.Execute`. A press with nothing to play fails with `UPC.Ability.Fail.NoPairedAction`, which a failed-activation listener can answer with a guard. The ability ends with the paired action.

### From Blueprint

| Node | Does |
| --- | --- |
| **Try Run Paired Action** | Plays one move with whoever fits; **Debug** draws the search for two seconds. |
| **Try Run Paired Action from Set**, **from Set Array** | Plays the best fitting row of the sets. |
| **Find Paired Action**, **Play Paired Action Pick** | Finds a move and cast without playing, for a prompt; then plays it. |
| **Can Run Any Paired Action** | Whether anything in the sets could play now. |
| **Play Paired Action**, **at Anchor** | Plays with the characters you hand it, at Anchor around a spot you choose, with a pin per stage. |
| **Get Paired Action Slots at Anchor**, **for Bindings** | Where each role would stand. |

Off the server, play nodes report **Not Authority** or fire **On Failed**.

---

## Who it picks

A search looks around the character for bodies to fill the other roles. A body counts when:

- its collision is a Pawn object and it carries an enabled **UPC Targetable**;
- it stands inside the search's radius and arc, on the side **Target Teams** allows;
- its tags fit a role, and it is in no other paired action.

Required roles fill first, then the role the fewest bodies could take; each role takes the body nearest its slot. With a Victim any enemy fits and a Heavy only an `Enemy.Type.Heavy` enemy fits, the Heavy fills first, so the tagged enemy is not used up as the Victim. A **Primary Picker** on a row or node picks the main body another way:

| Picker | Picks |
| --- | --- |
| **Current Target** | The attack's target, else the lock, else a fresh pick; **Repick at Press** picks fresh, for a vault the stick aims. Needs [UPC Targeting](https://rigbak.com/docs/universal-player-combat/targeting); for a remote player it is the target that player last reported to the server, which exists only when a Target State or Target Distance condition sits on the transition or the targeting config selects continuously. |
| **Proximity Scan** | The nearest inside **Radius** (300 cm) and **Max Angle Degrees**; 180 includes behind. |
| **Soonest Impact** | The body whose blow lands first; **Max Seconds to Impact** at 0.6 keeps a counter to swings on their way (0, the default, takes any). |
| **Scored** | The best by a Targeting Config's score policies, the character's own when empty. |

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

**Category: Paired Action**

| Property | Value |
| --- | --- |
| Primary Picker | Soonest Impact |
| Primary Picker > Min Targets | 1 |
| Primary Picker > Radius | 300 |
| Primary Picker > Max Angle Degrees | 90 |
| Primary Picker > Required Target Tags | no tags |
| Primary Picker > Max Seconds to Impact | 0 |
| Primary Picker > Max Targets | 1 |

*The body whose blow lands first, for a counter. Set Max Seconds to Impact to 0.6 to keep it to swings already on their way; 0 accepts any wait.*

**Target Role Id** is the role the pick fills (None: the first it may fill), and a pick that fails the row's tags, team or rules refuses the row. As a transition condition in the action graph, a picker passes once it finds **Min Targets**.

---

## Roles

At Role, with the Attacker as the anchor: the attacker holds its ground and the victim glides onto the ring in front of it, turned to face it.

**Details panel: Victim** (instanced object, in Paired_MyStunExecution)

**Category: Role: Victim**

| Property | Value |
| --- | --- |
| Offset Location | (110, 0, 0) |
| Offset Rotation | (0, 0, 180) |
| Required | true |
| Required Actor Tags | UPC.State.Staggered |
| Blocked Actor Tags | no tags |
| Role Start Seconds | 0 |
| Role End Seconds | 0 |
| Travel Mode | Data Driven |
| Approach Duration Seconds | 0.4 |
| Approach Speed Limit | Unlimited |
| Tags During Action | UPC.State.ActionsBlocked, UPC.State.EquipmentBlocked, UPC.State.Intangible |
| Stand Down Actions on Join | true |
| Cancel Abilities on Join | no tags |
| Hooks | 0 Array elements |

**Category: Animation**

| Property | Value |
| --- | --- |
| Montage | AM_UPC_Unarmed_Execute_Victim_B |
| Start Section | None |
| Start Delay Seconds | 0 |
| Play from Seconds | 0 |
| Play to Seconds | 0 |
| Sync with Current | false |
| Sync Marker | Sync (greyed out) |

**Category: Preview Stand-In (collapsed until clicked)**

| Property | Value |
| --- | --- |
| Preview Kind | Skeletal Mesh |
| Preview Mesh | None |
| Preview Anim Instance Class | None |
| Preview Items | 0 Array elements |
| Preview Scale | 1 |
| Preview ZOffset | 0 |
| Preview Mesh Yaw Offset | -90.0 |

*The stun execution's Victim. Select a role in the Roles panel, on the timeline or in the viewport; picking its Animation row on the timeline narrows the panel to Animation.*

| Setting | Does |
| --- | --- |
| **Offset Location**, **Offset Rotation** | The role's slot around the anchor, ground position and yaw only; drag the stand-in to set it. |
| **Required** | Off, the action plays without it: an optional second victim. |
| **Required Actor Tags**, **Blocked Actor Tags** | Who may fill it, such as `UPC.State.Staggered` or an item's equipment tag. |
| **Tags During Action** | Held during the part: `UPC.State.ActionsBlocked` and `UPC.State.EquipmentBlocked` by default; add `UPC.State.Intangible` so swings pass through a victim. |
| **Stand Down Actions on Join** | Stops the character's action graph as it joins. |
| **Cancel Abilities on Join** | Cancels abilities by tag as it joins: a raised guard, a spell. |
| **Travel Mode** | **Data Driven** (default) glides onto the slot in **Approach Duration Seconds** (0.4), through characters, not walls; **Montage Driven** moves by a warp window on **Warp Target Name** (`UPCPairedAction`) or a UPC Approach Window; **In Place** stays. |
| **Approach Speed Limit** | **Unlimited** (default) arrives on time; **Fixed Speed** (600 cm/s) and **Character's Max Speed** can arrive short. |

Every character taking part holds `UPC.State.PairedAction`. The role's bar on the [timeline](https://rigbak.com/docs/universal-player-combat/pairing-editor#the-timeline) sets when it is in the action, in seconds from the action's start:

- **Role Start Seconds**: when the role joins. Its tags go on, its hooks start and its glide begins. 0 joins at the start.
- **Role End Seconds**: when the role is let go. 0 leaves it to the **Release Rule**. Under On Own End, a montage ending sooner lets it go first.

A Data Driven role's montage that starts inside its glide (**Approach Duration Seconds** after the role's start) loses its root motion until the glide ends. Start the montage after the glide, or use Montage Driven; the pairing editor's validation reports the overlap.

---

## The anchor

**Details panel: Paired_MyExecution** (data asset, in UPC Pairing Editor)

**Category: Paired Action > Timing**

| Property | Value |
| --- | --- |
| Play Rate | 1.0 |
| Action Length Seconds | 0 |

**Category: Paired Action > Anchor**

| Property | Value |
| --- | --- |
| Anchor Mode | At Role |
| Anchor Role Id | Attacker |
| Formation Yaw Offset | 0.0 |
| Face Toward Role Id | None |
| Warp Target Name | UPCPairedAction |

**Category: Paired Action > Cast**

| Property | Value |
| --- | --- |
| Abort Rule | Cancel All |
| Release Rule | On Own End |

**Category: Paired Action > Placement**

| Property | Value |
| --- | --- |
| Max Slot Distance | 200 |
| Max Slot Yaw Degrees | 0 |
| Require Clear Slots | false |

**Category: Paired Action > Designer Tools**

| Property | Value |
| --- | --- |
| Designer Tools | buttons: Derive Offsets from Montages |

*The Action tab: settings for the whole action. A role's own settings live in the Details tab.*

| Setting | Does |
| --- | --- |
| **Anchor Mode** | **At Role**: under the **Anchor Role Id** role's feet, which holds its ground. **Centroid**: the middle of the cast's feet. |
| **Face Toward Role Id** | Turns the anchor to a role, lining the cast up between them. None keeps the anchor's facing. |
| **Formation Yaw Offset** | Turns the formation around the anchor. |
| **Release Rule** | **On Own End** (default) frees each role as its montage ends; **When All Finish** holds all until the action ends, so a short victim part stays untouchable. |
| **Abort Rule** | **Cancel All** (default) ends every role when one ends early; **Independent** does not. |

A play that names its own spot, such as a placed spot, ignores Anchor Mode and Face Toward; the spot's location and facing are the anchor.

Centroid: the anchor sits between the two bodies and faces the first role, so both glide to meet in the middle.

---

## Hooks on a role

**Clear Space** clears room as its role starts: bystanders within **Radius** (500 cm) on **Teams** stop attacking, any nearer than **Keep Out Distance** (300 cm) step back over **Retreat Seconds**, and each holds **Held Tags** (`UPC.State.ActionsBlocked`) until the role ends. Put it on the player's role in a counter. **Teams** reads from the hook's role: there, Enemies Only holds the enemies.

**Details panel: Defender** (instanced object, in Paired_MyCounter)

**Category: Role: Defender**

| Property | Value |
| --- | --- |
| Hooks | 1 Array element |
| Hooks > Index [0] | Clear Space |
| Hooks > Index [0] > Radius | 500 |
| Hooks > Index [0] > Keep Out Distance | 300 |
| Hooks > Index [0] > Retreat Seconds | 0.4 |
| Hooks > Index [0] > Teams | Enemies Only |
| Hooks > Index [0] > Stop Actions | true |
| Hooks > Index [0] > Held Tags | UPC.State.ActionsBlocked |
| Hooks > Index [0] > Ignored Tags | no tags |
| Hooks > Index [0] > Tick | false |

*On the player's role in a counter: other enemies nearby stop attacking, back off and wait until the role's half ends.*

**Authored Camera Shot**, **Auto Cinematic View** and **Camera Layer** move the camera of the player in the role ([Cameras for paired actions](https://rigbak.com/docs/universal-player-combat/camera#cameras-for-paired-actions); keying a shot: [Pairing Editor](https://rigbak.com/docs/universal-player-combat/pairing-editor#camera-shots)).

---

## Listen from your own Blueprint

- A [timeline](https://rigbak.com/docs/universal-player-combat/pairing-editor#events) **Notify Listener** event calls **On Paired Action Event**, with its name, numbers and words, on a character that implements `UPCPairedActionListener` and has an ability system.
- **Is Actor in Paired Action** and **Is Actor in Any Paired Action** answer for a character; **Is Paired Action Active**, **Get Paired Action Role Actor**, **Get Paired Action Roles** and **Is Paired Action Role Live** for a play node's handle.

---

## Debug it

| Console variable | Shows |
| --- | --- |
| `UPC.Debug.Paired.Draw 1` | The anchor, each slot and its facing, at every play. |
| `UPC.Debug.Paired.DrawSelection 1` | Every search: sphere, arc, each body green or red with the reason. |
| `UPC.Debug.Paired 1` | Over each character in one: the action, its role, its partners. |

`Log LogUPCPaired Verbose` writes why each row was chosen or refused, and Troubleshooting lists what each refusal means.

<details>
<summary>Placement and casting rules (Advanced)</summary>

- **Placement** on the Action tab: **Max Slot Distance** (200 cm, 0 any) is the farthest a character may stand from its slot; **Max Slot Yaw Degrees** (0, any) the most it may turn; **Require Clear Slots** refuses a slot something solid stands on, ignoring the cast. The worst character speaks for the cast.
- Every play checks role tags and placement, characters handed in directly included.
- A spot's row shows only while its character may fill Instigator Role, each required role has a character near its slot, and nobody is busy. The interactable also fires **On Paired Action Started** and **Ended** on the server, and **Evaluate Play** asks whether the action could play, its **Refusal** saying why not.
- **Cancel Active on Conflict** lets the asking character leave a running paired action for this one, to chain executions.
- A hook of your own is a Blueprint `UPCPairedActionHook` with **Enter**, **Exit** and **Tick Paired Action** (**Tick** on) and **On Montage Notify**.
- A row's **Rules** add checks: **Actor Class**, or a Blueprint `UPCPairedActionRule` overriding **Should Allow Candidate** or **Should Allow Pick**. A Blueprint `UPCPairedTargetPicker` overriding **Pick Targets** is a picker of your own.

</details>

<details>
<summary>The demo</summary>

- The paired hallway runs six `BP_UPC_PairedStation` actors, each a spot and an interactable, with `BP_UPC_PairedDummy` as the partner.
- `PairedActionSet_UPC_Unarmed`, `PairedActionSet_UPC_UnarmedExecute` and `PairedActionSet_UPC_SwordExecute` hold the demo's counters and executions.

</details>

<details>
<summary>Only the server starts and ends it (Multiplayer)</summary>

- Every role, the victim's included, starts from an event the server sends to that character's ability system, and plays on every machine from there.
- The graph node asking for an execution is predicted, so the press feels immediate; the paired action waits for the server. A press finding nobody on the player's machine takes Action Failed there, and the server confirms that route.
- A part whose montage is over holds on every machine until the server releases the role; the player's copy ignores a local cancel.
- The trigger ability runs on the server, which works the choice out again. A spot's row on a client is a hint the server checks again.
- **Find Paired Action** reads replicated state, so a prompt matches the press except within about 0.1 s plus half a round trip of a timing edge. The handle and actor queries answer on every machine, a client's a moment behind.
- A gliding role passes through characters on the server and its own player's machine; on a third player's it can still block.

</details>

<details>
<summary>C++</summary>

- `UUPCPairedActionSubsystem` runs every paired action. `PlayPairedAction`, `CancelPairedAction`, `ReleaseRole` and `ReleaseRoleAfter` are C++ only; Blueprint ends a role early with a **Release Role** timeline event.
- `UPCPairedActionStatics::ResolveOptions` ranks fitting rows (priority, fit, authored order) without changing the world; `ChooseRankedIndex` (authority) draws among near ties by weight; `CheckPlacement` runs the placement checks on a cast you chose.
- Subclass `UUPCPairedTargetPicker` (`PickTargets_Implementation`), `UUPCPairedActionRule` (`ShouldAllowCandidate_Implementation`, `ShouldAllowPick_Implementation`), `UUPCPairedActionHook` and `UUPCPairedActionEvent`. Pickers, rules and events are shared by every play, so hold no per-play state; hooks are copied per play.

</details>

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

| Refusal | Means |
| --- | --- |
| **No Options** | No sets, or every row off or empty. |
| **Owner Tags** | The asking character misses a tag the row or role wants, or holds a blocked one. |
| **No Candidates** | Nothing targetable nearby. |
| **Target Tags** | No body has the tags a row or role wants: a counter while the enemy is not swinging. |
| **Team**, **Already Pairing** | The only bodies in reach are allies, or busy elsewhere. |
| **Candidate Rule**, **Pick Rule** | A row's rule refused every body, or the cast. |
| **Missing Roles** | Too few bodies for the required roles. |
| **Too Far**, **Wrong Facing**, **Slot Blocked** | The asset's placement checks. |
| **Not Authority** | It ran off the server. |
| **Director Refused** | A body stopped being valid before the play. |

</details>

---

Previous page: [Interaction Payloads](https://rigbak.com/docs/universal-player-combat/interaction-payloads). Next page: [Pairing Editor](https://rigbak.com/docs/universal-player-combat/pairing-editor)
