# 1. Playtest Goals and Event Schema
Part of [[Playtest Telemetry and Heatmaps]]. Next: [[2. Telemetry Recorder and CSV Export]].
> [!warning] Code not compiled
> The schema struct below is shown again, complete, in part 2. Nothing in this series has been compiled in Unity.
## 1.1 Start from questions, not from data
Telemetry that logs "everything" produces a spreadsheet nobody opens. Write the questions first, on the board, before you add a single `Log` call. Good first questions for a class level:
| Question | Event you need | How you will look at it |
|---|---|---|
| Where do players die? | `death` with position and cause | Heatmap of `death` |
| Do players find the intended route? | `path` samples every 0.5 s | Path lines + `path` heatmap |
| Where do players get lost or stop? | `idle` when the player has not moved for N seconds | Heatmap of `idle` |
| How long does each section take? | `checkpoint` with id | Time between checkpoint rows in the CSV |
| Is the reward at the end of each "finger" found? | `pickup` with item id | Count per pickup id |
Rogers' *Level 13* rule (*"If it feels too long, hard, or boring, then it probably is"*) maps directly onto columns 1, 3 and 4: hard = deaths, long = time between checkpoints, boring/lost = idle. See [[Level Up! (Review)]].
## 1.2 What not to log
- **Nothing that identifies a student.** No names, emails, device serials or account IDs. The session id is a timestamp plus a random number. In a classroom, a tester's identity is the seat they sat in, written on paper if you need it.
- **No raw input streams.** You do not need every stick value; you need outcomes.
- **No per-frame rows.** Sample at a fixed interval (part 3). A 10-minute session at 2 samples per second is about 1,200 path rows, which is fine; at 72 fps on Quest it would be over 40,000.
## 1.3 One flat schema
Every row has the same nine columns. Flat CSV opens in a spreadsheet, a text editor, Python, or the Editor window in part 4, and survives being emailed or dropped into a shared drive.
```
session,time,scene,type,x,y,z,label,value
20261112-141502-4821,0.000,Level01,session_start,0.000,0.000,0.000,dev|0.3.1|Oculus Quest,0
20261112-141502-4821,12.503,Level01,path,4.210,0.000,-3.880,player,0
20261112-141502-4821,31.020,Level01,death,18.400,-2.100,6.050,SpikePit,25
20261112-141502-4821,44.700,Level01,checkpoint,20.000,0.000,9.000,CP_02,0
```
| Column | Type | Meaning |
|---|---|---|
| `session` | string | One id per app launch |
| `time` | float | Seconds since session start (unscaled, so pause menus and hit-stop do not distort it) |
| `scene` | string | Active scene name, so one file can span a level sequence |
| `type` | string | `path`, `idle`, `death`, `checkpoint`, `pickup`, `session_start`, `session_end`, ... |
| `x`,`y`,`z` | float | World position |
| `label` | string | Cause of death, checkpoint id, item id |
| `value` | float | Optional number: damage, health left, idle seconds |
Rules that keep it parseable:
1. **Invariant culture** for numbers. A laptop set to a German locale would otherwise write `4,210` and break every column (part 6).
2. **Quote** a text field only when it contains a comma, quote or newline, and double any quotes inside it (standard CSV).
3. **Append-only** files, one per session, named `session_<id>.csv`. Never rewrite an existing file; that way a crash loses at most one buffer.
## 1.4 Event names are a contract
Treat `type` and `label` strings like an API. Put them in one place so a typo in one script does not split "death" into "death" and "Death":
```csharp
namespace Playtest.Telemetry
{
/// <summary>
/// Canonical event type names. Use these constants instead of string literals.
/// </summary>
public static class TelemetryTypes
{
public const string SessionStart = "session_start";
public const string SessionEnd = "session_end";
public const string Path = "path";
public const string Idle = "idle";
public const string Death = "death";
public const string Checkpoint = "checkpoint";
public const string Pickup = "pickup";
public const string Teleport = "teleport";
public const string Custom = "custom";
}
}
```
`Teleport` is there for VR levels: [[VR Locomotion and Interaction Deep Dive]] can log each teleport destination, which turns a heatmap into a "where do people choose to stand" map.
## 1.5 Exercise
Pick one existing level (the gray-box from [[ProBuilder Gray-Boxing and Landmarks]] or the hazard course from [[5. Worked Example Spike Key Door Checkpoint]]). Write three questions you want a playtest to answer and the event type that answers each. Keep the list on the hub of your own project; part 5 checks against it.
Next: [[2. Telemetry Recorder and CSV Export]]