# Patterns

> Recipes built on the demo: the three combat styles, a parry and a block, a counter, a shield bash, a dodge with two charges, an execution, a door and a chest, and a heavy that shrugs off hits.

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

> **Warning**
>
> **Build on copies of the demo assets**: a plugin update replaces the plugin's content, edits included. Turn on **Show Plugin Content** in the Content Browser's settings to see the `Demo` folder.

---

## Three combat styles

A style plate at the end of the hallway switches the player's **Combat Style** and loadout and opens its arena.

| Style | Loadout | Feel |
| --- | --- | --- |
| `CombatStyle_UPC_OverShoulder` (the start) | Sword and shield | Faces the camera, attacks straight ahead, close shoulder camera. |
| `CombatStyle_UPC_Freeflow` | Bare fists | Strikes aimed by the stick, no lock-on; the right mouse button guards. |
| `CombatStyle_UPC_Soulslike` | Two swords | Faces where it moves, attacks where it faces, the target while locked. |

For a fourth, duplicate the nearest style and change one fragment at a time; `BP_UPC_StylePlate` calls **Set Style** on the Combat component, then adds the new items.

---

## A parry and a block

The demo sword (Soulslike plate) parries a blow when Guard is pressed as it lands, and blocks while Guard is held. `Item_UPC_Sword`'s **Guard** fragment (the item part that supplies a defense set) lends `DefenseRuleSet_UPC_Sword`, which holds two **UPC Guard** rules with the parry first:

| Field | Parry | Block |
| --- | --- | --- |
| **Required Defender Tags** | `UPC.State.Parrying` | `UPC.State.Blocking` |
| **Arc Half Angle Degrees** | 45 | 60 |
| **Damage Multiplier** | 0 | 0 |
| **Blocked Attack Tags** | `UPC.Attack.Unparryable` | `UPC.Attack.Unblockable` |
| **Result Tag** | `UPC.DamageResult.Parried` | `UPC.DamageResult.Blocked` |
| **Cost Vital Tag** | `UPC.Vital.Stance` | `UPC.Vital.Stance` |
| **Cost Per Damage** | 0.5 | 1 |
| **Spend Remainder when Unaffordable** | on | on |

Guarding spends stance, the large pool that stuns its owner when it breaks. A parried 10-damage blow costs 5 stance, a blocked one 10, and no health. With 4 stance left, the parry spends those 4 (Spend Remainder when Unaffordable) and then declines the blow, which falls through to the responses below it: the 4 stance is spent and the blow is not parried; the next rule decides what it does.

1. Make a **Defense Rule Set** (**UPC**, **Damage and Defense**) with the two rules, parry first, and set it as your weapon's **Guard** fragment **Defense Set**.
2. In the weapon's graph, wire Guard into a raise node, the raise's **Action Completed** into a **Hold** node with **Applied Tags** `UPC.State.Blocking`, and Guard released out of both into a lowering node.
3. On the raise montage, add a **UPC State Tag Window** holding `UPC.State.Parrying` over the frames that parry.

`AG_UPC_Sword` does this with Interrupt transitions from idle and each light attack; `AM_UPC_Sword_Parry` parries for the raise's first half second ([Defense](https://rigbak.com/docs/universal-player-combat/defense)).

<details>
<summary>The recoil and the counter window (Advanced)</summary>

- **A parried attacker recoils.** The rule set's **Outcome Effects** send `UPC.Event.ParryRecoil` to the attacker, which `GA_UPC_ParryRecoil` answers; `AbilitySet_UPC_Default` and `AbilitySet_UPC_Enemy` grant it ([Hit Reactions](https://rigbak.com/docs/universal-player-combat/hit-reactions#answer-the-attacker-a-parry-recoil)).
- **A counter window.** A **UPC Apply Gameplay Effect** outcome applies `GE_UPC_CounterWindow` on a parry, holding `UPC.State.CanCounter` on the defender for a second. Put that tag in a transition's **Required Tags** for a move that only follows a parry.

