TinyGames · how it works

Rope Jump

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

The whole game is one question

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.

A pass is found, not noticed

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.

The window is the airtime

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.

No grace window

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.

The knees

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.


Three levels, one button

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.

The high hop

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.

Perfect

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.

The wall

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

What the tests actually assert

$ 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.


What the tests are worth

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.


Playing it

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.