# Telegraphs

> Telegraphs warn the player about incoming attacks: a flare over a swing a guard can stop, a cross over an unblockable one, nothing over one that opens a counter, and markers over a stunned enemy.

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

## Set it up (5 minutes)

1. **Create a style set**

   Create the asset: right-click in the Content Browser, choose **UPC > Targeting > Telegraph Style Set**, and name it **TelegraphStyle_MyPlayer**.

   *Right-click in the Content Browser, UPC, Targeting, Telegraph Style Set.*
2. **Add a row for the flare**

   Add a row to **Styles**. Leave **Required Tags** empty so it matches any attack, put `UPC.Attack.Counterable` (a label for an attack that opens a counter move of your own) in **Blocked Tags** so those attacks show nothing, and set **Presenter Class** (the Blueprint actor that draws the marker) to the demo's flare, `BP_UPC_TelegraphPresenter_BlueLine` (a soft yellow line).

   In **TelegraphStyle_MyPlayer**, under Styles, Index [ 0 ], set:

   | Property | Value |
   | --- | --- |
   | Blocked Tags | UPC.Attack.Counterable |
   | Presenter Class | BP_UPC_TelegraphPresenter_BlueLine |

   *An attack matching no row shows nothing.*
3. **Give the player a viewer**

   Add **UPC Telegraph Viewer** to the player character and set its **Style Set** to `TelegraphStyle_MyPlayer`. The demo's `BP_UPC_Character` carries one, set to `TelegraphStyle_UPC_Default`.
4. **Mark the attack's windup**

   On the enemy's attack montage, add the Notify State **UPC Telegraph Window** across the windup, up to the swing's **UPC Melee Trace Window**, and tick **Find The Attack Automatically** so it describes the swing with that swing's own tags.

   **Timeline: AM_MyEnemy_Attack** (1.6 s long). Tracks:

   - **Notifies**: UPC Telegraph Window (0.15 s to 0.6 s); UPC Melee Trace Window (0.6 s to 0.85 s)

   *The marker lives as long as the telegraph window.*

   The window's **Shape** warns players within 500 cm in any direction, leaving the attacker's teammates out; the style set's **View Rules** add limits ([Who is warned](https://rigbak.com/docs/universal-player-combat/telegraphs#who-is-warned)). Your new set has none.
5. **Press Play and stand in front of the swing**

   Stand within 5 m before the enemy starts the attack: the flare shows over the windup and goes as the window closes.

---

## Flare, cross or nothing

Each style row matches an attack by its tags; among matching rows the highest **Priority** wins, then the row listed first:

| Row | Required Tags | Blocked Tags | Priority | Presenter Class |
| --- | --- | --- | --- | --- |
| The cross | `UPC.Attack.Unblockable` |  | 10 | `BP_UPC_TelegraphPresenter_RedCross` |
| The flare |  | `UPC.Attack.Counterable` | 0 | `BP_UPC_TelegraphPresenter_BlueLine` |