</details>

---

## A counter

In the Freeflow arena, Guard while a counter marker shows over an enemy's first or second punch plays a paired counter. Otherwise Guard plays **Failed Guard Attempt**, a guard animation that blocks nothing.

One tag chain ties the three assets together:

| Asset | Holds | Says |
| --- | --- | --- |
| `AM_UPC_Unarmed_Combo`, trace window | **Extra Damage Tags** `UPC.Attack.Counterable.A` | This punch is a counterable one, variant A. |
| `AM_UPC_Unarmed_Combo`, **UPC Telegraph Window** before it | **Tags** `UPC.Attack.Counterable`, **Find The Attack Automatically** on | Hold the trace window's tags on the enemy while it winds up, and show the marker (`TelegraphStyle_UPC_Default`). |
| `PairedActionSet_UPC_Unarmed`, row | **Required Target Tags** `UPC.Attack.Counterable.A` | Play `Paired_UPC_Unarmed_Counter_A`, the player as **Defender**; `.B` plays `_B`. |

The enemy's role has **Sync with Current**, taking over the punch at the `Sync` **UPC Paired Sync Marker**. In `AG_UPC_Unarmed`, Guard leaves idle and every punch on two **Interrupt** transitions:

| Transition | Priority | Gate | Leads to |
| --- | --- | --- | --- |
| The counter | 10 | **Paired Action Available** with the set | **Play Paired Action**, **Source** **Paired Action Sets** |
| The fallback | 0 | **Blocked Tags** `UPC.State.ActionRunning` | **Failed Guard Attempt** |

