Skip to content

Blueprint Mutators

Blueprint mutators are pure functions that transform a LevelBlueprint before play begins. They compose via an ordered pipeline (specs.Aggregate), are factory-resolved from MutatorRegistry, and their parameters are frozen into the RunId hash for reproducibility.

MutatorKey ParamsEffect
NarrowMarginpct ∈ [0,1]Scales aperture heights down — tighter gaps
WideMarginpct ∈ [0,1]Scales aperture heights up — more forgiving
DifficultyCurveexp ∈ [0.1,5]Remaps gate difficulty by index — front-load or back-load
RhythmLockdiv ∈ {2,3,4,6,8}Quantizes gate phases to N divisions — rhythmic patterns
GateJitterstr ∈ [0,1]Deterministic vertical offset via sin() — spatial perturbation
SegmentBiasseg, amt, shapeDivides gates into acts with per-segment difficulty bias

Mutators are applied as an ordered fold: LevelBlueprint → LevelBlueprint. The pipeline processes each mutator spec in sequence, passing the output of one as the input to the next.

Since mutator parameters are frozen into the RunId hash, any change to the mutator pipeline produces a different RunId — ensuring replay integrity.

The SegmentBias mutator supports three difficulty distribution shapes:

ShapeNameFormulaBehavior
0Crescendod = 2t - 1Easy start → hard finish
1Valleyd = 8t(1-t) - 1Hard middle, easy ends
2Waved = (-1)^kAlternating easy/hard segments

Each shape distributes difficulty differently across the level’s segments, creating distinct play experiences from the same seed.

Every mutator has a MutatorId (stable string identifier) and MutatorSpec (id + parameters). The MutatorParam values are serialized canonically into the RunId hash using FNV-1a 64-bit hashing. This means:

  • Same mutator pipeline + same seed = same RunId on every platform
  • Changing any parameter produces a new RunId
  • Mutator order matters — different ordering produces different levels and different RunIds