| # | Time (s) | Window (frames) | ms |
|---|
23.2 - 81.8
Each input at L*: its pass probability p, the chance of reaching it
alive reach, and — since a run is scored on its own — times shown in both seconds and % of
the scored length. The weakest inputs (lowest p) are where the level fights back.
bits is the input's share of G (at G's reference precision) and time lost is its share of
T (at T's reference precision) — the same window costs far more time late in a run than early.
| # | Time (s) | Time (%) | Window | ms | p (pass) | reach | bits (G) | time lost (T) |
|---|
Each input i has a window of Nₕ frames, so its duration is
wₕ = Nₕ / fps seconds. A player with precision L (bigger = sharper;
L = 1/σ of their timing error in seconds) clears that input if their timing lands inside the
half-window, giving pₕ = erf( (½·wₕ·L) / √2 ).
Completion probability P(C) = ∏ pₕ. Reach probability
rₕ = ∏₃₂ₓₖ p₋. Expected time per attempt
E[T₉] = tₙ·P(C) + ∑ tₕ·rₕ·qₕ (qₕ=1−pₕ,
tₙ = level length), and expected time to complete E[T╕] = E[T₉] / P(C).
The tool bisects on L for L*, where E[T╕] equals your target time.
It also shows σ = 1/L* in milliseconds.
Histogram — you give counts per frame-window size; the tool assumes inputs are evenly spaced across the level and evenly interleaved by difficulty (no clustering). With modifiers off, the result depends only on the histogram, level length and target.
Manual list — you give each input's exact time and window, so ordering, gaps and per-input positions are taken directly from your data (nothing is scattered evenly). The Seconds / % switch reads times either as seconds or as a percentage of the level length, where % grows evenly across the level (50% = halfway in time).
Window FPS is the timing-window rate (wₕ = Nₕ/fps). Game FPS only converts
time positions when the Frames unit is selected. Respawn time is added to every attempt — because
∑rₕqₕ + P(C) = 1, it contributes exactly its own value per attempt.
A row's window may be - to mark it ignored: it passes automatically, though its time
position still counts toward attempt timing. With CPS enabled it instead takes one more than the run's largest
numeric window, matching the official calculator. The # column is the input number i, which
drives Fatigue (e^(−k·i)) and the local CPS numerator
(cₕ = (i − i′)/(tₕ − tₕ′)) — so non-consecutive numbering
models skipped clicks.
Fixed precision mode reverses the calculation: instead of solving for L*, it reports P(C), expected attempts and completion time at a precision you supply.
Turn on Calculate a run and give a range like 23.2 - 81.8 to score only the inputs inside
it. The slice is treated as its own level: its inputs are re-based so the run starts at 0 and its length becomes
to − from. The range is read in whatever the Seconds / % switch is set to.
Each enabled modifier multiplies an input's effective window before the probability is taken: Nerve
e^(−k·tₕ), Fatigue e^(−k·i), CPS
(4/max(1,2c))^k where c is the local clicks/sec from the gap to the previous input.
All three are off by default and use the calibrated constants published by the official NaNDL calculator
(k_t = 0.0016520833717346, k_u = 0.0002727763242154, k_c = 0.2784421686721826),
and remain editable for experimentation. CPS keeps a WIP tag because the official
calculator itself still describes that multiplier as work-in-progress and unreliable.
L* answers “how sharp must you be?” but it compresses an enormous range into a small
number and cannot be added: two levels played back to back do not have
L*₁ + L*₂. G fixes both by measuring difficulty in log space:
G = −log₂ P(C) = ∑ −log₂ pₕ (bits)
Physically it is the information content of one clean run — how many bits of luck a completion
costs. Expected attempts ≈ 2ᵍ, so one extra bit means twice the grind, everywhere
on the scale. Because logs add, G(A then B) = G(A) + G(B) exactly, and each input carries its
own gₕ (shown in the per-input breakdown), so any segment's difficulty is just the sum of its
inputs' bits.
G is measured at a reference precision you set — that is what buys the additivity, since a level's improbability depends on who is playing it. Respawn time does not affect G: it changes how long an attempt costs, not how improbable one is.
P(C) is a product, so G cannot tell where a hard input sits — a 1-frame window on the
first click scores the same as one on the last. The expected completion time can, because failures are weighted
by how far you got:
T = E[T╕] = tₙ + respawn/P(C) + ∑ costₕ, where
costₕ = tₕ·rₕ·qₕ / P(C)
Miss the first input and you lose a fraction of a second before retrying; miss the last and every failure
burns a whole run, and you only get there rₕ of the time. So costₕ — each
input's share of the total grind, shown in the breakdown's time lost column — climbs steeply toward the
end of a level. T has its own reference precision (default 200) since the times explode at lower ones.
The three measures answer different questions: L* “how sharp must you be?”, G “how improbable is a clean run?” (additive, position-blind), T “how long will this actually take?” (position-sensitive, not additive).
Import JSON / Export JSON exchange runs with the official calculator. A document carries the
frame-window rows plus gameFps, windowFps, respawnTime and
useFrames. Time positions given as frame numbers (useFrames: true) are converted to
seconds using gameFps, and rows with an ignored window ("-") are skipped and reported.
Key spellings are matched loosely, so gameFps, game_fps and "Game FPS" all
read the same.