The question “how much pitch randomization is too much” sounds like it has a single answer. It has two, and they are not the same number. The first is the point at which the change becomes audible. The second is the point at which the jump stops reading as the same jump. The useful range for a platformer jump sits between those two thresholds, and most of the advice online conflates them.
The sections below work through both thresholds, the engine-level side effects that make the numbers harder to apply than they look, and the working ranges that hold up for a jump sound that fires hundreds of times in a session.
The JND Is the Floor, Not the Ceiling
The just-noticeable difference for pitch is the smallest change a listener can detect under controlled conditions. For complex tones — which is what a synthesized jump is, since it contains multiple harmonics — the discrimination threshold is commonly cited around 9 cents, roughly one-twelfth of a semitone, and it is relatively constant across pitch [reference:0]. Some sources put the best-case floor lower, around 4 cents under ideal conditions [reference:1], and others put the practical range at 5–10 cents for pure tones [reference:2].
The useful framing from one acoustic dissertation is a three-tier scale: a difference below 9 cents is an excellent approach to “inaudible,” a difference around 18 cents is a good approach, and anything at or above 19 cents is a poor approach to inaudibility [reference:3]. That is a threshold for detectability, not for identity.
A randomization range that stays below roughly 18 cents total (±9 cents) will be near-inaudible as a pitch change. But “inaudible as a pitch change” is not the goal. The goal is for the variation to be felt as non-identical without being heard as a different sound. That requires a range above the JND and below the identity threshold.
The Identity Threshold Is Where the Jump Stops Being the Jump
The identity threshold is harder to pin to a single number because it depends on what the sound is carrying. A pure tone can be shifted by a semitone and still be recognized as “the same tone, higher.” A complex, noisy, enveloped sound — like a jump — loses more identity per cent of shift, because the shift changes the relationship between its harmonics and its formant-like resonances.
The practical evidence from game audio practice converges on a
range of roughly ±2 to ±3 semitones. One
game-audio teaching text recommends that pitch randomization
“should not exceed more than 3 semitones,” and
specifically suggests a setting of 0 to 3
semitones as the working range, because larger shifts
make the sound “thin, short, and squeaky” at the high end and
“low, sluggish, and stretched” at the low end [reference:4].
Arma 3’s sound configuration exposes a
frequencyRandomizer that applies pitch
randomization “within 3 semitones (positive and negative)” as a
documented example [reference:5]. A commercial game-audio guide
reaches the same conclusion from the opposite direction: pitch
variation should be limited to within one octave if preserving
the original sound’s meaning is necessary, with the implication
that anything approaching that limit is already at the edge of
recognizability [reference:6].
For a platformer jump specifically, the working range is narrower than ±3 semitones, because a jump is a short event with a strong pitch contour. Shifting the whole contour by three semitones changes where the sweep starts and ends relative to the character’s other sounds, and the jump can start to read as a different move. A range of ±1 to ±2 semitones is enough to break exact repetition without crossing into “different jump” territory.
pitch_scale Is Resampling, and It Changes Duration as Well as Pitch
The engine-level complication is that the most common way to vary
pitch — multiplying a playback rate or pitch_scale —
does not shift pitch in isolation. In Godot 4,
AudioStreamPlayer.pitch_scale is documented as
resampling, not pitch shifting: it changes how quickly samples
are read, so pitch and duration move together
[reference:7]. A pitch_scale of 0.5 plays the stream at
half speed and one octave lower; a value of 2.0 plays it at
double speed and one octave higher [reference:8]. Unity’s
AudioSource.pitch behaves the same way.
For a jump, this coupling is usually acceptable at small values. A ±5% pitch shift shortens or lengthens the sound by about 5%, which for a 120 ms jump is roughly 6 ms — below the threshold where the duration change becomes a separate percept [reference:9]. At larger values the coupling starts to matter: a ±2 semitone shift (about ±12%) changes a 120 ms jump to 106 ms or 136 ms, and that difference can affect whether the jump’s tail collides with the landing sound.
The four-parameter jump diagnosis covers the duration side of that interaction; the pitch-side point is that a “pitch-only” variation is not actually pitch-only unless the engine uses a time-preserving pitch shifter, which is the more expensive option and is usually unnecessary for a short jump.
Randomizing pitch_scale Linearly Biases the Result Toward Higher Pitches
There is a second engine-level trap that is less obvious. If
pitch_scale is a multiplier, then choosing a random
number from a linear range between, say, 0.9 and 1.1 does not
produce a symmetric distribution in pitch terms. The midpoint of
the multiplier range is 1.0, but the midpoint in cents is not
1.0 — it is the geometric mean, which is slightly below 1.0 for
any symmetric linear range. Godot fixed exactly this bug in
AudioStreamRandomizer: the original implementation
picked a random pitch_scale linearly, and the fix
converted the range to log space before sampling, because
“pitch_scale is multiplicative, so picking a random number for it
without log conversion will bias it towards higher pitches”
.
A designer who samples randf_range(0.95, 1.05)
directly will get a distribution that is very slightly biased
upward, because 1.05 is further from 1.0 in cents than 0.95 is.
The bias is small enough that it is usually inaudible across a
few jumps, but it becomes measurable across a long session, and
the fix is simple: sample in cents (or log space) and convert
back to a multiplier. If the engine’s randomizer already does
this, use it rather than rolling a custom range.
Working Ranges by Use Case
The table below gives starting ranges for a jump sound and a few
adjacent cases. The values are in semitones, with the equivalent
pitch_scale multiplier in parentheses, because
engines differ in which unit they expose.
| Use case | Working range | What breaks above it |
|---|---|---|
| Platformer jump, subtle variation | ±0.5 to ±1 semitone (×0.97–1.03 to ×0.94–1.06) | The variation is inaudible; exact repetition remains |
| Platformer jump, clearly varied | ±1 to ±2 semitones (×0.94–1.06 to ×0.89–1.12) | The jump starts reading as a different move; duration coupling becomes noticeable |
| Footstep variation | ±1 to ±2 semitones | The footstep changes apparent size or material |
| Weapon fire variation | ±0.5 to ±1.5 semitones | The weapon changes perceived power |
| UI click variation | ±0.5 semitones or less | The click starts reading as a different UI state |
The ranges are deliberately narrow. A jump that varies by ±2 semitones already covers a span of four semitones between the highest and lowest instance, which is a major third — enough to be clearly heard as variation, and close to the point where the jump stops sounding like one sound. The controlled randomness guide covers the broader principle of setting ranges by the identity threshold rather than by the JND; the jump case is a specific application where the identity threshold is unusually tight.
What the Research Says About Pitch Shifting and Recognition
There is one more piece of evidence that supports keeping the range narrow. A study on sound variations in interactive systems found that pitch shifting especially slowed reaction times and decreased accuracy in identifying sounds, particularly for tonal sounds, and that 55% of participants reported that some modifications — pitch shifts and time stretches — altered the sounds so much that they “no longer felt familiar” [reference:11].
That is a reaction-time cost, not just an aesthetic one. A player who has to spend extra milliseconds identifying a jump as a jump is a player whose movement is slightly less fluent. The cost is small at ±1 semitone and grows with the range. For a sound that fires constantly, the cumulative cost is worth avoiding.
The same study found that flanging and time-stretching had less impact on recognition than pitch shifting, which suggests that if a designer wants variation but is worried about recognizability, a non-pitch variation (a subtle filter sweep, a short flanger) is a safer axis than a wider pitch range [reference:12]. The sound variation system guide covers the non-pitch variation options; the pitch-specific point is that pitch is the most identity-sensitive axis and should be varied last and least.
A Test That Separates “Varied” From “Broken”
The check that settles the range is not a listening test on a single sound. It is a comparison across instances.
- Render ten jumps at the current range and play them in sequence. If you can hear the range as a range — “that one was higher, that one was lower” — the variation is already at the edge of what a player will notice as variation rather than as inconsistency.
- Play the same ten jumps without looking at the screen. If any instance fails to read as “a jump,” the range has crossed the identity threshold for that listener. The failure is usually at the extremes, which is why the range should be set by the extreme, not by the average.
- Trigger the jump at the rate the game will produce it. A range that sounds acceptable at one jump per second can sound unstable at five per second, because the ear compares adjacent instances more closely.
- Check the duration coupling at the extremes. If the lowest-pitched instance is long enough to collide with the landing sound, the range is too wide for the available duration budget, even if the pitch variation itself sounds fine.
A jump that passes those checks has a range that is large enough to break exact repetition and small enough to preserve identity. That range is narrower than most “pitch randomization” recommendations suggest, because most of those recommendations are aimed at footsteps or weapons, where the identity threshold is looser. A jump is a short, contour-heavy event, and it tolerates less variation before it stops being a jump.