# Reviewing a run

Day 2, hours 6 and 7 of the [training path](TRAINING.md): the after-action review. A run is recorded as its inputs
and the instructor's commands, and it plays back to exactly the same run. The console's review mode plays it on a
timeline: jump to any event, watch from any camera, and take over from any moment to try it again.

You need [The instructor](TRAINING-INSTRUCTOR.md): the console, and a recorded run.

## 1. Record the run

A session is recorded when it starts with a recording file:

```sh
argus run . --save-replay runs/trainee-1.replay
```

The recording holds:

- the scene's identity, and the engine version that made it;
- every tick's input;
- the instructor's commands, at their ticks;
- the journal's entries and the metric values, which a playback checks;
- the journal kinds and metric definitions in force, so a recording scores the same even after the project's files
  change.

It is a text file of about a line a tick: Crossing Drive's one-minute self-test run is about 340 KB with the
journal and metric values, under 50 KB zipped.

In the console, **End and review** ends the live run for everyone and opens its recording in review. **Open
recording** lists the recordings beside it.

## 2. The review

| Where | What |
|---|---|
| Event list | every event, the instructor's included; click one to jump to 3 s before it, so you see it coming |
| Timeline | the run end to end, each event a marker by severity, with the scorecard's traces (speed) under it |
| Transport | play and pause (Space), a tick back or forward (← →), the previous or next event (3 s before it), the speed, and a loop over a stretch |
| Cameras | the scene's cameras, follow any entity, or fly free |
| Bookmarks and notes | yours, kept in the recording file itself; click one to jump to 2 s before it |
| Result | the scorecard, scored from the recording |
| At the playhead | the scorecard's numbers at the moment shown: a reaction time appears once the playhead passes it |

Jumping is fast: when it opens a recording, the review plays it through once, as fast as it simulates, keeping a
snapshot every few seconds. A jump restores the nearest snapshot and simulates only the ticks after it, so it lands
on exactly the state a straight playback reaches, in a fraction of a second.

**It looks as the run did.** The review shows the environment each tick had, so the dusk comes in when the instructor
set it, and the game's HUD with its own units and decimals. While an instructor held the trainee's vehicle, the view
says **Instructor has taken over from** and the trainee's name.

**The camera is only yours.** Changing it changes what you see, never the run: the simulation does not read the
review's camera. A camera chosen while paused shows at once.

## 3. Take over from here

**Take over from here** turns the review into a live session at the moment shown. The trainee, or you, drives on
from there, and the instructor's tools all work.

The new run is recorded as a recording of its own, named after the first with `.branch-<tick>`
(`trainee-1.branch-900.replay`). Its header names the recording it came from and the tick it branched at, and it
carries the first one's input up to that tick, so it plays on its own. Up to the branch it is exactly the first run,
which the engine checks. The clock starts paused at the branch, so nobody is surprised: resume when the driver is
ready.

## 4. Share it

**Share recording** downloads the file. For a few seconds the button then names it and its size
(**Saved trainee-1.replay · 340 KB**). Anyone with the same scenario and the same engine version plays it back to the
same run, on Windows or Linux. Another engine version refuses it (`replay-engine-mismatch`), so keep the engine a
recording was made on for as long as it may be replayed. Keep the recordings with the reports: re-scoring a
recording with a changed scorecard gives the new score for the old run.

Score a recording without the console with the Training plugin's `score.mjs`
([Events, metrics and scorecards](TRAINING-EVENTS-SCORECARDS.md), section 6). It reads only the file.

## 5. Without the console

The review is the engine's replay timeline, and a script can drive it on the session's port. The reference is
`crates/query/API.md` (on the docs site, **Query API**), "The replay timeline":

| Request | Does |
|---|---|
| `POST /timeline {"load": "<recording>"}` | opens a recording; `"@session"` ends the live run and opens its own recording (the run was started with `--save-replay`) |
| `POST /timeline {"seek": 900}` | jumps to tick 900 |
| `POST /timeline {"play": 1}`, `{"pause": true}` | plays at a rate, or holds |
| `POST /timeline {"step": 1}`, `{"step": -1}` | a tick on, or back |
| `POST /timeline {"loop": [600, 900]}` | loops a stretch |
| `GET /timeline` | where it is: the tick, the length, the markers (the recording's journal), and `desync`, non-null if the playback parts from the recording |
| `POST /session/camera {"mode": "follow", "entity": "car"}` | the view: `scene`, `follow`, `entity` or `free` (`eye`, `target`, `fov`); `GET /cameras` lists the scene's |
| `POST /timeline/branch {"at": 900}` | takes over from tick 900; `"possess": [{"entity": "car", "client": "cl_1"}]` hands the car to a client at once, and `"file"` names the new recording |
| `GET /recordings` | the recordings beside this one, for choosing |
| `GET /metrics/speed/series?entity=car` | a metric's values over the run, for a graph (a per-trainee metric needs `entity`: without it the answer is a 400 that names the choices, such as `one of car, walker`) |

Or play a recording from the command line:

```sh
argus run . --replay runs/trainee-1.replay
```

## Done

That is the two-day path: a scenario, its rules, its score, the instructor and the review. What's next:

- **The training room:** [Training scenarios](TRAINING.md), "The training room".
- **Several trainees and observers:** [Netcode](NETCODE.md).
- **Other simulators over DIS:** the DIS plugin (`argus plugin info dis`).

