When Dave Jones of DMA Design wrote Menace for the Amiga, he gave every alien a collision box the size of its sprite, 32 by 24 pixels. Then he noticed what that did to the small aliens. A missile could enter the box, register a hit and destroy an alien that, on screen, it had plainly missed. His fix, he told Amiga Format readers in 1990, was to “store a collision box size for each alien”; the small one in his example “would suit a box of 24 x 18 better.”
That is a hitbox: the invisible shape a game tests instead of the picture the player sees. Almost every hitbox in the period was a rectangle, because a rectangle can be tested with a handful of comparisons. Its size and position are a design decision as much as a programming one. Too large and the player dies from bullets that missed; too small and shots pass through enemies. The arithmetic of testing boxes is covered in Collision Detection. This entry is about choosing them.
Fast facts
- What it is: a rectangle, usually smaller than the sprite, stored as offsets from the sprite’s position.
- Why not the pixels: testing every pixel costs far too much, and the C64’s hardware collision register reports which sprites touched something, not which touched which.
- Per-object sizes: a box for each kind of object, kept in a table, so a big ship and a small bullet each get a fair box.
- Per-frame sizes: some games stored a box for every animation frame, so the box changed as the character moved.
- Deliberately small: bullet-hell shooters shrank the player’s box to a small part of the ship, which is what makes their dense bullet patterns survivable.
A box for each kind of object
A box is two corners. Jones put it plainly: “A box only needs two coordinates, the top left and bottom right. If two boxes overlap then we flag a collision.” It is rough, he admitted, because “not many aliens appear as a box shape”, which is why the box’s size matters.
On the C64, Achim’s Codebase64 article makes the same point. One box size for every sprite works “as long as all sprites in the game have a similar size. But with different sprite sizes (e.g. a big space ship and a small bullet) it’s better to work with individual boxes.” His version keeps four offsets for each sprite in a table. In his worked example the box starts 3 pixels below the sprite’s top and is 12 pixels tall, and runs from 8 to 16 pixels across: a small target in the middle of a 24 by 21 sprite.
C64 sprites can sit at X positions above 255, which needs a ninth bit. Achim suggests the “2*x trick”: store X positions halved, so every edge fits in a byte and plain comparisons will do. A routine in that style builds each object’s box from its type, then tests it against the player’s:
; Build object X's box from the table entry for its type, in Y.
; X coordinates are stored halved (0-159), so every edge fits in a byte.
makebox:
lda obj_x,x
clc
adc box_x1,y
sta box_left,x
lda obj_x,x
clc
adc box_x2,y
sta box_right,x
lda obj_y,x
clc
adc box_y1,y
sta box_top,x
lda obj_y,x
clc
adc box_y2,y
sta box_bottom,x
rts
; Does object X's box overlap the player's (object 0)?
; Returns with carry set for a hit, clear for a miss.
hittest:
lda box_right ; player's right edge
cmp box_left,x ; left of the enemy's left edge?
bcc miss
lda box_right,x ; enemy's right edge
cmp box_left ; left of the player's left edge?
bcc miss
lda box_bottom ; player's bottom edge
cmp box_top,x ; above the enemy's top?
bcc miss
lda box_bottom,x ; enemy's bottom edge
cmp box_top ; above the player's top?
bcc miss
rts ; carry is set: the boxes overlap
miss: clc
rtsEach cmp sets the carry when the first number is at least as large as the second, so the test gives up at the first pair of edges that are apart, and boxes that share an edge count as touching. With Achim’s offsets, the player’s entry in the table is 4 and 8 for X (his 8 and 16 pixels, halved) and 3 and 15 for Y.
Why not let the hardware do it?
The C64’s video chip will report sprite collisions by itself, pixel by pixel, in register $D01E. But a 1985 guide to arcade game programming on the machine warned that the register “will only tell you which sprites are involved in collisions, not which sprite hit which sprite. If you are multiplexing sprites, the data in the SSCOL register may be useless”, because one hardware sprite may be showing several objects in a frame. It also cannot be made smaller than the drawing. Codebase64’s article on the hardware method concedes that “with most games these days, $D01E is very useless, therefore a software collision is used.”
The Amiga’s hardware can also detect collisions, and Jones used it for the player’s ship in Menace. For missiles against aliens he used boxes, with two shortcuts. A missile was too small to need a box of its own, so “only one coordinate at the tip of each missile was checked”. And because twelve aliens against eighteen missiles “would mean checking every missile against every alien = 216 checks”, he first used the blitter to ask whether any missile had touched any alien at all, and only then worked out which.
A box for each frame
A character that crouches, kicks or stretches changes shape, and a fixed box fits some poses badly. One answer is a box for every image. The source code of id Software’s Keen Dreams (1991), released in 2014, shows how. Each sprite image in the game’s graphics file carries its own hit rectangle, four values xl, yl, xh and yh, alongside its size. Every time an object moves, the game reads the rectangle for whatever image it is showing at that moment, so the box follows the animation. Objects whose rectangles overlap call each other’s contact routine.
Small on purpose
The most deliberate hitboxes belong to shoot-’em-ups. James Greenhalgh of the site Shmups.com explained to Retro Gamer in 2007 that the old rule, “when a bullet touching your ship in any way meant death”, could not work in shooters that fill the screen with bullets. So designers “reduce the size of the hit-box, the area of the player sprite that can collide with bullets, and even reduced bullet hit-boxes themselves. You can’t reduce the sprites to those sizes; it would just look like tiny specks on the screen.” Some games turned the gap between sprite and box into a scoring system, rewarding the player for “grazing” bullets.
Modern games keep the idea and the name, though not always the box. Wireframe noted in 2019 that “hitbox” is “actually a bit of a misnomer, because they come in more shapes than just boxes”: first-person shooters build characters’ hitboxes from spheres and capsules fitted to the skeleton.
Sources
- Dave Jones, games programming series, part on collision detection in Menace, Amiga Format issue 12, July 1990, pp. 156–158: boxes from two corners, the 32 × 24 and 24 × 18 boxes, the single point at the missile’s tip, 216 checks, and the blitter test.
- Achim, “Individual sprite ‘boxes’ for collision detection”, Codebase64 (web): per-sprite offset tables, the worked example and the “2*x trick”. https://codebase64.net/doku.php?id=base:sprite_collision_detection
- Commodore 64 Assembly Language Arcade Game Programming (TAB Books, 1985), p. 32: what the sprite collision register does and does not tell you.
- Commodore, Commodore 64 Programmer’s Reference Guide (1983), pp. 144–145: the sprite collision registers.
- Richard Bayliss, “Sprite/Sprite hardware collision”, Codebase64 (web). https://codebase64.net/doku.php?id=base:simple_hardware_sprite_to_sprite_collision
- Keen Dreams source code, released under the GNU GPL in September 2014 (web):
id_vw.h(the sprite table’sxl,yl,xh,yh) andkd_play.c(building each object’s rectangle from its current image, and the overlap test that callscontact). https://github.com/keendreams/keen - Bas Smits, Game Engine White Papers: Commander Keen (self-published, 2026; modern book): Keen Dreams released in 1991.
- James Greenhalgh, interviewed in Retro Gamer issue 42, 2007, p. 55: smaller hit-boxes in shoot-’em-ups and “grazing”.
- Patrick Gordon, “The theory behind first-person hitboxes”, Wireframe issue 22, September 2019, pp. 30–31: hitbox shapes in modern shooters.