◀ 9.49.59.6 ▶

9.5 — Datasets: Insights from Playtest Data

All semester you have written playtest numbers into tables by hand — one row per section in 6.5, one row per beat in 7.7. Today the same table arrives as a file of 32 rows, and the habit becomes DATA SCIENCE: the move from "section 3 feels brutal" to "section 3 takes 12 of this file's 52 deaths, and the second run through it took 148 seconds where the first took 271."

In this lesson you will be able to answer“how do I find a pattern in a pile of data?”
Break It Down~10 min

Find a pattern in 32 rows of playtest numbers — and be able to say which of your questions the file can actually answer.

First, before anything else: cut that into parts small enough that you could look each one up on its own.

  1. Say what a row is and what a column is, before you read a numberwhat does this part do?Read: the numbered column table in the Concept Lab below, and the beat-granular table you filled in for 7.7
  2. Turn the hunch into a question that names its columnswhat does this part do?Read: the Socratic prompt in the Concept Lab below
  3. Filter: keep only the rows your question is aboutwhat does this part do?Read: Step 3 of the Build Lab below, and the 1-indexed list rules on the Exam Reference Sheet
  4. Aggregate: total the filtered rows, count them, dividewhat does this part do?Read: the pseudocode block in Step 3 of the Build Lab below
  5. Say what the number leaves out, before you act on itwhat does this part do?Read: the file-wide facts in the Concept Lab below — the three blank comments and the column that never varies — and the checklist question about what this file cannot answer

The order is the whole method: say what a row is, name the columns your question needs, filter to the rows that answer it, aggregate them into one number, then say what that number leaves out. None of the five is hard alone, and the last one is the one the exam keeps asking. A dataset only ever answers a question its columns were built to answer, and no amount of arithmetic gets around a column that was never recorded.

The test of a finished split: can you write your hunch down as a filter and a total before you open the file? "Section 3 feels unfair" is a feeling. "Total deaths, and total seconds, for the rows where section is 3" is a question a column can answer — and if you cannot write it that way, the file is not going to settle it either.

Your turn

Pick two of the parts above and say in one line what each one actually does.

Section 3 takes the most deaths of any section, and the column that says so is deaths. Before you act on that number: which single other column would you read next, and what would it change about the fix you chose?

The distance_to_boss_start column holds one value per section and never varies between the rows of a section. What can a column that never varies tell you about the runs inside that section — and what does that say about the question its name seems to promise?

Concept Lab ~15 min

Download the dataset. Grab playtests.csv — 32 rows and 14 columns. Every column is a variable: one thing somebody measured. Every row is one record: one run, by one tester. Open it in a spreadsheet and the row numbers down the left margin are the same ones the exam's 1-indexed lists use, so the file and the reference sheet count the same way.

#ColumnWhat it holds
1sectionWhich part of the cave, 1 to 6. Six of them here — and the six are NOT the five named sections of your own gauntlet
2run_idWhich run: R001 to R032, one row each
3player_idWhich tester: P01 to P08
4deathsDeaths on this run, every cause added together — the column "which section is deadliest?" is really about
5deaths_by_spikesDeaths on this run caused by spikes
6deaths_by_enemyDeaths on this run caused by an enemy
7deaths_by_fallDeaths on this run caused by falling
8time_secondsSeconds spent in that section on that run
9coins_missedCoins the tester saw and did not get
10jumpsJump inputs pressed — how busy the section kept them
11distance_to_boss_startThe same number on every row of a section, and never a different one. Check it
12completed_bossTRUE if the run finished, FALSE if it did not
13ratingThe tester's score for the run, 1 to 5
14commentThe tester's own words. Three rows have none

Five things that are true of the whole file, before you compute anything. One cause of death leads all the others, and it is the cause the comments shout about — but not by the landslide they imply, and no section's deaths come near a majority of the file. Most of the runs finished the boss. One section takes more deaths than any other, and half of those are spikes. Three rows leave the comment column empty, which is a fact about the data rather than a hole in it — a blank is a value you have to decide what to do with.

