# Multiplayer

> Play online on a listen or dedicated server: a player's moves answer the button at once, the server has the final word on what they cost and hit, and the editor can add lag to test it.

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

## Set it up (2 minutes)

1. **Play as two clients**

   In the Play dropdown, set **Net Mode** to **Play As Client** and **Number of Players** to 2: a dedicated server with two players.
2. **Add lag**

   In **Editor Preferences**, **Level Editor**, **Play**, **Multiplayer Options**, tick **Enable Network Emulation**, set **Emulation Target** to **Everyone**, and pick the **Network Emulation Profile** **Average**, or **Bad** for a poor connection. To lag one machine, use its console:

   ```
   NetEmulation.PktLag 80            // 80 ms on each packet it sends
   NetEmulation.PktLagVariance 20    // Up to 20 ms either way
   NetEmulation.PktLoss 5            // 5% dropped
   ```

   `NetEmulation.Off` turns it off again.
3. **Try it under lag**

   Swing, hit an enemy, draw a weapon from the belt, open a chest and lock on. The swing, the lock and the draw animation answer the press at once; the enemy's health, the drawn weapon and the chest's walk follow a round trip (a packet to the server and back) later.

---

## What runs where

| What | Who decides |
| --- | --- |
| **Moves** | The player's machine, on the press; the server confirms the move or ends it. |
| **Hits** | The attacking player's machine, at contact; the server checks each before damage, and finds an AI's hits itself. |
| **Damage, health, defense** | The server. |
| **Costs and cooldowns** | Both machines check, the server spends. A cooldown blocks at once; its countdown and the spend show a round trip later. |
| **Equipment, belt, inventory** | The server, a round trip after the press; the reach plays at once. Each player receives only their own inventory, and a loot chest's inventory reaches every player near it. |
| **Interaction, paired actions** | The server, checking the option and reach again; they start a round trip after the press. |
| **Targeting and lock-on** | The player's machine, at once. |
| **Camera, HUD, telegraphs, prompts** | Each machine on its own, sending nothing. |

---

## Before you test online

| Check | Why |
| --- | --- |
| **A team on the pawn**, not its controller | Other machines read a controller's team as none ([Targeting](https://rigbak.com/docs/universal-player-combat/targeting#leave-teammates-out)). |
| A combat style's Rotation, Targeting, Approach and Movement fragments on **Every Machine** | The server steers attacks by its own values. Read each fragment's **Scope** in the style, such as `CombatStyle_UPC_Soulslike`; Every Machine is the default ([Combat Styles](https://rigbak.com/docs/universal-player-combat/combat-styles#scope-which-machines-a-fragment-sets-up)). |
| **Steering Mode**, **Attack Facing** and the **Targeting Config**, set at runtime, on every machine | They do not replicate, so the server and each watcher need the same values. Call **Set Steering Mode** and **Set Attack Facing** on the UPC Attack Approach, and **Set Targeting Config** on the UPC Targeting component, on the server and on each player's machine ([Attack Steering](https://rigbak.com/docs/universal-player-combat/attack-steering)). |
| A fast dash holds the movement's **Grace Tag** | Without it a lagging server pulls a long dash back. Put `UPC.State.Dashing`, the demo's tag, in the dodge's State Tag Window beside `UPC.State.Intangible` ([Patterns](https://rigbak.com/docs/universal-player-combat/patterns#a-dodge-with-two-charges)). |
| **Replication Mode** Mixed or Full on an ability system the PlayerState carries | Under Minimal the player's machine receives no cooldown timers. Set it in C++ with `SetReplicationMode`; the UPC Character Base's own runs Mixed. |

---

## Cheating and fairness

By default a hit counts once it lands on the attacker's screen, suiting co-op and PvE.

**For competitive PvP, set Hit Detection Authority to Server Authoritative**: the server finds every hit itself and refuses reported ones, and the attacker sees contact a round trip late. Set it on a character's **UPC Melee Trace**, or for every character left on **Project Default** with **Default Hit Detection Authority** in **Project Settings**, **Plugins**, **Universal Player Combat** ([Melee Trace](https://rigbak.com/docs/universal-player-combat/melee-trace)).

<details>
<summary>What the server checks (Advanced)</summary>

- **A reported hit** must come from a swing window the server's copy of the attack plays, land within the weapon's reach plus what latency explains, and stay within the hits and targets that window allows. One that fails deals nothing.
- **Moves**: which may follow which, and how soon. **Costs and cooldowns**, **equipment changes**, **interaction reach**, and how far a dash carries the player.

</details>

---

Previous page: [HUD and Input Prompts](https://rigbak.com/docs/universal-player-combat/hud-and-input-prompts). Next page: [Patterns](https://rigbak.com/docs/universal-player-combat/patterns)
