On this page
  1. Related
  2. Mechanics
  3. References
  4. Sources

Jupiter’s Pokémon Pinball has two tables, the Red and Blue fields. The atlas reads it through pret’s pokepinball disassembly, which builds the US and Australian ROM1. Labels and comments quoted here are pret’s.

The ball moves in 8.8 fixed point, gaining 11/256 of a pixel per frame of downward speed every frame2. Each axis is capped at about 7 pixels a frame, so a diagonal ball goes faster3. A wall’s angle comes from which of 16 points around the ball touch it, read from a table4. The ball bounces back at a quarter of its speed into the wall, and a hard hit shakes the rumble5.

A flipper swings in 5 frames6. Its push grows with how far from the pivot the ball touches it, and comes only while it’s swinging up7. The tilt buttons nudge the ball and never tilt out8. A ball saver runs for 20 seconds at the start of each ball, pausing while the ball’s x is 154 or more9.

In Catch ‘Em mode, a table mode, on the Red field, Voltorb hits flip the billboard’s 24 tiles to reveal a Pokémon10. The fourth registered hit on it catches it11. Every species gets 2 minutes12.

Mechanics

MechanicKindHow
Pinball physicsMasks and a normal table16 points around the ball tested against 1-bit masks; the touching run picks a normal from a 256-entry table, and the bounce keeps a quarter of the speed into the wall
GravityOne gravity11/256 px per frame² on the ball, 8.8 fixed point
FlipperBy the contact point5 frames a swing; the push is the contact's distance from the pivot times the swing this frame, up to 12.6 px per frame at the tip
TiltNudge onlythree buttons nudge the ball a pixel a frame for 3 or 4 frames, with no tilt-out
Table modeTimedCatch 'Em mode: 2 minutes to reveal a Pokémon with 24 billboard tiles and hit it 4 times
Ball saverTimed20 seconds at each new ball, two saves; 60 seconds without limit during Catch 'Em mode
Every claim about this game, by concept (12)
Ball saverEach table starts with a 20-second ball saver, and every ball lost for good starts a new one. While it runs, a drained ball is saved: the first save leaves the timer alone, and the second cuts it to 1 second and 1 frame. The timer counts down 60 frames a second, and not while the ball is at x 154 or more. Set to 20 seconds, it lasts 1,259 frames, about 21 seconds, if the ball stays left of x 154 throughout (computed). The slot cave can award 30, 60, or 90 seconds instead.Code
FlipperEach flipper's position runs from 0 to 15 in 8.8 fixed point. Holding its button adds 0x0333 (3.2 positions) each frame and releasing it subtracts 0x0333, so a flipper swings fully up in 5 frames and fully down in 5 (computed). While the flippers are disabled, a held button counts as released. A flipper resting at either end records no change.Code
Flipper collisions come from precomputed tables. For each flipper position from last frame's to this frame's, a 48 × 32-pixel grid gives the contact's distance from the pivot and the surface normal there; the right flipper reads the left's grid mirrored. A hit bounces the ball with amplification 1, then pushes it out along the normal by FlipperRadiusMagnitudes at that distance times 4 × the flipper's change this frame. A still flipper adds no push, and one moving down adds none either. The push at the tip of a rising flipper is 12.6 px per frame (computed); next frame's cap holds each axis to under 8.Code
GravityGravity adds 11/256 of a pixel per frame to the ball's downward speed every frame while gravity is on. The ball's position and velocity are both 8.8 fixed point: whole pixels in the high byte, 256ths in the low.Code
Pinball physicsIn the US and Australian Pokémon Pinball, the main loop runs the game's screen logic once per frame. During play that logic adds gravity, caps the velocity, handles the tilts and, on the lower half of a table, the flippers. It then tests for collisions, bounces the ball if one touches, and moves the ball last.Code
Each axis of the ball's velocity is capped on its own: a high byte above 7 becomes 7 and one below −7 becomes −7, the fraction kept, so the caps are 7 255/256 px per frame down or right and −7 up or left (computed), and a diagonal ball goes faster than a straight one. The move is limited again: a velocity of 5 px per frame or more moves the ball 4 255/256 px that frame, and one below −4 moves it 4 255/256 px the other way.Code
To find a wall, the game tests 16 points around the ball against 1-bit collision masks for the tiles under it. The first and last points of the longest run of touching points index a 256-entry table, CollisionForceAngles, for the surface's normal angle, in 256ths of a turn. Two more tables with the same index push the ball back out of the wall.Code
On a hit, the game rotates the ball's velocity so the surface's normal points up. A ball moving away is left alone. A ball moving in bounces back at a quarter of its speed into the surface, plus an eighth for each step of the hit's amplification. Its speed along the surface gains half the stored spin, in 256ths of a pixel per frame; the new spin is that speed × 4 / 256. The velocity is rotated back. A speed of 3 px per frame or more into the surface also sets the rumble's duration to 1 and, unless a flipper was hit, plays a sound.Code
Table modeIn Catch 'Em mode on the Red field, each Voltorb hit flips 4 of the billboard's 24 tiles and scores 100,000, so 6 hits reveal the Pokémon from a blank board (computed). The Pokémon appears once all 24 are flipped and the ball is on the table's lower half.Code
Once the Pokémon appears, each registered hit scores 300,000 and steps a counter from 0 to 3, lighting part of the CATCH bar; a hit with the counter at 3 catches it, so the fourth registered hit catches. Mew counts a hit only when a separate byte of its own rolls over at 256, so it would need 1,024 hits from a zero byte (computed). When the timer runs out on Mew, the game marks Mew caught in the Pokédex anyway.Code
Every Pokémon gets the same 2 minutes to be caught: all 151 entries of CatchEmTimerData are 0 seconds and 2 minutes. Starting the mode also starts a 60-second ball saver that saves without limit, and the saver from before is restored when the mode ends.Code
TiltPokémon Pinball's tilt is a nudge with no tilt-out: the tilt routines keep no warning count and never end a ball. Holding a tilt button (left, right, or up; D-pad Down, B, and Select by default) runs its counter and screen shake for 3 frames (4 for up), and on each of those frames moves the ball 1 pixel if the ball is visible and gravity and tilt are on. That tilt then waits until the button is released and its counter has run back to 0. While a tilt is pushing, a ball touching a surface gets a velocity from a table for that tilt, read by the normal angle. Left and right together cancel.Code

