TinyGames · how it works
One rope, then faster, then two. Tap to jump as it comes round, and keep going as long as your feet do. Tap twice for a high hop when the ropes come close.
Draft. It is built, compiled and tested like every other game, and it is not
on the hub: "draft": true in build/games.json keeps it off the cards, out of
the sitemap and without a readme page. Take the flag off when it is worth playing.
Open index.html. No build step, no dependencies, no images, no audio files —
the figure and the rope are drawn, and the beat is synthesised.
ropejump/
index.html markup, and the restart button
style.css the frame around the canvas
js/rope.js the rope's clock, the hop, the high hop, the knees and the schedule
- no pixels, no engine, no DOM
js/ropejump.js the playable layer: drawing, input, the beat
test-rope.js node test-rope.js
Were the feet up when the rope arrived?
The rope is a phase, in whole turns, advanced by speed * dt — never one step
per frame, so a 120Hz phone and a 60Hz laptop play the same game. It is at the
feet whenever the phase reaches due. A jump lifts the figure for AIR
seconds. A rope arriving inside that is cleared and counts one; a rope arriving
after the landing is a trip, and the run is over.
Three decisions fall out of that sentence, and each of them is where a game of this kind usually goes wrong.
advance() does not look at where the phase ended up after a tick and ask
whether a pass went by. It works out when inside the tick the rope arrives,
moves the figure to exactly that moment, and asks then. Otherwise a hop that
lands a millisecond before the rope is judged at the end of the tick, sixteen
milliseconds later, and the verdict depends on where the tick boundaries
happened to fall — which is to say on the frame rate.
There is no second number for "how early may you press", and none for "how
late". Pressing earlier than the airtime before the rope means landing before
it arrives, and that is a trip. Two numbers would let the picture and the
rule disagree — a figure drawn in the air being told it tripped, or one drawn on
the ground being told it cleared — and a player who sees that once stops
trusting the game. AIR is 0.28 s: what a real skipping hop takes, seventeen
ticks wide on a phone, and short enough that an ordinary hop can never outlast
the gap between two passes and clear both for one press. That job belongs to
the high hop, and to nothing else.
None, on either side: not a few milliseconds after landing that still count as
up, not a press just after the rope that still clears. The decision (2026-09-12)
is written at the verdict in advance(), where anyone reaching for one would
put it, and the mutation table has a mutant that puts one back — the window
sweep catches it. If the game ever needs to be kinder, AIR gets longer, where
everyone can see it.
Without a landing recovery, tapping as fast as possible is a strategy. So the
figure needs REST (0.08 s) on the ground before it can push off again — and a
tap that arrives in the air or in the crouch is not thrown away, it waits
and fires the instant the knees allow. Ignoring it would trip a player who was
keeping time for pressing, which is the one thing a timing game must never do.
REST was 0.06 s and went up on 2026-09-12 so that a masher's feet are down for
more than a fifth of every cycle (22 per cent, from 18). Measured with ordinary
hops, before the double tap existed: from a random phase at the one-rope stages
a masher lasted 4.6 passes on average and 21 at the luckiest alignment, and
afterwards 3.2 and 16. One figure went the other way and is recorded so nobody
rediscovers it: a masher who starts on the very first tick of a run got 9 jumps
where it got 6, because a chain of hops 0.36 s apart happens to sit on the first
rope's 1.11 s beat a little longer than a 0.34 s chain did. That is alignment,
not resistance — start one tick later and the number is different — and the
average is what the constant buys. Now that two quick taps make a high hop, a
masher is a chain of high hops with the feet down a quarter of the time, and
lasts 2.1 passes on average, 6 at most, and none at all from the first tick.
Level one is one rope, getting faster twice — 0.9, 1.05, 1.2 turns a second, fourteen jumps a stage — and never hard: the gap stays three hops wide, which is what a warm-up should do.
Level two joins the second rope at the speed already turning, half a turn
behind the first and turning the other way, so the pass rate exactly doubles on
that beat and nothing else changes. Then 1.3 and 1.4, sixteen jumps a stage.
What makes a stage hard is the gap between passes against the hop: after an
ideal press the feet are down AIR/2 after the rope and the knees ready REST
later, so the room to press for the next one is gap − AIR/2 − REST — 280 ms
with one rope, 197 ms when the second joins, 137 ms at 1.4, which is 3 ms a pass
short of AIR + REST and costs an ideal player 46 of the 140 ms in hand over
the row: felt, not fatal.
Level three slows the ropes to 1.0 and bunches them: the second rope trails
the first by PAIR, 0.30 s, so the two go under the feet as a double beat —
tick-tock, then most of a second of nothing. The pair is tuned between the two
hops. It is over AIR, so no ordinary hop can hold both ropes however it is
timed (just under would let one pressed in the last few milliseconds do it, and
a mechanic that works by luck teaches nothing). It is under HIGH_AIR by
0.15 s, which is the room the high hop gets.
A second tap within DOUBLE_TAP of the hop's start — 0.155 s — lifts the figure
higher and keeps it up HIGH_AIR, 0.45 s, 1.6 times as long; it lands into a
longer crouch, REST_HIGH 0.15 s. The window has to be under AIR so the
figure is still up to be lifted, and short enough that no press meant for the
next rope is ever taken for a double: the shortest gap in the whole table is
0.271 s, and the window closes six ticks before it. It is 0.155 and not the
round 0.15 because 0.15 is exactly nine ticks at 60Hz, and a press lands on the
rules' clock at a tick: nine ticks after the hop, "within 0.15" was being decided
by float noise, both ways. It is measured from the hop's start, so a tap that
had to wait for the knees still gets its double, and a second press while a tap
is waiting makes the waiting hop high.
A high hop holds both ropes of a pair exactly when it starts inside the last
HIGH_AIR − PAIR = 150 ms before the first of them: nine ticks, half the
ordinary window. That is the level-three skill and it is meant to be half as
forgiving. A pair can also be taken as two ordinary hops if the first is
pressed at least AIR + REST − PAIR = 60 ms early, so that the knees are ready
before the second rope — that is the rhythm player's route and it is allowed;
the high hop is the late press's. On the opposite ropes of level two a high hop
holds two passes only if it starts within 33 to 93 ms of the first, so the
ordinary rhythm stays the natural way there, and a high hop taken at the
ordinary moment lands, rests, and is still down when the second rope comes. It
is a tool for the pair, and a player who reaches for it everywhere learns that
in level two. The count is per pass cleared, never per hop: a high hop over two
ropes scores two.
The trail stays 0.30 s as level three speeds up — 1.0, 1.25, 1.5, 1.75 — which is what a second turner a beat behind the first does, and it means the ropes open out: at 1.75 the trail is more than half a turn and the beat is nearly even again, at three and a half passes a second, which nothing but a high hop taking two at a time survives.
A cleared pass with the top of the hop within PERFECT of the rope — 0.05 s,
three ticks either side, a band of six out of the seventeen the window has — is
perfect and counts twice. One bonus point, not a streak: the count going up by
two is a thing the player already understands, and it needs no second readout
and no rule for losing it. The count that drives the schedule is passes
cleared; the score shown is that plus the perfects. A perfect is decided about
the hop as it was when the rope came — a hop doubled after the rope had passed
was an ordinary hop for that rope — and a trip is never perfect.
A high hop a turn needs the turn to be at least HIGH_AIR + REST_HIGH, 0.60 s.
At 1.75 it is 29 ms short, so the latest possible start slips 29 ms a turn and
the 75 ms a player pressing in the middle of the window has in hand go in three
turns. The ordinary rhythm gave out a row earlier: at 1.5 the two-hop route
round the pair is 53 ms a turn short. So the rhythm alone reaches the 1.5 row
and ends five passes into it, at 127, and the double tap reaches the last row
and ends six passes into it, at 144 — about 80 seconds either way. Nothing is
past that: a row above 1.75 is never reached, and the table ends at the wall
rather than pretending there is something behind it.
level one 0.9 1.05 1.2 turns/s 14 a stage
level two 1.2 1.3 1.4 opposite 16
level three 1.0 1.25 1.5 1.75 0.30 s behind 16
$ node test-rope.js
157 passed, 0 failed
Against the shipped, minified js/rope.js, in the house style: properties over
many seeded runs, an independent reference, and a negative control.
| property | how it is checked |
|---|---|
the window is exactly (T − AIR, T) |
from a standing start at every row, pressing before each tick in turn; the presses that clear must be one unbroken block ending at the pass, at 1/60, 1/61 and 1/97 s steps |
| a press in the middle never trips, too early or too late always does | the same sweep |
a double tap holds a pair exactly when the first press is in (T2 − HIGH_AIR, T1], two ordinary hops exactly when it is by T2 − AIR − REST, one ordinary press never |
the same sweep at every level-three row, first press before each tick and a second on the tick after, or 0.2 s after |
| landing on the rope is a trip | float-exact halves and whole seconds at the row that turns at exactly 1.0 |
| a stage lands one pass after it is announced | both ideal players through the table |
| the cadence exactly doubles at the join; at level three it becomes the pair and the rest of the turn | measured between passes, and from passGap() |
| the rhythm player ends on the row before the last, the double-tap player on the last, each within a dozen passes; the climb is 130 to 160 | the ideal players |
| the same presses give the same run at 30, 60 and 120Hz | forty double-tap scripts, three rates |
the waiting tap fires at AIR + REST exactly, high if it was doubled |
through settle() and through advance() at three step sizes |
a press exactly AIR / 2 before the rope is perfect, one PERFECT and a hair beyond is not, a hair inside is, a high hop about its own middle, never on a trip |
ten exact steps to the press, at every row |
| mashing loses | every tick pressed, from the start, from the builder's six phases at every one-rope stage, and from two hundred phases a stage |
| the constants hang together | PAIR between the two hops with nine ticks to spare, the double-tap window under AIR and six ticks clear of the shortest gap and off the tick grid, both mashers' feet down more than a fifth, stages twelve to sixteen long, two or three boosts in level one, level three no faster than level two ended, the last row's turn under a high hop and its landing |
The independent reference is the same rules in the opposite shape: hops as
an event chain built from the press times with no dt anywhere — a press on
the ground starts a hop, one inside the window doubles it, one in the air after
that or in the crouch waits and starts a hop when the knees are ready, doubled
if a second came while it waited — pass times as a running sum over whole
turns, the stage in force as a table lookup on the pass count with no pending
flag, and a hop as an interval [start, start + airtime) that a pass either
lies inside or does not. Four hundred scripted runs — both ideal players'
presses moved, dropped and doubled with a different sloppiness per script, plain
random tapping, and a hundred nearly ideal scripts with a few presses nudged by
a tick or three and every other one given a real slip in its second half, so
that the fast rows, the pair and the wall are reached — are played by the tick
machine and judged by the reference, and the two agree on cleared, perfect and
passes for every one.
Eleven of those scripts are set aside, and the reason is worth knowing. Random
tapping turns into a chain of hops exactly AIR + REST apart, and with every
number in the game rational, such a chain meets a pass time exactly: the first
script the suite found had a hop ending at 10/3 s and a pass at 3/0.9 s. Which
side of that a float lands is not a property of the rules, so ties are detected
and counted rather than argued with — and the edge itself is pinned separately
with numbers that do not round. A press at the instant the knees are ready is
not a tie: either side of it, the same hop starts at the same moment.
Twenty-six mutants: the shipped file with one function replaced, one constant moved or the table bent, each put through the whole suite. Twenty-five change a rule and every one is caught; the twenty-sixth changes nothing and passes.
| mutation | result |
|---|---|
| the knees never rest | caught |
| a waiting tap is forgotten | caught |
| the waiting tap fires at touchdown, skipping the crouch | caught |
| a high hop rests only as long as an ordinary one | caught |
| a tap in the air after the window lifts the figure again at once | caught |
| a tap in the crouch is dropped instead of kept | caught |
| a second tap while one waits does not double it | caught |
| feet on the ground count as cleared | caught |
| the verdict is taken at the end of the tick, not at the pass | caught |
| a stage lands the moment it is announced | caught |
| the schedule never advances | caught |
| the second rope is ignored | caught |
| the second rope always opposite, whatever the row says | caught |
| landing on the rope counts as clearing it | caught |
| a landing up to 40 ms before the rope is forgiven — a grace window | caught |
| a perfect is awarded on a trip as well | caught |
| the count is per hop, not per pass | caught |
REST back to 0.06 |
caught |
DOUBLE_TAP is zero |
caught |
PERFECT covers the whole hop |
caught |
| the close pair's gap under an ordinary hop's airtime | caught |
passInterval ignores the rope count |
caught |
passGap: both gaps half a turn, whatever the offset |
caught |
| the second rope a quarter turn behind, whatever the row says | caught |
stageOf always the first stage |
caught |
advance wrapped, behaviour unchanged |
passes, as it should |
The landing-on-the-rope mutant survived the first version of the suite: it only
differs at an exact tie, and the cross-checks set ties aside. A mutant the suite
cannot kill is a rule the suite does not test, so the edge got its own test with
numbers chosen so nothing is rounded. The grace-window and REST mutants came
with the 2026-09-12 retune, and the double-tap, perfect and pair mutants with
the three-level design of the same day, so that every decision recorded above
is one the suite would notice being undone.
One button. Tap anywhere, or Space; tap twice, quickly, for the high hop.
Escape or P pauses, M mutes, and sound is also in the settings sheet. The
rope starts at the feet and the first pass is a whole turn away, so you see one
complete swing before there is anything to do. Every pass makes a soft tick —
one pitch for the first rope, a lower one for the second — because the ear times
this better than the eye; a perfect pass rings, and says so over the figure's
head. Level three's first row keeps "tap twice to jump high" in the band, which
is the one time the double tap is explained.
There is no resume. A run is one unbroken stretch of rhythm with no moment a player could sensibly be handed back to.
Advertisement