The defense reads the same tags off the attack. With `UPC.Attack.Unblockable` in the blocking Guard's **Blocked Attack Tags** and `UPC.Attack.Unparryable` in the parrying one's ([Defense](https://rigbak.com/docs/universal-player-combat/defense)), the two rows give:

| The attack carries | Marker | The guard stops it with |
| --- | --- | --- |
| No attack tag | Flare | A block or a parry |
| `UPC.Attack.Unparryable` | Flare | A block |
| `UPC.Attack.Unblockable` | Cross | A parry |
| `UPC.Attack.Unblockable` and `UPC.Attack.Unparryable` | Cross | Nothing: the player dodges |
| `UPC.Attack.Counterable`, without Unblockable | None | What its other tags allow: Counterable only labels the attack and changes no guard rule |

To keep the cross for attacks the player can only dodge, add `UPC.Attack.Unparryable` to the cross row's **Required Tags**. While a counterable attack winds up, its window holds `UPC.Attack.Counterable` on the attacker, which a counter move requires.

The same set with the two shipped View Rules added; a player must pass them and the window's 500 cm:

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

**Category: Telegraph**

| Property | Value |
| --- | --- |
| Styles | 2 Array elements |
| Styles > Index [0] > Required Tags | UPC.Attack.Unblockable |
| Styles > Index [0] > Blocked Tags | no tags |
| Styles > Index [0] > Priority | 10 |
| Styles > Index [0] > Presenter Class | BP_UPC_TelegraphPresenter_RedCross |
| Styles > Index [0] > Fallback Socket | None |
| Styles > Index [0] > Duration | 0 |
| Styles > Index [1] > Required Tags | no tags |
| Styles > Index [1] > Blocked Tags | UPC.Attack.Counterable |
| Styles > Index [1] > Priority | 0 |
| Styles > Index [1] > Presenter Class | BP_UPC_TelegraphPresenter_BlueLine |
| Styles > Index [1] > Fallback Socket | None |
| Styles > Index [1] > Duration | 0 |
| View Rules | 2 Array elements |
| View Rules > Index [0] | UPC Within Distance |
| View Rules > Index [0] > Max Distance | 1500 |
| View Rules > Index [1] | UPC Subject Facing Viewer |
| View Rules > Index [1] > Arc Half Angle Degrees | 75 |

*An unblockable attack matches both rows and takes the cross, the higher Priority. An attack that is counterable, and not also unblockable, matches neither, so it shows nothing. Every other attack gets the flare.*

**Fallback Socket** places the marker when the announcement names no socket; **Duration** sets the length for a one-frame announcement with none.

---

## Mark the attack on the montage

| Notify | Use it for |
| --- | --- |
| **UPC Telegraph Window** | A stretch of frames: a windup, or the seconds a stunned character is open to a finisher. Its tags sit on the character while it runs; the marker comes down as it closes. |
| **UPC Telegraph** | One frame with no end, such as a parry landing. **Duration Seconds** sets the marker's length, the style row's **Duration** when 0; it holds no tags. |

**Details panel: UPC Telegraph Window** (anim notify, in AM_MyEnemy_Attack)

**Category: Telegraph**

| Property | Value |
| --- | --- |
| Origin Space | Montage Mesh |
| Telegraph Type | Damage |
| Find The Attack Automatically | true |
| Tags | no tags |
| Origin Socket | None |
| Magnitude | 0 |
| Override Time To Impact | false |

**Category: Broadcast**

| Property | Value |
| --- | --- |
| Shape | Sphere |
| Team Filter | Enemies Only |

**Category: Broadcast > Shape**

| Property | Value |
| --- | --- |
| Radius | 500 |

**Category: Debug**

| Property | Value |
| --- | --- |
| Draw Debug | false |

*A fresh window warns players up to 500 cm away. With Find The Attack Automatically ticked it reads the tags of the next UPC Melee Trace Window in its montage section, and with Override Time To Impact left off its countdown is the gap to that window.*

| Setting | Does |
| --- | --- |
| **Telegraph Type** | **Damage** describes an incoming blow and takes the attack's tags; **None** describes a state with **Tags** alone. |
| **Find The Attack Automatically** | Reads the next **UPC Melee Trace Window** in this montage section: its **Extra Damage Tags** and its damage config's **Damage Tags**. Off by default. |
| **Attack** | With that off, the damage config described, for a grab with no trace window. Empty announces the window's **Tags** alone, so a feint warns about a blow it never lands. |
| **Tags** | Added to the attack's tags; under **None**, the whole description. |
| **Origin Socket** | Where the reach is measured from and the marker hangs; None uses the mesh's origin. |
| **Shape**, **Team Filter** | The ground it warns: a **Sphere** of **Radius** 500 cm, or a **Cone** with **Half Angle Degrees** (60) and **Yaw Offset Degrees**. **Enemies Only** leaves the attacker's teammates out. With no Shape, every player the style set passes sees it, wherever they stand. |
| **Override Time To Impact** | Set the countdown by hand, for a grab or a projectile launch with no trace window to measure. |

**Draw Debug** draws the reach for a moment. A window warns once per play-through, also for a montage shown on two meshes ([Animation Integration](https://rigbak.com/docs/universal-player-combat/animation-integration)).

---

## Who is warned

One announcement. Each viewer on this machine, step by step.

1. **An attack announces itself** (a UPC Telegraph Window on the attacker's montage, or Show Marker): The window announces when the montage reaches it, on every machine playing that montage, with the tags it describes the attack by. Show Marker announces the same way on the machine that calls it.
2. **A player on this machine is watching** (UPC Telegraph Viewer, Style Set): Each viewer on a pawn a player on this machine controls, with a Style Set, is asked in turn. A character is never warned about its own attack, and an AI pawn is never a viewer.
3. **The attack reaches the player** (the window's Shape and Team Filter): A window with a shape warns only a player standing inside it whom its Team Filter lets through. With no shape, every viewer goes on to the next step.
4. **A style row matches** (Styles: Required Tags, Blocked Tags, Priority): The highest Priority row matching the attack's tags. No row, no marker.
5. **Every view rule agrees** (View Rules): Close enough, aimed the player's way, or whatever a rule of your own asks. An empty list agrees to everything.
6. **The marker goes up** (the row's Presenter Class, at the Origin Socket or the row's Fallback Socket): The presenter spawns on the socket and Begin Telegraph runs, then Update Telegraph each frame until the window closes or the marker's length runs out, then End Telegraph. A one-frame notify with no length anywhere, or a weapon stowed before this step, draws nothing.

A player who starts watching while a window is still open, such as one who respawned or was given a new style set, is shown that warning too.

The first step that says no means no marker; the window's 500 cm reach is the first, the View Rules follow. The steps run as the window opens, so a player who walks out of range keeps the marker. A player 3 m behind the attacker passes the 500 cm test and the distance rule, and the facing rule refuses it.

The **View Rules** that ship:

| Rule | Warns only about |
| --- | --- |
| **UPC Within Distance** | Attackers within **Max Distance** (1500 cm). |
| **UPC Subject Facing Viewer** | Attackers facing the player, within **Arc Half Angle Degrees** (75; 180 turns it off) of their forward. |

For another rule, such as warning only about the locked-on enemy, make a Blueprint child of **UPC Telegraph View Rule** and override **Should Show**, which gets the announcement and the player's pawn.

---

## Make a marker

A marker is a Blueprint child of **UPC Telegraph Presenter** holding the particle system or widget, named on a style row. It spawns on the socket the warning names and rides the swing; each warned player gets their own.

Blueprint graph, nodes in reading order:

- **Comment box: BP_MyTelegraphMarker · Event Graph**

  - **Event Begin Telegraph** (event); outputs: Telegraph
  - **Activate** (function; Target is Actor Component); inputs: Target = Niagara, Reset = false
  - **Event Update Telegraph** (event); outputs: Normalized Time, Seconds to Impact
  - **Event End Telegraph** (event)

| Event | Runs |
| --- | --- |
| **Begin Telegraph** | As the marker goes up, with the announcement: **Subject**, mesh, socket, **Tags**, **Time to Impact**. Start the effect. |
| **Update Telegraph** | Each frame, with **Normalized Time** (0 to 1 across the windup, 1 as the swing starts sweeping) and **Seconds to Impact**. |
| **End Telegraph** | As the warning ends: the window closed or was cut, its length ran out, Hide Marker, a style set change, or the attacker or weapon went away. The actor goes right after, so a fade plays from a copy spawned here. |

Both follow the montage, so a slowed attack keeps them right. A marker with no swing to time against runs them across its own length; with neither they stay 0, so treat 0 as unknown.

---

## Put the marker on the weapon

Set the window's **Origin Space** to **Drawn Item** and **Origin Socket** to a socket on the weapon's mesh, so a blade flare rides the blade. **Origin Item Tag** picks the item, the one driving combat when unset. For a two-weapon attack, one window per weapon, name a tag from the other item's **Equipment Tags**. Two drawn items sharing a tag answer with the one drawn first. When the item is not drawn or lacks the socket, the marker falls back to the character's mesh in silence, and a weapon put away mid-windup takes its marker with it.

---

## Put a marker over a character

Add **UPC Telegraph Subject** to any actor with a skeletal mesh and call **Show Marker** for a circle over a stunned enemy or a flare on a weak point.

Blueprint graph, nodes in reading order:

- **Comment box: BP_MyEnemy · when it is stunned**

  - **UPCTelegraphSubject** (variable)
  - **Show Marker** (function; Target is UPC Telegraph Subject); inputs: Target, Tags = UPC.State.Staggered, Socket = head, Seconds = 3.0; outputs: Return Value

**Tags** is what the style rows match, **Socket** where the marker sits (the row's Fallback Socket when None), and **Seconds** how long it stays; 0 lasts until **Hide Marker** with the returned handle, or **Hide All Markers**. Each player's style set and view rules still decide what shows, and the actor's own player never sees its markers.

The style set needs a row for the marker's tag, or the catch-all flare answers it. For `UPC.State.Staggered`, add a row with that tag in **Required Tags**, a **Priority** above the flare's 0, and a presenter such as the demo's `BP_UPC_TelegraphPresenter_Executable` rings. **Show Marker** draws on the calling machine only ([What runs where](https://rigbak.com/docs/universal-player-combat/telegraphs#what-runs-where)).

For a state the animation already plays, a **UPC Telegraph Window** with **Telegraph Type** **None** and the state's tag does the same from the montage, holding the tag while it runs; the demo's `AM_UPC_Stun` raises `UPC.State.Staggered` this way.

---

## Debug it

`LogUPCTelegraph` warns once per cause, and Troubleshooting lists each with its fix.

<details>
<summary>Draw the warning in the HUD instead (Alternative)</summary>

The viewer fires **On Telegraph Shown** (the **Subject**, the attack's **Tags**, the **Presenter**) and **On Telegraph Hidden** (Subject and Presenter), also for a row with no Presenter Class, so a HUD can draw its own marker. One attacker can raise several warnings at once, one per weapon, so count per Subject and remove the element at zero. **Set Style Set** swaps the set at runtime and takes down the old set's markers, none turning warnings off; **Get Style Set** reads it. **Is Viewing** answers whether a player on this machine controls the pawn, the only case drawn.

</details>

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

`TelegraphStyle_UPC_Default` adds a counter marker for counterable attacks.

| Marker | Draws |
| --- | --- |
| `BP_UPC_TelegraphPresenter_BlueLine` | The soft yellow flare, `NS_UPC_AttackNotifier_Soft`. |
| `BP_UPC_TelegraphPresenter_RedCross` | The unblockable cross, `NS_UPC_AttackNotifier_Unblockable`. |
| `BP_UPC_TelegraphPresenter_Counter` | The counter marker, the flare in blue, `NS_UPC_AttackNotifier_Counter`. |
| `BP_UPC_TelegraphPresenter_Executable` | Rings over a character open to an execution, `NS_UPC_ExecutionPrompt_Rings`. |

</details>

<details>
<summary>What runs where (Multiplayer)</summary>

- Nothing replicates: each machine draws warnings for its own players from the montages it plays. A dedicated server draws none and loads no presenter.
- **Show Marker** raises a marker on the calling machine only; for every player, call it from something each machine receives, such as a replicated tag or a gameplay cue.
- Each player's machine runs the team test, so put the attacker's UPC Team on the pawn, not its AI controller. Exclusions changed at runtime on the server do not reach clients.

</details>

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

- Announcements go out through `UPCTelegraph::OnBegin()` with an `FUPCTelegraph`, and `UPCTelegraph::OnEnd()` follows when a window or a Show Marker ends; a one-frame notify sends no end. Both are process-wide, so check the `Subject`'s world: two Play In Editor sessions share them. `UUPCTelegraphSubsystem` listens for the viewer.
- `FUPCTelegraph` carries `Subject`, `Mesh`, `OriginSocket`, `Type`, `Tags`, `TimeToImpact`, `bAwaitsExplicitEnd`, `DurationSeconds`, `OriginComponent`, `Origin`, `Direction`, `Magnitude`, `Broadcast` and `Payload`.
- A view rule overrides `UUPCTelegraphViewRule::ShouldShow_Implementation(const FUPCTelegraph&, APawn* Viewer) const`; a presenter overrides `BeginTelegraph_Implementation`, `UpdateTelegraph_Implementation` and `EndTelegraph_Implementation`.
- `IUPCTelegraphOriginProvider::GetTelegraphOriginActor` is a Blueprint native event. `UUPCEquipmentManagerComponent` answers by `GetInstanceByTag` or `GetCombatDriverInstance`; the window asks the pawn, then its first component implementing it.

</details>

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

| Warning says | Fix |
| --- | --- |
| asked for a marker with no length | Set the one-frame notify's **Duration Seconds** or the row's **Duration**. |
| was still loading when a warning went up | Assign the style set before combat; the viewer loads its markers on assignment. |
| found no skeletal mesh to hang a marker on | Give the actor with **UPC Telegraph Subject** a skeletal mesh. |
| which the attack it describes does not carry | The window's Tags promise what the attack lacks; put the tag on the trace window or the damage config. For a feint, untick Find The Attack Automatically and clear Attack. |
| found no melee trace window after it | Add a trace window after it in its section, or tick Override Time To Impact. |

**No marker showed up**

In order:

- **No viewer, or no Style Set.** An AI pawn is never a viewer, so a map with no player shows nothing.
- **The player made the attack.**
- **Out of reach**, or a teammate under Enemies Only, judged as the window opens.
- **No row matches** the attack's tags. With Find The Attack Automatically off and no **Attack**, the window carries only its own Tags.
- **A view rule refused**: a player behind the attacker, or beyond Max Distance.
- **The row has no Presenter Class.**
- **The montage plays in an editor preview**, which runs no game world.

</details>

---

Previous page: [Vitals](https://rigbak.com/docs/universal-player-combat/vitals). Next page: [Interaction](https://rigbak.com/docs/universal-player-combat/interaction)