References

  1. ^In the US and Australian Pokémon Pinball, the main loop runs the game's screen logic once per frame. During play that logic adds gravity, caps the velocity, handles the tilts and, on the lower half of a table, the flippers. It then tests for collisions, bounces the ball if one touches, and moves the ball last.Codepret/pokepinball
    How we know
    2114.master_loop
    2115	call TickRumbleDuration
    2116	call DoScreenLogic
    ⋮
    2119	rst AdvanceFrame
    2120	jr .master_loop
    
    home.asm lines 2114–2120 at 0a6f6dc · upstream ↗
    69GameScreenFunction_HandleBallPhysics: ; 0xd909
    70; main loop for stage logic
    ⋮
    74	call ApplyGravityToBall
    75	call LimitBallVelocity
    ⋮
    78	call HandleTilts
    ⋮
    81	callba nz, HandleFlippers  ; only perform flipper logic on the lower half of stages
    ⋮
    86	call CheckStageCollision
    ⋮
    91	call CheckGameObjectCollisions
    ⋮
    111	call ApplyCollisionForces
    ⋮
    150	call MoveBallPosition
    
    engine/pinball_game.asm lines 69–150 at 0a6f6dc · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  2. ^Gravity adds 11/256 of a pixel per frame to the ball's downward speed every frame while gravity is on. The ball's position and velocity are both 8.8 fixed point: whole pixels in the high byte, 256ths in the low.Codepret/pokepinball
    How we know
    2377ApplyGravityToBall: ; 0x2168
    2378; Adds a constant to the pinball's y velocity.
    2379	ld a, [wEnableBallGravityAndTilt]
    2380	and a
    2381	ret z
    2382	ld de, $000b  ; gravity added to y velocity every frame
    ⋮
    2392	ret
    
    home.asm lines 2377–2392 at 0a6f6dc · upstream ↗
    271wBallXPos:: ; 0xd4b3
    272; 8.8 fixed-point values in little-endian format
    ⋮
    278; 8.8 fixed-point values in little-endian format
    ⋮
    283wBallXVelocity:: ; 0xd4bb
    284; 8.8 fixed-point values in little-endian format
    ⋮
    287; 8.8 fixed-point values in little-endian format
    
    wram.asm lines 271–288 at 0a6f6dc · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  3. ^Each axis of the ball's velocity is capped on its own: a high byte above 7 becomes 7 and one below −7 becomes −7, the fraction kept, so the caps are 7 255/256 px per frame down or right and −7 up or left (computed), and a diagonal ball goes faster than a straight one. The move is limited again: a velocity of 5 px per frame or more moves the ball 4 255/256 px that frame, and one below −4 moves it 4 255/256 px the other way.Codepret/pokepinball
    How we know
    2394LimitBallVelocity: ; 0x2180
    2395; Ensures that the ball's x and y velocity are kept under a threshold.
    2396; The ball can travel at a greater max speed when moving diagonally, since it
    2397; limits the x and y components independently.
    ⋮
    2406	cp 8
    2407	ret c
    2408	ld a, 7  ; max positive velocity
    ⋮
    2410	ret
    ⋮
    2413	cp -7
    2414	ret nc
    2415	ld a, -7  ; max negative velocity
    
    home.asm lines 2394–2415 at 0a6f6dc · upstream ↗
    2436AddVelocityToPosition: ; 0x21c3
    2437	ld a, [de]
    2438	bit 7, a
    2439	jr nz, .negativeVelocity
    2440	cp 5
    2441	jr c, .readLoByte
    2442	ld bc, $04ff
    2443	jr .updateBallPos
    ⋮
    2445.negativeVelocity
    2446	cp -4
    2447	jr nc, .readLoByte
    2448	ld bc, -$04ff
    ⋮
    
    home.asm lines 2436–2458 at 0a6f6dc · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  4. ^To find a wall, the game tests 16 points around the ball against 1-bit collision masks for the tiles under it. The first and last points of the longest run of touching points index a 256-entry table, CollisionForceAngles, for the surface's normal angle, in 256ths of a turn. Two more tables with the same index push the ball back out of the wall.Codepret/pokepinball
    How we know
    2735	ld b, 16  ; length of wCollisionPointTests
    
    home.asm line 2735 at 0a6f6dc · upstream ↗
    2878.determinedCollisionStatus
    2879	; e = maximum number of consecutive successful collision points
    2880	; d = the start and last index of that consecutive string of collision points (wCollisionPointTests)
    2881	;     the hi nybble is the start index, lo nybble is the end index
    ⋮
    2892	; Based on the start and end collision point indices, look
    2893	; up the corresponding normal angle for them.
    ⋮
    2896	ld hl, CollisionForceAngles
    2897	add hl, de
    2898	ld a, [hl]
    2899	ld [wCollisionNormalAngle], a
    2900	; Again, based on the start and end collision point indices, apply
    2901	; position offsets to position the ball safely outside of the wall
    ⋮
    
    home.asm lines 2878–2922 at 0a6f6dc · upstream ↗
    2345Cosine: ; 0x2147
    ⋮
    2349	add $40
    ⋮
    2357	and $7f ; ensure angle is between 0 and 180 degrees
    
    home.asm lines 2345–2357 at 0a6f6dc · upstream ↗
    1CollisionForceAngles: ; 0x8817
    2; This data has something to do with collisions.
    3	db $C0
    
    data/collision/collision_deltas.asm lines 1–3 at 0a6f6dc · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  5. ^On a hit, the game rotates the ball's velocity so the surface's normal points up. A ball moving away is left alone. A ball moving in bounces back at a quarter of its speed into the surface, plus an eighth for each step of the hit's amplification. Its speed along the surface gains half the stored spin, in 256ths of a pixel per frame; the new spin is that speed × 4 / 256. The velocity is rotated back. A speed of 3 px per frame or more into the surface also sets the rumble's duration to 1 and, unless a flipper was hit, plays a sound.Codepret/pokepinball
    How we know
    101	ld a, [wIsBallColliding]  ; check for collision flag
    ⋮
    106	; First, rotate the velocity vector into a standardized coordinate
    107	; system where the normal angle points upwards.
    108	ld a, [wCollisionNormalAngle]
    109	call RotateVector
    110	; Apply the collision forces to the ball in the rotated coordinate system.
    111	call ApplyCollisionForces
    ⋮
    144	; Rotate the velocity vector back to the regular coordinate system, and
    145	; set the ball's velocity to the resulting vector.
    146	ld a, [wCollisionNormalAngle]
    147	call NegateAngleAndRotateVector
    148	call SetBallVelocity
    
    engine/pinball_game.asm lines 101–148 at 0a6f6dc · upstream ↗
    2528ApplyCollisionForces: ; 0x222b
    ⋮
    2542	; Early exit if the ball is traveling away from the collision normal.
    2543	bit 7, d
    2544	jr nz, .exit
    ⋮
    2547	cp 3
    2548	jr c, .applyforces
    2549	; The ball collided hard because its y velocity is a
    2550	; large value. Shake the rumble pack, and play a little
    2551	; sound effect to enhance the collision.
    2552	ld a, $ff
    2553	ld [wRumblePattern], a
    2554	ld a, 1
    ⋮
    
    home.asm lines 2528–2625 at 0a6f6dc · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  6. ^Each flipper's position runs from 0 to 15 in 8.8 fixed point. Holding its button adds 0x0333 (3.2 positions) each frame and releasing it subtracts 0x0333, so a flipper swings fully up in 5 frames and fully down in 5 (computed). While the flippers are disabled, a held button counts as released. A flipper resting at either end records no change.Codepret/pokepinballrevised
    How we know
    14UpdateFlipperStates: ; 0xe118
    ⋮
    20	ld hl, wKeyConfigLeftFlipper
    21	call IsKeyPressed2
    22	ld hl, -$0333
    23	jr z, .checkLeftStateBounds
    24	ld a, [wFlippersDisabled]
    25	and a
    26	jr nz, .checkLeftStateBounds
    27	ld hl,  $0333
    28.checkLeftStateBounds
    ⋮
    30	and a
    ⋮
    35	cp $f
    ⋮
    
    engine/pinball_game/flippers.asm lines 14–76 at 0a6f6dc · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  7. ^Flipper collisions come from precomputed tables. For each flipper position from last frame's to this frame's, a 48 × 32-pixel grid gives the contact's distance from the pivot and the surface normal there; the right flipper reads the left's grid mirrored. A hit bounces the ball with amplification 1, then pushes it out along the normal by FlipperRadiusMagnitudes at that distance times 4 × the flipper's change this frame. A still flipper adds no push, and one moving down adds none either. The push at the tip of a rising flipper is 12.6 px per frame (computed); next frame's cap holds each axis to under 8.Codepret/pokepinball
    How we know
    202ReadFlipperCollisionAttributes: ; 0xe25a
    203	ldh a, [hBallXPos + 1]
    204	sub 43  ; check if ball is in horizontal range of flippers
    205	ret c
    206	cp 48
    207	ret nc
    ⋮
    211	sub 123  ; check if ball is in vertical range of flippers
    212	ret c
    213	cp 32
    214	ret nc
    ⋮
    218.collisionCheckLoop
    ⋮
    275.collision
    ⋮
    
    engine/pinball_game/flippers.asm lines 202–297 at 0a6f6dc · upstream ↗
    167CheckRightFlipperCollision: ; 0xe226
    168; ball is in right half of screen
    ⋮
    171	ld a, [hli]  ; Invert the ball's x position, so that the flipper collision bytes are mirrored.
    
    engine/pinball_game/flippers.asm lines 167–171 at 0a6f6dc · upstream ↗
    622HandleFlipperCollision: ; 0xe442
    ⋮
    625	ld a, 1
    ⋮
    637	ld hl, FlipperRadiusMagnitudes
    ⋮
    648	rl d
    ⋮
    650	rl d  ; multiplied flipper state change by 4
    651	call CalculateFlipperYForce
    ⋮
    660	cpl  ; mirror the normal angle across the y axis
    ⋮
    664	ld a, 1
    665	ld [wCollisionForceAmplification], a
    ⋮
    669	; don't apply any y force if the ball is being forced downwards into the flipper
    
    engine/pinball_game/flippers.asm lines 622–673 at 0a6f6dc · upstream ↗
    423CalculateFlipperYForce: ; 0xe379
    424; Calculates the y force that's added to the ball's velocity when colliding with a flipper.
    425; Flippers rotate around a point, and the further away from that rotation point that ball is, the
    426; higher the magnitude value is (bc). This magnitude is multiplied by the flipper state change to
    
    engine/pinball_game/flippers.asm lines 423–430 at 0a6f6dc · upstream ↗
    800; Each entry corresponds to a distance from the flipper's rotation point.
    801FlipperRadiusMagnitudes: ; 0xe538
    802	dw $0000
    803	dw $000C
    ⋮
    818	dw $00F8
    819	dw $00FC
    820	dw $00FC
    821	dw $00FC
    822	dw $00FC
    823	dw $00FC
    824	dw $00FC
    825	dw $00FC
    ⋮
    
    engine/pinball_game/flippers.asm lines 800–833 at 0a6f6dc · upstream ↗
    115	; de -= *wFlipperYForce
    116	ld hl, wFlipperYForce
    117	ld a, [hli]
    118	ld h, [hl]
    119	ld l, a
    120	ld a, e
    121	sub l
    122	ld e, a
    123	ld a, d
    124	sbc h
    125	ld d, a
    
    engine/pinball_game.asm lines 115–125 at 0a6f6dc · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-25.

    Checked by a second AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

  8. ^Pokémon Pinball's tilt is a nudge with no tilt-out: the tilt routines keep no warning count and never end a ball. Holding a tilt button (left, right, or up; D-pad Down, B, and Select by default) runs its counter and screen shake for 3 frames (4 for up), and on each of those frames moves the ball 1 pixel if the ball is visible and gravity and tilt are on. That tilt then waits until the button is released and its counter has run back to 0. While a tilt is pushing, a ball touching a surface gets a velocity from a table for that tilt, read by the normal angle. Left and right together cancel.Codepret/pokepinballrevised
    How we know
    1HandleTilts: ; 0x3582
    ⋮
    5	ret
    ⋮
    7HandleLeftTilt: ; 0x358c
    8	ld a, [wLeftTiltReset]
    9	and a
    10	jr nz, .tiltCoolDown
    11	ld hl, wKeyConfigLeftTilt
    12	call IsKeyPressed2
    ⋮
    14	ld a, [wLeftTiltCounter]
    15	cp 3
    16	jr z, .startCoolDown
    ⋮
    24	ld a, [wPinballIsVisible]
    ⋮
    
    home/tilt.asm lines 1–240 at 0a6f6dc · upstream ↗
    101	ld a, [wIsBallColliding]  ; check for collision flag
    102	and a
    103	jr z, .moveBallPosition
    104	call ApplyTiltForces
    
    engine/pinball_game.asm lines 101–104 at 0a6f6dc · upstream ↗
    1080DefaultKeyConfigs: ; 0xca55
    ⋮
    1084	db D_DOWN,   $00  ; wKeyConfigLeftTilt
    1085	db B_BUTTON, $00  ; wKeyConfigRightTilt
    1086	db SELECT,   $00  ; wKeyConfigUpperTilt
    
    engine/options_screen.asm lines 1080–1087 at 0a6f6dc · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  9. ^Each table starts with a 20-second ball saver, and every ball lost for good starts a new one. While it runs, a drained ball is saved: the first save leaves the timer alone, and the second cuts it to 1 second and 1 frame. The timer counts down 60 frames a second, and not while the ball is at x 154 or more. Set to 20 seconds, it lasts 1,259 frames, about 21 seconds, if the ball stays left of x 154 throughout (computed). The slot cave can award 30, 60, or 90 seconds instead.Codepret/pokepinballrevised
    How we know
    1Start20SecondSaverTimer: ; 0xdbba
    ⋮
    6	ld a, 59
    7	ld [wBallSaverTimerFrames], a
    8	ld a, 20
    9	ld [wBallSaverTimerSeconds], a
    10	ld a, $2
    11	ld [wNumTimesBallSavedTextWillDisplay], a
    
    engine/pinball_game/ball_saver/ball_saver_20.asm lines 1–12 at 0a6f6dc · upstream ↗
    1HandleBallLossRedField: ; 0xdd76
    2	ld a, [wBallSaverTimerFrames]
    3	ld hl, wBallSaverTimerSeconds
    4	or [hl]
    5	jr z, .youLose
    6	ld a, [wNumTimesBallSavedTextWillDisplay]
    7	bit 7, a
    8	jr nz, .skip_save_text
    9	dec a
    10	ld [wNumTimesBallSavedTextWillDisplay], a
    ⋮
    15	jr nz, .skip_save_text
    16	ld a, $1
    ⋮
    
    engine/pinball_game/ball_loss/ball_loss_red_field.asm lines 1–31 at 0a6f6dc · upstream ↗
    54UpdateBallSaverState: ; 0x146a9
    55	ld a, [wBallSaverTimerFrames]
    56	ld hl, wBallSaverTimerSeconds
    57	or [hl] ;skip if timer ran out
    58	ret z
    59	ld a, [wBallXPos + 1]
    60	cp 154 ;if high? Byte of ball X pos is >= 154, don't update timers
    61	jr nc, .SkipSecondsOrFramesUpdate
    62	ld a, [wBallSaverTimerFrames]
    63	dec a
    64	ld [wBallSaverTimerFrames], a
    65	bit 7, a
    ⋮
    
    engine/pinball_game/object_collision/red_stage_resolve_collision.asm lines 53–75 at 0a6f6dc · upstream ↗
    43	callba Start20SecondSaverTimer
    
    engine/pinball_game/stage_init/init_red_field.asm line 43 at 0a6f6dc · upstream ↗
    161SlotRewards_CallTable: ; 0xeeca
    162	dw Start30SecondSaverTimer
    163	dw Start60SecondSaverTimer
    164	dw Start90SecondSaverTimer
    
    engine/pinball_game/slot.asm lines 161–164 at 0a6f6dc · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  10. ^In Catch 'Em mode on the Red field, each Voltorb hit flips 4 of the billboard's 24 tiles and scores 100,000, so 6 hits reveal the Pokémon from a blank board (computed). The Pokémon appears once all 24 are flipped and the ball is on the table's lower half.Codepret/pokepinballrevised
    How we know
    231HandleVoltorbCollision_CatchemMode: ; 0x20230 resolve hitting a voltorb in catch mode?
    232	ld a, [wNumberOfCatchModeTilesFlipped]
    233	cp $18
    ⋮
    251	ld a, [wNumberOfCatchModeTilesFlipped]
    252	add $4 ;then add 4 to FlippedCount, clamp to 24
    253	cp $18
    ⋮
    258	cp $18
    ⋮
    264	ld bc, OneHundredThousandPoints
    
    engine/pinball_game/catchem_mode/catchem_mode_red_field.asm lines 231–264 at 0a6f6dc · upstream ↗
    28Func_20041: ; 0x20041
    29	ld a, [wNumberOfCatchModeTilesFlipped]
    30	cp $18
    31	jr nz, .NotDone
    32	ld a, [wCurrentStage]
    33	bit 0, a
    34	jr z, .NotDone
    
    engine/pinball_game/catchem_mode/catchem_mode_red_field.asm lines 28–34 at 0a6f6dc · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  11. ^Once the Pokémon appears, each registered hit scores 300,000 and steps a counter from 0 to 3, lighting part of the CATCH bar; a hit with the counter at 3 catches it, so the fourth registered hit catches. Mew counts a hit only when a separate byte of its own rolls over at 256, so it would need 1,024 hits from a zero byte (computed). When the timer runs out on Mew, the game marks Mew caught in the Pokédex anyway.Codepret/pokepinballrevised
    How we know
    97	ld a, [wBallHitWildMon]
    98	and a
    99	jp z, .BallDidntHitMon ;if no ball hit(?), jump
    ⋮
    106	ld a, [wCurrentCatchEmMon]
    107	cp MEW - 1
    108	jr nz, .notMew
    109	ld a, [wNumMewHits]
    110	inc a
    111	ld [wNumMewHits], a
    112	jr nz, .Not256MewHits
    113.notMew
    114	ld a, [wNumMonHits]
    ⋮
    
    engine/pinball_game/catchem_mode/catchem_mode_red_field.asm lines 96–148 at 0a6f6dc · upstream ↗
    99	ld a, [wBallHitWildMon]
    ⋮
    116	ld a, [wNumMonHits]
    117	cp $3
    
    engine/pinball_game/catchem_mode/catchem_mode_blue_field.asm lines 99–120 at 0a6f6dc · upstream ↗
    866Func_10611: ; 0x10611
    ⋮
    884Data_1062a:
    885	dw Data_10630
    886	dw Data_10638
    887	dw Data_10640
    
    engine/pinball_game/catchem_mode.asm lines 866–888 at 0a6f6dc · upstream ↗
    212CheckIfCatchemModeTimerExpired_RedField: ; 0x201f2
    ⋮
    221	; Automatically set Mew as caught, since you can't possibly catch it
    222	ld a, [wCurrentCatchEmMon]
    223	cp MEW - 1
    224	jr nz, .asm_2021b
    225	callba SetPokemonOwnedFlag
    226.asm_2021b
    
    engine/pinball_game/catchem_mode/catchem_mode_red_field.asm lines 212–227 at 0a6f6dc · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  12. ^Every Pokémon gets the same 2 minutes to be caught: all 151 entries of CatchEmTimerData are 0 seconds and 2 minutes. Starting the mode also starts a 60-second ball saver that saves without limit, and the saver from before is restored when the mode ends.Codepret/pokepinballrevised
    How we know
    1CatchEmTimerData: ; 0x12a22
    2; Each 2-byte entry represents the total time you have to catch a Pokemon.
    3; They're all exactly 2 minutes, 0 seconds, but they can be changed to make
    4; different pokemon have different times, in order to add difficulty.
    5; First byte  = seconds value
    6; Second byte = minutes value
    7	db $00, $02  ; BULBASAUR
    ⋮
    157	db $00, $02  ; MEW
    
    data/catchem_timer_values.asm lines 1–157 at 0a6f6dc · upstream ↗
    123	ld hl, CatchEmTimerData ;contains how long each mon stays on screen, all are 2 minutes by default
    ⋮
    129	callba StartTimer
    130	callba InitBallSaverForCatchEmMode
    
    engine/pinball_game/catchem_mode.asm lines 118–131 at 0a6f6dc · upstream ↗
    1InitBallSaverForCatchEmMode: ; 0xdbd4
    ⋮
    10	ld a, $ff
    ⋮
    14	ld a, 60
    15	ld [wBallSaverTimerSeconds], a
    16	ld a, $ff
    17	ld [wNumTimesBallSavedTextWillDisplay], a
    18	ret
    ⋮
    20RestoreBallSaverAfterCatchEmMode: ; 0xdc00
    ⋮
    24	ld [wBallSaverTimerSeconds], a
    ⋮
    26	ld [wNumTimesBallSavedTextWillDisplay], a
    
    engine/pinball_game/ball_saver/ball_saver_catchem_mode.asm lines 1–32 at 0a6f6dc · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

Sources

Code