# Fights

> Stabbing, shooting and fist fights played on the bodies: Actor:wield, Actor:strike, Actor:flee and the moves in Combat/*.json.

Source: https://underlives.com/docs/characters/fights

A fight is played one exchange at a time. One person strikes (a stab, a slash, a swing, a punch, a kick, a shove, a shot) and the other answers at the same moment: they cover, dodge, cower, beg or run. When the blow lands, a wound opens on the body. The scene decides who wins and what happens next. It chains the exchanges with no pause between them and only stops to ask the player when something changes: they fight back, they run. Nothing on screen looks like turns.

`ul_Arms` uses this for **Attack them with a weapon** and **Pull a weapon on them**. Any scene can do the same.

## In a scene

```lua
local me = UL.me()
me:wield("Rooms/Sets/GenCore/Pieces/GenCore/Product_Knife_Kitchen.glb")   -- the knife in the right hand
local seconds = me:strike(target, {
  move = "stab",                 -- an id from Combat/*.json
  hit = true,                    -- false: the blow finds nothing
  wound = { bone = "spine2", side = "front", severity = 0.65, kind = "Stab" },
})
Game:Hold(seconds)               -- let the exchange play
target:flee(me, 900)             -- they run, as far as the room lets them
me:wield()                       -- put it away
me:standDown()
```

| Call | What it does |
| --- | --- |
| `Actor:wield(piece, hand?)` | Puts a room piece (any mod's `.glb`) in the hand, `"r"` (the default) or `"l"`. The hand closes on it the way it closes on things in animation clips: a hold set in the Held Check level wins, otherwise a grip is guessed from the piece's shape. `wield()` with no piece puts it away. |
| `Actor:strike(target, options)` | Plays one exchange and returns how many seconds it takes (`nil` for an unknown move). If the two stand further apart than the move's `reach_cm`, the striker walks up first. |
| `Actor:flee(from, cm?)` | They run from `from`, `cm` away (900 by default), at a running pace. |
| `Actor:standDown()` | The fight is over for them: they drop the guard and the room's life gets them back. This also happens on its own after 30 seconds without a blow. |

Options for `strike`:

| Option | Meaning |
| --- | --- |
| `move` | A move id. |
| `answer` | What the target does: an answer id. Left out, a blow that misses plays the move's `miss_answer`, and a blow that lands is answered by the wound itself. |
| `hit` | `false` for a miss. Defaults to `true`. |
| `wound` | `{ bone, side, severity, kind }`. The wound opens at the moment the blow lands, as `Actor:addWound` would open it. The body then reacts the way [wounds](fluids) make it react: it holds the wound, or goes down. |
| `knockOut` | A cause from `Reactions/*.json` `unconscious.causes`: they are out cold at the moment of the blow. |

A blow that lands with no `wound` and no `knockOut` (a fist, a shove) plays the `reel` answer. A gun move fires at the hit moment, with a flash and its sound. A shot that misses leaves its hole in whatever is behind the target, the same hole `Actor:shootAt` leaves.

## Combat/*.json

Moves and answers are mod data. Every enabled mod's `Combat/*.json` is read in load order, and a later mod's id replaces an earlier one's. The files are read again at every exchange, so a change shows up the next time someone strikes.

```json
{
  "moves": {
    "stab": {
      "clips": [ { "clip": "newMotions/curation/gut_punch_1_F.ulanim", "from": 0.0, "to": 0.75, "hit_at": 0.39 } ],
      "reach_cm": 60,
      "miss_answer": "dodge"
    },
    "shoot": {
      "clips": [ { "clip": "newMotions/curation/attack_12_F.ulanim", "from": 0.15, "to": 0.45, "hit_at": 0.3 } ],
      "reach_cm": 400, "after": "hold",
      "shots": 1, "sound": "gunshot.wav", "flash": true
    }
  },
  "answers": {
    "cover": { "clips": [ { "clip": "newMotions/curation/attack_14_F.ulanim", "from": 0.2, "to": 0.6 } ], "lead": 0.35 },
    "cower": { "activity": "fear_stand", "lead": 0.6 },
    "dodge": { "clips": [ ... ], "lead": 0.25, "step_cm": 35 },
    "flee":  { "flee_cm": 900, "lead": 0.4 },
    "reel":  { "activity": "hurt_stand", "seconds": 2.5 }
  },
  "flee": { "activity": "flee_run", "speed": 2.6, "rate": 1.0 }
}
```

| Field | Meaning |
| --- | --- |
| `clips` | One is drawn at each play. `clip` is a path under a mod's `Animations/`. `from` and `to` mark the part of the clip that plays once, and `hit_at` the moment the blow lands. All three are fractions of the whole clip, so one punch can be taken from a long combo clip. `sex`: `"f"` or `"m"` to prefer the clip for bodies of that sex. |
| `reach_cm` | How far apart the two stand for the move, from one actor to the other. |
| `after` | What the striker does once the move is over: an activity looped, `"hold"` to keep the last frame (the arm still out, the gun still on them), or nothing for the rest idle. |
| `shots`, `shot_gap`, `sound`, `flash` | A gun: the number of shots from the hit moment and the seconds between them. `sound` is a file under a mod's `Audio/`. `flash` lights the muzzle (the held piece's `top` end) for one frame. |
| `lead` | How many seconds before the hit the answer starts: an arm comes up before the blade arrives. |
| `activity` | An answer played as an activity, tried as `<id>_f` / `<id>_m` first. `seconds` is how long it lasts before `after`. |
| `step_cm` | The target steps back that far from the striker (a dodge). |
| `flee_cm` | The target runs that far instead. |

The moves `ul_Arms` ships are `stab`, `slash`, `swing`, `punch`, `kick`, `shove`, `aim`, `shoot` and `shoot_twice`. The answers are `cover`, `dodge`, `reel`, `cower`, `beg` and `flee`. Each weapon class strikes with its own move (`Arms.MOVE`), and each class has a piece to hold (`Arms.HELD`; a weapon's own `held` and `move` fields win over its class's).

The clips are animations already in the game that fit the moves. Dedicated clips for a two-person stab, a pistol shot with recoil and a hit reaction have not been made yet. When they exist, adding them to a move's `clips` is enough.
