Frogger's Turtles Only Vanish for a Quarter of a Second
Halfway across the river in Frogger, the turtles look like the safe choice. They are wide, they are slow, and they stay in a neat line. Then one group of them sinks with your frog on its back, and you learn to distrust them.
The diving turtles feel like a trap that springs at random. The original 1981 program says otherwise. The dive runs on a fixed clock, it is always the same group in each lane, and the moment that actually drowns the frog is far shorter than it looks: 16 frames, about a quarter of a second, in every 4.2 seconds. This article walks through how the original code does it.
What you see
Two of the five river lanes are turtles. The second lane from the top carries pairs, and the lane nearest the middle strip carries groups of three. Most of the turtles paddle along with nothing to worry about. In each lane, one group behaves differently:
- Its shells change colour.
- The turtles disappear, leaving only a ring of ripples where they were.
- The water is empty.
- The ripples come back, then the coloured shells, and finally the group rejoins the others, paddling as if nothing happened.
It is easy to read steps 2 to 4 as "the turtles are under water", and to jump off as soon as you see ripples. The code reads it differently.
A clock, not a dice roll
Each turtle lane has its own counter, and the game adds to both of them every time it draws the screen, about 60.6 times a second. The counter for the pairs goes up by one each frame and rolls over to zero after 255, so its cycle is 256 frames, about 4.2 seconds. Nothing random is involved, and almost nothing you do changes it. Losing a frog on the road or to the timer does not touch it, and clearing a level starts it again from zero. The one exception is drowning, which comes up below.
The code that draws the diving group just compares that counter with a handful of fixed values:
| Counter | What you see | How long | Safe to stand on? |
|---|---|---|---|
| 0 to 79 | Paddling with the others | 80 frames, 1.3 s | yes |
| 80 to 127 | Coloured shells | 48 frames, 0.8 s | yes |
| 128 to 159 | Ripples | 32 frames, 0.5 s | yes |
| 160 to 175 | Empty water | 16 frames, 0.26 s | no |
| 176 to 207 | Ripples | 32 frames, 0.5 s | yes |
| 208 to 255 | Coloured shells | 48 frames, 0.8 s | yes |
So a frog riding the ripples is on solid ground as far as the game is concerned. The only frames that drown it are the 16 when the water is completely empty.
The threes dive twice as often
The lane of threes uses a second counter that goes up by two each frame, so it goes through its whole routine twice in the time the pairs take once. Everything is squeezed to match: about 0.4 seconds of coloured shells, a quarter second of ripples, and only 8 frames, about an eighth of a second, of empty water, then the same in reverse. After that, the group paddles normally for almost a second before diving again.
Because both counters start together and one runs exactly twice as fast as the other, they stay locked in step. Every second time the threes go under, they do it in the middle of the pairs' gap. For 8 frames in every 256, both diving groups are gone at once. That holds from the start of a level until the first time the frog drowns.
How the game drowns you
You might expect the code that checks the frog to know about turtles. It does not. For each lane the frog can be in, the game keeps a short list: how many things are in the lane, then where each one is. Every frame it looks up the frog's lane, walks through the list, and asks whether the frog overlaps any of them. In the river, no overlap means the frog is in the water.
The diving group is always the last entry in its lane's list. So when the dive code draws the empty water, it also raises a flag, and while that flag is up the game does something blunt: just before the frog check, it takes one off the count at the front of the list.
ld a,(under) ; is the diving group under water?
and a ; (set the zero flag if not)
jr z,check ; not under: skip straight to the check
ld a,(count) ; how many groups in this lane's list
dec a ; say there is one fewer
ld (count),a ; so the check never reaches the last one
call check_frog ; check: is the frog on anything?
Straight after the check it adds the one back. The turtles are not removed from anything, and no position changes. The check just stops one entry short, so a frog standing on the last group is standing on nothing.
The full routines, with addresses, are on the diving turtles page.
Drowning restarts the pairs
There is one thing that resets the clock in the middle of a level. When the frog dies in the river (the code makes no difference between a dive and a missed jump), the game plays a different death sequence from the one on the road, and the last step of that sequence sets the pairs' counter back to zero. It does not touch the threes' counter.
Two things follow. After a drowning, the pairs always start a fresh cycle: the new frog appeared with the counter at 16, so the diving pair would next be gone 144 frames later, about 2.4 seconds. And the two lanes are no longer in step, so the pairs and the threes stop vanishing together until the next level.
Same group, every time
Because the diver is defined as "the last group in the list", it is always the same group of turtles in each lane, all level long. What changes from level to level is how many safe groups surround it. The game has five lane layouts and moves to the next one each time you clear a level, starting over after the fifth:
| Level | Groups of pairs | Groups of threes |
|---|---|---|
| 1 | 4 | 4 |
| 2 | 5 | 3 |
| 3 | 4 | 3 |
| 4 | 3 | 3 |
| 5 | 3 | 2 |
In each layout there is exactly one diving group per turtle lane, and the dive timing never changes: the counters always step by one and two a frame, and the empty-water stretch is always 16 and 8 frames. The turtles get scarcer in later levels, not quicker to dive.
Watching the counters
All of the above comes from reading the program, so the original code was run under a test script that started a game and recorded its memory on every frame. Over 3,843 frames of play on level 1:
- the pairs' counter went up by exactly one every frame, and the threes' counter was always exactly twice it, rolling over at 256;
- the "under water" flag for the pairs was up for 240 frames, every one of them with the counter between 160 and 175;
- the flag for the threes was up for 240 frames too, 8 at a time, and both flags were up together for 120 of them.
Then the script put the frog straight onto a turtle group at a chosen moment and watched for the game's "frog is dying" flag:
| Where the frog was put | When | Result |
|---|---|---|
| Diving pair, coloured shells | counter 88 | carried through the shells and the ripples, then died on the frame the counter reached 160 |
| Diving pair | counter 162 (empty water) | died on the next frame |
| Other pairs in the lane | counter 162 | carried along, unharmed |
| Diving pair | counter 175, the last empty frame | survived: by the next check the ripples were back |
| Diving pair | counter 176 (ripples) | carried along, unharmed |
| Diving threes, coloured shells | start of a dive | carried until the water emptied, then died |
| Other threes in the lane | while the diver was gone | carried along, unharmed |
| Diving pair, left to drown | counter 162 | the pairs' counter went back to 0 during the drowning; the threes' counter kept going |
Clearing level 1 gave level 2's layout, five groups of pairs and three of threes. There the last group in each lane drowned the frog at the same counter values, and the pair beside it did not.
What it means at the controls
- Ripples are safe. As long as you can see ripples or coloured shells, the frog is riding something.
- On the way down, the ripples of the pairs last about half a second, and those of the threes about a quarter of a second, before the water empties.
- The water is never empty for longer than 16 frames. A frog that lands on the diving group while it is gone drowns at once, but waiting a quarter of a second is always enough for it to come back.
- The rhythm is fixed. The pairs go under once every 4.2 seconds and the threes twice in the same time. Only a new level, or a drowning for the pairs, restarts the count.
Credits and further reading
- The MAME team, the Galaxian family driver in MAME 0.289, for the hardware description and the ROM list used to verify the original Konami program.
- Lawrence Kesteloot, z80-disasm, the disassembler used to read the program.
- The research notes behind this article, with every address and the full measurement tables, are on the diving turtles page of the Frogger case study.