Why Galaga's Bees Stop Shooting
Anyone who spent time around a Galaga cabinet has heard of the trick. On the first stage, shoot everything except the bees in the bottom left corner. Then dodge them. Keep dodging while they swoop down, fire, and loop back up, for something like fifteen minutes. Eventually they stop firing. Shoot them, and for the rest of the game no enemy fires a single shot. You can play on for as long as you can stay out of their way.
It sounds like a cheat code, the kind of thing a programmer would hide on purpose. It is not. It is what happens when one bullet out of every few hundred lands on the one position the game treats as "not there", and the game has room for only eight bullets.
This article follows an enemy bullet through the original 1981 program, the code that ran on the arcade boards, and shows where it gets lost. It also looks at a later revision of the program that Namco shipped, which quietly closes the hole with four extra bytes.
Three processors sharing a desk
Galaga's circuit board has three Z80 processors, the same chip that ran Pac-Man, all reading and writing the same block of memory. Think of three clerks at one desk with a shared notepad. The main processor runs the game: your ship, your shots, the score. A second processor flies the enemies along their swooping paths and decides when they shoot. The third plays the sound.
An enemy bullet passes between two of those clerks. The second processor creates it. The main processor moves it down the screen every frame and throws it away when it leaves the screen.
Eight slots
The game keeps exactly eight places for enemy bullets, eight slots in that shared memory. Each slot is either free or holds a bullet in flight. When an enemy decides to fire, the enemy processor looks through the slots for a free one:
ld hl,$8868 ; the first of the eight enemy bullet slots
ld b,8 ; eight to check
ld a,(hl) ; look at this slot
cp $80 ; $80 means free
If it finds one, it marks it taken and copies the enemy's position into it, so the bullet starts where the enemy is. If all eight are taken, the enemy simply does not fire. There is no error and no waiting. That shot just never happens.
This is normal. On a busy stage all eight slots fill up for a moment and some enemies miss their turn. A slot comes free again as soon as its bullet falls off the bottom of the screen.
The number zero
Each bullet's position across the screen is a single byte, a number from 0 to 255, growing from left to right. Your ship is kept between 17 and 225.
The game uses one of those numbers as a signal: position 0 means "this object is not on the screen". The hardware draws anything at 0 outside the visible picture, and the code that handles objects can use 0 as a quick test for "not in use".
The routine that moves enemy bullets does exactly that. Every frame it goes through the eight slots and nudges each bullet along. When a bullet's position is 0, it skips it. The bullet is not shown, so why move it?
The routine that throws bullets away has a different test. It frees a slot when the bullet has left the screen: off the top or the bottom, or at position 244 or more, off the right-hand side. A bullet at position 0 is inside the top and bottom and not past 244. As far as this check is concerned, it is still on the screen.
So a bullet at exactly 0 is never moved, because the mover thinks it is not on screen. And it is never freed, because the cleaner thinks it is. Since it never moves, nothing about it ever changes. It sits in its slot, invisible, for the rest of the game.
How a bee gets to zero
A bullet starts at the position of the enemy that fires it. So for this to happen, a bee has to fire at the exact moment it is at position 0.
The bees at the bottom left of the formation dive out to the left. Their loops take them right off the edge of the screen, and as they go their position counts down: 3, 2, 1, 0. The next step is not -1, because a byte has no negative numbers. It wraps around to 255, then 254, and so on. A bee swinging out past the left edge looks, to the game, like it jumped to the far right.
That wraparound is why only 0 is dangerous. A bee that fires a frame later, at 255, makes a bullet the cleaner sees as past the right-hand edge, so it is thrown away right away. A bee that fires a frame earlier, at 1, makes a bullet that the mover handles like any other. Only a bullet made in the one or two frames the bee spends at exactly 0 slips through both checks.
That takes luck. Two bees left alone on the first stage passed through position 0 forty-one times in three minutes, and only four of those visits lined up with a shot. But the bees have all the time in the world, and the player only has to survive.
Each stuck bullet takes one slot. After eight of them there are no free slots at all. Every bee that wants to fire is turned away, and nothing ever frees a slot again, not even a new stage. That is the trick.
Four bytes
The Galaga set that MAME treats as the main version is a later Namco revision, labelled rev B. Its chips carry a "b" in their names. In that program, the mover's "skip this bullet" path does one more thing before moving on:
ld h,$88 ; point at this bullet's slot
ld (hl),$80 ; and mark it free
inc l ; then on to the next bullet, as before
A bullet at position 0 still is not moved, but its slot is handed back straight away. The bullet that would have been lost is simply cancelled.
Chris Cantrell's annotated listing of the earlier program, published on his Computer Archeology site, has the same routine without the first two lines: it skips the bullet and moves on, nothing more. The rev B version is four bytes longer, and everything after it in that chip sits four bytes further along. Cantrell found the bug by reading that earlier code, and proposed his own fix in a different place, by nudging a bullet made at 0 to 1 when it is created.
Waiting for the bees
Reading code is one thing; watching it run is better. The rev B program was run under a test script that made the player's ship indestructible by turning off the check that destroys it. When the ship is hit, the game also stops enemies firing for a while; with no hits that never happened, and firing otherwise worked as normal. The script shot every enemy except the two bees at the far left of the bottom two rows, then parked the ship at the right edge and logged every bullet created, every bullet made at position 0, and every slot freed.
The same scenario ran twice: once with the rev B program as it is, and once with its four new bytes replaced by instructions that do nothing, which makes the routine behave like the older listing.
| Rev B as shipped | Four bytes disabled | |
|---|---|---|
| First bullet made at position 0 | after 22 seconds | after 22 seconds |
| What happened to it | freed in the same frame | freed anyway, by a fluke (see below) |
| Second one, after 54 seconds | freed in the same frame | stuck |
| All eight slots stuck | never | after 11 minutes |
| Bullets fired after that point, still on stage 1 | bees kept firing | none |
| The next 8 minutes, after shooting the two bees | 378 bullets, stages 2 to 13 | none at all, stages 2 to 6 |
With the fix in place, the two bees fired 1,114 bullets over half an hour of game time. Thirty-one of them were made at position 0, and every one was freed in the same frame it was made. Not once was a slot left stuck.
With the fix disabled, the bullets made at position 0 came at the same moments, because the bees fly the same way either way, at least until the slots began to run out. Eight of the ten that came before the end stayed stuck. Two were cleared by the throw-away check after all, apparently because that check reads a copy of the positions that can still hold the previous bullet's last position for a moment. That detail was not traced further. Either way, the eighth slot filled eleven minutes in, and the game went quiet for good.
Eleven minutes is shorter than the fifteen or so players talk about. In the test the ship sat still at the far right and could not be hit, which is not how a person plays, and how quickly the bees line up with zero depends on their loops. The order of events, though, is exactly the story players tell.
Which machines have it
The program studied here, rev B, has the fix. In half an hour of play, its bees never stopped firing. According to Cantrell, the trick works on the earlier program he studied. According to Muse, who brought a Galaga recreation to the MEGA65 computer, the earlier Namco and Midway "set 1" programs have the bug, and Namco's rev B and Midway's "set 2" fixed it after the trick became widespread in arcades. Muse adds that they rarely found a rev B or set 2 machine where the trick no longer worked, which this article cannot explain. Neither the older Namco sets nor the Midway ones were run here.
So the trick that made Galaga famous among players is not a secret door. It is a single number that means "nothing here" to one part of the program and "something here" to another, eight places to keep bullets, and enough patience to fill them all.
Credits and further reading
- Chris Cantrell, Galaga No-Fire Cheat on his Computer Archeology site, with annotated listings of the three processors' programs. The first explanation of this bug from the code, and the source for the older program's version of the routine. The same work appeared in print as "Debugging Commercial Code: A Quick Fix for Galaga Code", Circuit Cellar issue 184, November 2005, not consulted here.
- Muse (sho3string), GalagaMEGA65, whose notes say which program revisions have the bug and how common the fixed boards were.
- The MAME team, galaga.cpp
and
galaga_v.cpp, for the ROM list, the memory map and how sprite positions are drawn. - The full research notes, with addresses and measurements, are on the enemy shots page of the Galaga case study.