Commodore 64 hardware sprites (MOBs, movable object blocks): the 24x21-pixel / 63-byte sprite shape, sprite pointers, enabling sprites, X/Y positioning including the X MSB ($D010) for positions past 255, sprite color, multicolor sprites, 2x X/Y expansion, sprite-to-background and sprite-to-sprite priority, and collision detection. Use this skill WHEN you see questions like "how do I make a sprite on the C64", "POKE 53269 enable sprite", "move a sprite past x 255 / $D010 MSB", "$D000 $D015 $D017 $D01C $D01D sprite registers", "set sprite pointer 2040", "multicolor sprite", "expand a sprite", "detect sprite collision $D01E $D01F", or "sprite priority". Pairs with c64-graphics (screen/charset/bank setup) and c64-vic-ii (exact raster timing and chip behavior).
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Commodore 64 hardware sprites (MOBs, movable object blocks): the 24x21-pixel / 63-byte sprite shape, sprite pointers, enabling sprites, X/Y positioning including the X MSB ($D010) for positions past 255, sprite color, multicolor sprites, 2x X/Y expansion, sprite-to-background and sprite-to-sprite priority, and collision detection. Use this skill WHEN you see questions like "how do I make a sprite on the C64", "POKE 53269 enable sprite", "move a sprite past x 255 / $D010 MSB", "$D000 $D015 $D017 $D01C $D01D sprite registers", "set sprite pointer 2040", "multicolor sprite", "expand a sprite", "detect sprite collision $D01E $D01F", or "sprite priority". Pairs with c64-graphics (screen/charset/bank setup) and c64-vic-ii (exact raster timing and chip behavior).
C64 Sprites (VIC-II MOBs)
Hardware sprites are small movable objects the VIC-II (6567/6569) draws and
positions for you — up to 8 at once. Each sprite is 24 dots wide x 21 dots
high = 504 dots = 63 bytes (21 rows of 3 bytes). The VIC handles drawing,
priority and collision; you set shape, color, position, and flags.
For screen RAM / charset / video-bank setup (which decides where pointers and
sprite data live) see c64-graphics. For cycle-exact raster timing, the
sprite DMA fetch cycles, and exact edge behavior see c64-vic-ii.
The sprite register block ($D000–$D02E)
Reg
Dec
Function
$D000–$D00F
53248–53263
Sprite 0–7 X,Y position pairs (X even reg, Y odd reg)
$D010
53264
X MSB register — bit n = sprite n's 9th X bit (X > 255)
$D015
53269
Enable — bit n turns sprite n on
$D017
53271
Y expand (2x vertical) — bit n
$D01B
53275
Sprite-to-background priority — bit n=1: sprite behind background
$D01C
53276
Multicolor select — bit n=1: sprite n is multicolor
$D01D
53277
X expand (2x horizontal) — bit n
$D01E
53278
Sprite-sprite collision latch — bit n set if sprite n hit another
$D01F
53279
Sprite-background (data) collision latch — bit n set on hit
$D025
53285
Shared multicolor color #0 (bit pair 01)
$D026
53286
Shared multicolor color #1 (bit pair 11)
$D027–$D02E
53287–53294
Per-sprite color, sprite 0–7 (bit pair 10 in MC)
$D019
53273
Interrupt status latch (bit1=sprite-data, bit2=sprite-sprite collision)
$D01A
53274
Interrupt enable (same bit layout) — set to fire an IRQ
Every per-sprite flag register uses bit n for sprite n. The idiom is
OR (2^SN) to set, AND (255-2^SN) to clear.
Sprite pointers — where the shape lives
Sprite data must start on a 64-byte boundary (63 bytes used + 1 wasted). The
8 sprite pointers are the last 8 bytes of screen RAM: default screen at
$0400 → pointers at $07F8–$07FF (2040–2047), one per sprite. Move the screen
and the pointers move with it.
Pointer value P (0–255) selects the block: actual address =
(BANK * 16384) + (P * 64). Example: pointer 2040 = 13 → data at
13*64 = 832 ($0340, the cassette buffer — a classic safe spot in bank 0).
POKE 2040,13 : REM sprite 0 shape comes from 13*64 = 832
Step-by-step: a sprite in BASIC
10 V=53248 : REM VIC base
20 POKE 2040,13 : REM sprite 0 pointer -> data at 832
30 FOR I=0 TO 62:READ A:POKE 832+I,A:NEXT : REM 63 shape bytes
40 POKE V+21,1 : REM $D015 enable sprite 0 (bit 0)
50 POKE V+39,1 : REM $D027 sprite 0 color = white
60 POKE V,100:POKE V+1,100 : REM X=100 ($D000), Y=100 ($D001)
To compute the 63 bytes: lay out a 24x21 grid, split each row into 3 bytes of 8
pixels (MSB = leftmost), value of a byte = sum of 2^(7-bit) for lit pixels.
Assembly equivalent of enable + position:
LDA #$01
STA $D015 ; enable sprite 0
LDA #100
STA $D000 ; X low
STA $D001 ; Y
LDA #$00
STA $D010 ; clear X MSB (X <= 255)
Positioning, and the X MSB for X > 255
Y is a single 0–255 byte. X needs 9 bits because the screen is wider than
255 dots, so the 9th bit of each sprite's X lives in $D010 (53264), one bit
per sprite.
Visible Y for an unexpanded sprite: first becomes visible at Y=30 (partially);
fully on-screen from Y=50 to Y=229; first fully-off value is 250.
Visible X spans roughly 24 ($18) to 343 ($157); X > 255 requires the MSB bit.
To place sprite n at X = XPOS (0–511):
POKE V+2*N, XPOS AND 255 : REM low 8 bits -> $D000+2N
IF XPOS>255 THEN POKE V+16, PEEK(V+16) OR (2^N) : REM set MSB bit n
IF XPOS<256 THEN POKE V+16, PEEK(V+16) AND (255-2^N) : REM clear MSB bit n
i.e. low 8 bits to $D000+2N, and set/clear bit n of $D010 (V+16) for the
9th bit.
Color and multicolor sprites
Single-color: one color per sprite in $D027+n; pixel on = that color, off =
transparent (shows background).
Multicolor (set bit n of $D01C): pixels are 2 bits wide, so 12x21 "fat"
pixels, 4 colors per sprite, at the cost of horizontal resolution:
Bit pair
Color source
00
transparent (background shows)
01
shared multicolor #0 — $D025 (53285)
10
sprite's own color — $D027+n
11
shared multicolor #1 — $D026 (53286)
The two $D025/$D026 colors are shared by all multicolor sprites; only bit-pair
10 is per-sprite.
AND (255-2^SN) to undo. Expansion stretches existing pixels — it does not add
detail.
Priority
Sprite-to-sprite priority is fixed: sprite 0 is in front of 1, 1 in front
of 2, … 7 is the lowest. Lower number wins on overlap.
Sprite-to-background priority is per-sprite in $D01B (53275): bit n=0 →
sprite n in front of the background (default); bit n=1 → sprite behind it (a
"window" effect, where a sprite passes behind on-screen graphics).
Collision detection
Two read-and-clear latch registers, each one bit per sprite:
$D01E (53278) sprite-to-sprite: a bit is set when sprites' non-transparent
pixels overlap.
$D01F (53279) sprite-to-background (data): set when a sprite hits non-zero
background pixels.
Both latch and stay set until you PEEK (read) them, which clears them. To get
an interrupt instead of polling, set the matching bit in the interrupt enable
register $D01A: bit1 = sprite-data collision, bit2 = sprite-sprite. The
interrupt status is $D019 (write a 1 back to that bit to acknowledge).
C = PEEK(53278) : REM read & clear sprite-sprite collisions
IF (C AND 1) THEN ... : REM sprite 0 was involved
In multicolor sprites, bit-pair 01 ($D025) counts as transparent for
collisions — it does not trigger a collision.
Quick answers
Sprite size / bytes? 24x21 pixels, 63 bytes (one wasted in the 64-byte block).
Where are the pointers? End of screen RAM: $07F8–$07FF for the default $0400 screen.
Enable register? $D015 (53269), bit per sprite. Per-sprite color? $D027–$D02E.
Move past X=255? Set bit n of $D010 (53264) and put X−256 in the low byte.
How many at once? 8 (more via raster interrupts — see c64-vic-ii).
Gotchas
Sprite data must start on a 64-byte boundary, and the pointer holds the
block number (address/64), not an address.
X position is 9-bit: forgetting $D010 makes a sprite wrap to the left edge
past X=255.
Collision latches clear on read — read once per frame and stash the value;
reading twice loses bits.
The pointers live in the selected video bank's screen RAM. Sprite data and
pointers must be in the 16K the VIC currently sees — set that up via
c64-graphics ($DD00 bank bits, $D018 screen base).
Multicolor 01 pixels are invisible to the collision logic.
Sprite-to-sprite priority is not configurable; only sprite-to-background
priority ($D01B) is.
How to read the references
references/sprites-programming.md — Programmer's Reference Guide Chapter
3 sprite half, verbatim: full position-register table, enable/expand/priority/
collision/multicolor sections, the X-MSB positioning diagrams, the interrupt
registers, and the "Programming Sprites — Another Look" worked BASIC programs.
Read this for the authoritative POKE values and complete listings.
references/sprites-tutorial.md — User's Guide Chapter 6, the step-by-step
beginner walkthrough (designing on a grid, computing the bytes, the balloon
example, moving and expanding). Read this when you want the gentle framing.
references/sprite-register-map.md — User's Guide App O sprite register
map, the compact bit-by-bit table of $D000–$D02E for sprites plus the color
codes. Read when you need the exact bit names. For cycle-exact timing and the
full chip spec, go to c64-vic-ii.