And one warning before you compare this with your own notes. The six sections here are not the five sections your gauntlet had. Yours were named in 6.5 — the gap, the climb, the spike run, the soft gate, the end. This file numbers six parts of a whole cave and names none of them. Decide what a row is a row of before you average it, or you will average two different things and call the result a pattern.

Socratic

The exam's dataset questions hinge on knowing WHICH column answers WHICH question. "Which section is deadliest?" uses deaths; "which section FRUSTRATES?" needs time PLUS rating. Why can the deadliest section and the most-hated section be different — and what would a designer do differently about each?

Build Lab ~20 min

Step 1 — eyeball then compute. Open the CSV in any spreadsheet tool (Numbers, Google Sheets). Predict three things from eyeballing, THEN compute them: total deaths per section (sort or sum), average time per section, and the completion rate (the completed_boss column: what fraction of the rows are TRUE?). A prediction next to a result is the whole scientific method in one spreadsheet — and the prediction is what makes a surprise visible instead of just a number.

Check your three predictions predict, then compute, then open this

Then compare. Every number here is two clicks away in your spreadsheet — what matters is which one surprised you, and why.

  • Deaths per section: section 3 is the deadliest at 12, and half of those are spikes.
  • Deaths by cause, whole file: 52 — 21 by spikes, 18 by enemy, 13 by fall. Spikes lead at 40%, which is still under half.
  • Completion rate: 25 of the 32 runs finished the boss — about 78%.
  • Average time per section: six numbers, not one — one per section, which is the point of a filter. Section 2's is worked in full in the key at the end of Step 3.

Step 2 — cross-tab questions. The interesting questions join columns:

  1. Do the sections with the most jumps also have the most fall deaths? (jumps beside deaths_by_fall, section by section)
  2. Do the rows that miss more coins rate lower? (coins_missed beside rating)
  3. Which section is slowest per death — the section's TOTAL time_seconds divided by its TOTAL deaths? Add up both columns for a section, then divide. A high ratio means people spent a long time there and rarely died: is that a good section or a boring one? Argue it.
  4. Of the runs that died to an enemy at least once, what fraction still finished the boss? (deaths_by_enemy above zero, then completed_boss)

Step 3 — aggregate like the exam. Work out the average time for section 2 the way the reference sheet makes you write it: a loop, a test inside it, and two counters. Two things the sheet does NOT give you: there is no AVERAGE function to call, and no one-line way to filter — you write the loop and the counters yourself, every time. And the sheet's lists start at 1, so column 1 is section and column 8 is time_seconds:

total ← 0
count ← 0
FOR EACH row IN runs
{
    IF (row[1] = 2)
    {
        total ← total + row[8]
        count ← count + 1
    }
}
average ← total / count

Check the loop against your spreadsheet — the four section-2 rows, the two counters they feed and the average they produce are in the key below. Then read the last line carefully, because it is the one line here that behaves differently on paper and in your game: on the exam / is real division even between two integers, so a total over a count comes back with its decimal intact, never as a whole number with the remainder thrown away. C# is the opposite — two ints divide and truncate — which is why your Unity code casts one side to a double.

Check your loop run it in the spreadsheet first

Then compare. If your counters disagree, the row you filtered on is the usual reason — column 1 is section, and column 8 is the time.

  • Section 2's four rows: 172, 133, 228, 199 seconds.
  • count finishes at 4; total finishes at 732.
  • average ← total / count is 183.0 — a decimal, because the exam's / does not truncate.

Checkpoint — before moving on, you must be able to:

Reference Docs

Need a deeper explanation? These pages cover the same concepts:

Next: 9.6 — Bias, Filtering & Fair Data

0/4 answered

Answers save on this device as you type. At the end of class, click Download and upload the file to the Canvas assignment.

Saved on this device only — the Dashboard tracks your progress.