Skip to main content

Module playtest

Module playtest 

Source
Expand description

A playtest runner: several named bots (Entrants) each play a stage K times from the same seeds, the game measures every try (Measure), and data-file Checks say per bot whether it succeeded about as often as the designer wants: ✓, ✗ too hard or ⚠ too easy.

run does it all. It is two halves, play_tries and judge, so a caller with threads can play seed ranges on threads of its own and judge them once: the report never depends on how the seeds were split. play_try plays one seed and keeps what a tool shows of a try besides: how many commands were applied, and the entrant’s record of it for replay (Entrant::record).

Every number is an integer, so a report is the same on every machine: a band compares successes * 100 with min * count, and the median of an even count is the lower middle value.

The checks are a flat list, or come from Targets: what each entrant should achieve on a stage of each of the game’s tiers, said once. Given a stage’s tier and the entrants that play, Targets::checks gives that stage’s checks. A game reads the file itself (the core does no I/O), over its own tier type:

(
    success: {
        "casual": [(measure: "won", min: Some(1))],
        "expert": [(measure: "won", min: Some(1)), (measure: "deaths", max: Some(0))],
    },
    bands: {
        Easy: {"casual": (min: 70, max: 90), "expert": (min: 80, max: 100)},
        Hard: {"casual": (min: 30, max: 50), "expert": (min: 50, max: 75)},
    },
    floors: {"casual": 20},
    medians: [(entrant: "expert", measure: "turns", want: Lower, than: "casual")],
)

Structs§

Band
A share of tries in percent, both ends inclusive.
Condition
A measure within bounds, both ends inclusive. A try missing the measure fails it.
EntrantTries
One entrant’s tries, in seed order.
Judged
A check and what it found.
MedianTarget
A Check::Median wanted wherever both entrants play.
PlayedTry
One try as play_try played it: what the checks read, how many commands were applied, and the entrant’s record of it, if it keeps one (Entrant::record). Build it with PlayedTry::new (ADR-0039).
PlaytestReport
What a playtest found. Its Display is the table people read; a game adds its own lines from the data.
Targets
What each entrant should achieve, over the game’s own tier type T (whatever its stages are labelled with). Targets::checks gives a stage’s checks from it.
Tried
One try of one entrant.
Tries
K tries from seeds seed to seed + count - 1 (those that fit in a u64), each stopped at turn turns if it hasn’t ended. Every entrant plays the same seeds.
UnknownEntrant
A check names an entrant that isn’t in the run. Build it with UnknownEntrant::new (ADR-0039).

Enums§

Check
A check of a run, kept as data.
Found
What a check found.
MedianVerdict
How a median compares.
PlaytestError
Why a playtest stopped. More reasons may come (ADR-0039).
RateVerdict
Where a share of tries falls against a Band.
Want
Which way a median should lean.

Constants§

UNFINISHED
How a try the turn limit stopped is written where an outcome would be.

Traits§

Entrant
One named bot as the runner plays it, over the stage definition S (the data a stage is built from).
Measure
A game’s measures of a try, watching it command by command.

Functions§

judge
The tries of every entrant (its name and its tries, in any seed order, in any number of parts) judged by checks.
play_tries
entrant plays stage once from each of seeds, each try stopped at turn turns: its tries in seed order.
play_try
entrant plays stage once from seed, stopped at turn turns: the try, the commands applied, and the entrant’s record of it (Entrant::record).
run
Every one of entrants plays stage as tries says, and checks judge their tries. A check naming an entrant not in the run fails before any try is played; a refused command stops the run.

Type Aliases§

Measures
The game’s measures of one try, by name. A success or a loss is a measure too ("won" 1 or 0), so every check reads measures only.