Step by step: [Paired Actions](https://rigbak.com/docs/universal-player-combat/paired-actions#a-counter-sets-and-the-paired-action-available-condition).

---

## A shield bash

With sword and shield drawn (Over Shoulder plate), hold Guard, let go, and press it again within a quarter second: the shield bashes for 100 stance and no health.

| Node in `AG_UPC_Shield` | Payload | Leads on |
| --- | --- | --- |
| **Guard Hold** | **Hold**, **Applied Tags** `UPC.State.Blocking` | Guard released: Guard Lower |
| **Guard Lower** | **Delay**, **Delay Seconds** 0.25 | Guard pressed: Shield Bash; **Action Completed**: idle |
| **Shield Bash** | **Play Montage** `AM_UPC_Shield_Bash` | **Action Completed**: idle |

- **Whose moves.** `Item_UPC_Shield` has **Main Weapon** off, so with both drawn the sword's `AG_UPC_Sword` gives every move.
- **Where the guard comes from.** `AG_UPC_Sword` folds `AG_UPC_Shield` in as a [sub graph](https://rigbak.com/docs/universal-player-combat/action-graph-editor#fold-one-graph-into-another). Its **Entry Required Tags** `UPC.Equipment.Shielded`, the tag the drawn shield puts on the character, adds the shield's moves only while the shield is out; **Priority Bias** 20 lets its Guard win over the sword's.
- **The block.** The shield's own **Guard** fragment lends `DefenseRuleSet_UPC_Shield`, a block on `UPC.State.Blocking`.
- **The bash.** It deals `Damage_UPC_Shield`, its stance under **Additional Vital Damage**.

---

## A dodge with two charges

Two dodges in a row, then a wait; each spends stamina.

1. In your weapon's graph, add a node **Dodge** playing `AM_UPC_DodgeBack`, which holds `UPC.State.Intangible` from 0.17 to 0.95 seconds; a melee trace with the default **Pass Through Tags** passes through it.
2. Under its **Gates**, add **Cooldown**: **Cooldown Tag** `UPC.Cooldown.Ability.Dodge`, **Seconds** 3, **Charges** 2.
3. Under **Costs**, add **Vital**: **Vital Tag** `UPC.Vital.Stamina`, **Amount** 25.
4. Wire idle and each attack to Dodge on `UPC.Input.Dodge`, **Timing** Interrupt from the attacks.
5. Map an Input Action to `UPC.Input.Dodge` in the item's **Input Mappings**, with that action in the item's **Input Mapping Context** ([Inputs an item brings](https://rigbak.com/docs/universal-player-combat/input#inputs-an-item-brings)); the demo's `IA_UPC_Dash` sits on Space and the left shoulder.

Each charge returns 3 seconds after its use; `AG_UPC_Sword`'s dash uses the same gate tag and a stamina cost. [Gates, Costs and Cooldowns](https://rigbak.com/docs/universal-player-combat/gates-costs-cooldowns#cooldown) adds a fallback move and a HUD countdown. Online, a long fast dodge needs `UPC.State.Dashing` in its State Tag Window as well, beside `UPC.State.Intangible` (see [Multiplayer](https://rigbak.com/docs/universal-player-combat/multiplayer#before-you-test-online)).

This dodge is a move in the action graph, so it cannot break out of an interaction, which shuts the graph; that takes a dodge granted as an ability of its own ([Let a dodge break out](https://rigbak.com/docs/universal-player-combat/interaction-payloads#let-a-dodge-break-out)).

---

## An execution

The hallway's paired stations loop `Paired_UPC_Sword_Execute_A`, `Paired_UPC_Sword_Execute_B` (one against two, with an authored camera) and `Paired_UPC_Unarmed_Execute_A`; on the ring marked (you), **E** plays one. The Soulslike arena's boss dies to `Paired_UPC_Sword_Execute_A`, which anchors on the Victim and turns it toward the Attacker, so the stunned boss holds its place while the player slides in, and a **Disarm** event on the Victim at the first slash knocks its baton to the ground. In a fight, the unarmed demo executes a stunned enemy:

- **The stun.** A demo enemy's **Stance** row sends `UPC.Event.GuardBreak` as it empties (**Depleted Gameplay Event**); `GA_UPC_Stun`, Server Initiated in `AbilitySet_UPC_Enemy`, answers and holds `UPC.State.Staggered`.
- **The gate.** `PairedActionSet_UPC_UnarmedExecute`'s row requires that tag in **Required Target Tags** and picks the victim with **Primary Picker** **Current Target**.
- **The press.** `UPC.Input.Execute` (`IA_UPC_Execute` on the demo weapons) leads to a **Play Paired Action** node sourcing the set.

Building one: [An execution on a stunned enemy](https://rigbak.com/docs/universal-player-combat/paired-actions#an-execution-on-a-stunned-enemy); a marker over the stunned enemy: [Telegraphs](https://rigbak.com/docs/universal-player-combat/telegraphs#put-a-marker-over-a-character).

---

## A door and a chest

| Actor | Options | What makes it work |
| --- | --- | --- |
| `BP_UPC_Door` | **Open** on Interact, **Kick** on `UPC.Input.Interact.Secondary` | `AM_UPC_DoorOpen`, `AM_UPC_DoorKick`. A **UPC Interaction Option Provider**, it gives each character the spot on its side and the section that pulls or pushes. |
| `BP_UPC_Chest` | **Open**, and **Break** on the second key | `AM_UPC_ChestOpen`, `AM_UPC_ChestBreak`, from the spot tagged `CharacterPosition` (**Spot Component Tag**). A break throws the lid off as cosmetic pieces; the chest closes after 5 seconds. |

Both follow the [chest recipe](https://rigbak.com/docs/universal-player-combat/interaction-payloads). How the door answers each side: [Answer per character](https://rigbak.com/docs/universal-player-combat/interaction-payloads#answer-per-character).

---

## A heavy that shrugs off hits

Poise is a small pool every hit drains; the hit that empties it flinches a demo character, cutting its attack short. Stance, the large pool, stuns when it breaks ([Hit Reactions](https://rigbak.com/docs/universal-player-combat/hit-reactions#poise-flinch-only-when-it-breaks)). Under hyper armor a swing takes half the poise damage: light hits land and it finishes, a heavy one still breaks it.

- **The window.** In `AM_UPC_Unarmed_Combo`, the sixth punch (section `5`, **Punch 6** in `AG_UPC_Unarmed`) holds `UPC.State.HyperArmor` over its windup and swing through a **UPC State Tag Window**.
- **The bonus.** `DefenseRuleSet_UPC_Character` opens with a **UPC Scale Damage** response that requires `UPC.State.HyperArmor`, with a **Vital Damage Multipliers** row: **Vital Tag** `UPC.Vital.Poise`, **Multiplier** 0.5.
- **The reaction.** On a hit that empties poise (`UPC.DamageResult.PoiseBroken`) and was not blocked or parried, the set's **Outcome Effects** send `UPC.Event.Reaction`, which `GA_UPC_HitReact` answers, and a **UPC Refill Vital** fills the pool again.

On a character set up like the demo's, with a Poise row, `DefenseRuleSet_UPC_Character` and a flinch ability, your own heavy needs only the tag window; [Hyper armor](https://rigbak.com/docs/universal-player-combat/hit-reactions#hyper-armor) builds the rest from scratch.

---

<details>
<summary>More from the demo</summary>

| Move | Where | How |
| --- | --- | --- |
| **Dash strike** | Freeflow | A light attack at an enemy 4 to 8 m away: a **Priority** 5 transition with **Target Distance** **Greater Than (>)** 400 and **Less Or Equal (<=)** 800 into **Strike Dash**, whose montage carries a **UPC Gap Closer Warp** window. |
| **Vault** | Freeflow | Space vaults the target: **Play Paired Action** with `Paired_UPC_Unarmed_Vault`, **Primary Picker** **Current Target**; with no target, nothing. |
| **A swing by distance** | The bosses | `AG_UPC_TwoHanded` sends a light attack to one of three swings by **Target Distance**: under 150, 150 to 300, or farther. Its heavy is an unblockable stomp. |
| **Warnings over swings** | Every arena | `TelegraphStyle_UPC_Default`: a red cross over an unblockable swing, a blue counter marker, a yellow flare over the rest. |
| **Enemies on action graphs** | Every arena | `BT_UPC_Enemy` presses each `BP_UPC_Enemy`'s attacks through **Queue Input Sequence** ([Getting Started](https://rigbak.com/docs/universal-player-combat/getting-started)). |
| **Two swords** | Soulslike | `Item_UPC_Sword` twice; its **Hold Places** list the main hand, then the off hand, and the first drawn gives the moves. |
| **A weapon rack** | Beside the door and chest | `BP_UPC_WeaponRack` is an [item holder](https://rigbak.com/docs/universal-player-combat/pickups-drops-holders#racks-and-shelves-item-holders): a peg filtered on `UPC.Slot.Weapon.Sword` offers **Take** and **Put Back**. |

</details>

---

## Debug it

```
UPC.Debug.Actions 1        // Node and waiting press
UPC.Debug.Paired 1         // Paired move, role, partners
UPC.Debug.Vitals 1         // Health, stamina, stance
UPC.Debug.Targeting 1      // Target, and why
```

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

**The recipe reads wrong in play**

- **No parry:** the tag window misses the hit's frames, or the blow carries `UPC.Attack.Unparryable`. Health falling under `UPC.Debug.Vitals 1` means no rule claimed the hit.
- **No counter:** the enemy carries no `UPC.Attack.Counterable.A` or `.B` at the press; `UPC.Debug.Paired.DrawSelection 1` draws each refusal.
- **A third dodge:** no Cooldown gate, an empty **Cooldown Tag** (which turns it off), **Seconds** 0 or **Charges** above 2. The graph editor shows charges live in play.
- **No execution:** the enemy lacks the tag the row or role requires, or no target is picked.

</details>

---

Previous page: [Multiplayer](https://rigbak.com/docs/universal-player-combat/multiplayer)
