Difficulty ramp
Rules that make later levels, or longer play within a level, harder.
On this page
A difficulty ramp makes later play harder by rule. Space Invaders starts each new rack lower1. Pac-Man steps through a table of per-level settings2. Galaxian and Donkey Kong add a part that rises with time spent in the level to one that rises per level3,4. Asteroids starts each wave with more large rocks, up to a cap: 4, 6, 8, 10, then 11 rocks5. Defender reads each wave’s enemy counts from a table, as Pac-Man reads its levels, and repeats the fourth wave’s counts after that6,2.
- Start positionSpace Invaders (1978). Each new rack starts lower, from an 8-entry table.1
- More enemiesAsteroids (1979). Each wave starts two more large rocks, up to 11.5
- Level tablePac-Man (1980). Each level advances one entry along a DIP-selected table until it reads 20.2Defender (1981). Enemy counts for waves 1 to 4 from a table, the fourth repeated after.6
- Level and timeGalaxian (1979). A base that rises per level plus an extra part that rises with time in the level.3Donkey Kong (1981). The level number plus a timer on the board, capped at 5; the bonus timer grows with the level.4,7
Games
| Game | Year | How | Note |
|---|---|---|---|
| Factorio | 2016 | the enemy grows stronger with play time and with the pollution the factory makes | |
| Space Invaders | 1978 | Start position | each new rack starts lower, from an 8-entry table |
| Asteroids | 1979 | More enemies | each wave starts two more large rocks, up to 11 |
| Pac-Man | 1980 | Level table | each level advances one entry along a DIP-selected table until it reads 20 |
| Defender | 1981 | Level table | enemy counts for waves 1 to 4 from a table, the fourth repeated after |
| Galaxian | 1979 | Level and time | a base that rises per level plus an extra part that rises with time in the level |
| Donkey Kong | 1981 | Level and time | the level number plus a timer on the board, capped at 5; the bonus timer grows with the level |
| Super Mario Bros.: The Lost Levels | 1986 | Level flag | from 4-4 on, and in worlds A to D, extra enemies appear and hammer bros, Bowser, and the cannons get more aggressive |
Every claim about this mechanic, by game (10)
References
- ^ abEach new rack starts lower on the screen. The first rack's bottom row starts at Y
$78. When a rack is cleared, the count of racks beaten (taken mod 8, plus 1) picks the next start from an 8-entry table,$60,$50,$48,$48,$48,$40,$40,$40, so the 10th rack starts where the 2nd did.CodeComputer Archeology, Space InvadersrevisedHow we know
17170A09: 2E FE LD L,$FE ; 2xFE ... rack count 17180A0B: 7E LD A,(HL) ; Get the number of racks the player has beaten 17190A0C: E6 07 AND $07 ; 0-7 17200A0E: 3C INC A ; Now 1-8 17210A0F: 77 LD (HL),A ; Update count since player just beat a rack 17220A10: 21 A2 1D LD HL,$1DA2 ; Starting coordinate of alien table 17230A13: 23 INC HL ; Find the ... 17240A14: 3D DEC A ; ... right entry ... 17250A15: C2 13 0A JP NZ,$0A13 ; {} ... in the table 17260A18: 7E LD A,(HL) ; Get the starting Y coordiante 17270A19: E1 POP HL ; Restore player's pointer 17280A1A: 2E FC LD L,$FC ; 2xFC ... ⋮
content/Arcade/SpaceInvaders/Code.md lines 1717–1731 at 1adc2a7 · upstream ↗ 4685AlienStartTable: 4686; Starting Y coordinates for aliens at beginning of rounds. The first round is initialized to $78 at 07EA. 4687; After that this table is used for 2nd, 3rd, 4th, 5th, 6th, 7th, 8th, and 9th. The 10th starts over at 4688; 1DA3 (60). 46891DA3: 60 46901DA4: 50 46911DA5: 48 46921DA6: 48 46931DA7: 48 46941DA8: 40 46951DA9: 40 46961DAA: 40
content/Arcade/SpaceInvaders/Code.md lines 4685–4696 at 1adc2a7 · upstream ↗ 137807EA: 21 78 38 LD HL,$3878 ; Screen coordinates for lower-left alien 137907ED: 22 FC 21 LD ($21FC),HL ; {ram.p1RefAlienY} Initialize reference alien for player 1
content/Arcade/SpaceInvaders/Code.md lines 1378–1379 at 1adc2a7 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-25.
Revised after a check by a second AI model, 2026-10-21.
Checked by a second AI model, 2026-10-25.
- ^ abcEach new level advances a pointer one entry along a difficulty table until the entry reads
$14(20). The DIP switch picks the table: one runs 0, 1, 2, … 20 and reaches 20 on level 21; the other, which the comment calls hard, runs 1, 3, 4, 6, 7, 8, … 17, 20 and reaches 20 on level 16. Each entry selects a 6-byte record at$0796that sets, among other things, the movement pattern and the ghosts' counters for leaving the house.Codemburkley/pacman-crevisedHow we know
273 /* Difficulty data. Two sets, easy or hard. Hard ramps up more quickly. 274 * Each level is more difficult until max difficulty which is 0x14 */ ⋮ 277 // 0068 00 01 02 03 04 05 06 07 278 // 0070 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 ⋮ 281 // 007d 01 03 04 282 // 0080 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 14
pacman.c lines 273–282 at 3277e56 · upstream ↗ 11406 DIFFICULTY_PTR = DIFFICULTY_DATA[DIP_SWITCH_DIFFICULTY ^ 1];pacman.c line 11406 at 3277e56 · upstream ↗ 3164 if (ROM[P1_CURR_DIFFICULTY] == 0x14) 3165 return; ⋮ 3172 P1_CURR_DIFFICULTY++;
pacman.c lines 3153–3172 at 3277e56 · upstream ↗ 2221void setupGhostTimers_070e (int b) ⋮ 2232 b = ROM[P1_CURR_DIFFICULTY]; ⋮ 2247 uint8_t *ix = DATA_0796 + b * 6; ⋮ 2270 setupMovePat_0814(hl); ⋮ 2292 initLeaveHouseCounters_083a(hl);
pacman.c lines 2221–2292 at 3277e56 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-25.
Revised after a check by a second AI model, 2026-10-21.
Checked by a second AI model, 2026-10-25.
- ^ abGalaxian's difficulty has two parts. A base value rises by 1 with each level cleared, up to 7. An extra value starts each level at 0 and rises by 1 each time two nested counters run out, up to 7. The counters reload to 60 and 20, so once running they step it every 1,200 passes of the game logic, but the cited code doesn't reset them when a level starts, so a level's first step can come sooner. They hold while the player is not in play or after a flagship in flight is shot. The two values set how many single attackers may fly at once and how many attack counters tick.CodeScottTunstall/Galaxianrevised
How we know
493; These 2 counters are used to gradually increase the DIFFICULTY_EXTRA_VALUE over time. See $14F3 for algorithm details. ⋮ 497; These values determine how often aliens attack (see $1524 and $1583), and how many can attack at one time (see $1352). 498DIFFICULTY_EXTRA_VALUE EQU $421A ; DIFFICULTY_EXTRA_VALUE is incremented during the level. Maximum value of 7. See $1509. 499DIFFICULTY_BASE_VALUE EQU $421B ; DIFFICULTY_BASE_VALUE is incremented when you complete a level. Maximum value of 7. See $1656.
galaxian.asm lines 493–499 at a16b402 · upstream ↗ 5183HANDLE_LEVEL_DIFFICULTY: 518414F3: 3A 00 42 ld a,($4200) ; read HAS_PLAYER_SPAWNED 518514F6: 0F rrca ; move flag into carry 518614F7: D0 ret nc ; return if player has not spawned 518714F8: 3A 2B 42 ld a,($422B) ; read IS_FLAGSHIP_HIT 518814FB: 0F rrca ; move flag into carry 518914FC: D8 ret c ; return if flagship has been hit ⋮ 519214FD: 21 18 42 ld hl,$4218 ; load HL with address of DIFFICULTY_COUNTER_1 51931500: 35 dec (hl) ; decrement counter 51941501: C0 ret nz 51951502: 36 3C ld (hl),$3C ; reset counter ⋮ 51981504: 23 inc hl ; bump HL to DIFFICULTY_COUNTER_2 ⋮
galaxian.asm lines 5183–5214 at a16b402 · upstream ↗ 55041649: AF xor a 5505164A: 32 1A 42 ld ($421A),a ; reset DIFFICULTY_EXTRA_VALUE ⋮ 55111656: 2A 1B 42 ld hl,($421B) ; load H with PLAYER_LEVEL and L with DIFFICULTY_BASE_VALUE 55121659: 24 inc h ; increment player level 5513165A: 7D ld a,l ; load A with DIFFICULTY_BASE_VALUE 5514165B: FE 07 cp $07 ; are we at max difficulty? 5515165D: 28 03 jr z,$1662 ; yes, goto $1662 ⋮ 55171661: 3C inc a ; otherwise, increment DIFFICULTY_BASE_VALUE 55181662: 6F ld l,a 55191663: 22 1B 42 ld ($421B),hl ; update PLAYER_LEVEL and DIFFICULTY_BASE_VALUE
galaxian.asm lines 5504–5519 at a16b402 · upstream ↗ 2040HANDLE_MAIN_GAME_LOGIC:galaxian.asm lines 2040–2055 at a16b402 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-25.
Revised after a check by a second AI model, 2026-10-21.
Checked by a second AI model, 2026-10-25.
- ^ abDonkey Kong's internal difficulty, which the comments say sets the speed of fires and the behavior of wild barrels, is the level number plus a timer that steps once every 2,048 calls of its routine (256 × 8), capped at 5.Codefurrykef/dkdasmrevised
How we know
439; #6380 - Internal difficulty. Dictates speed of fires, wild barrel behavior, barrel steerability and other things. Ranges from 1 to 5.dkong.asm line 439 at 4d296c5 · upstream ↗ 1633; checks timers and increments difficulty if needed ⋮ 1635; [timer_6384++ ; IF timer_6384 != 256 THEN RETURN ; timer_6384 := 0 ; ] ⋮ 1643; [timer_6381++ ; IF (timer_6381/8) != INT(timer_6381/8) THEN RETURN] ⋮ 1654; [ difficulty := (timer_6381 div 8) + level ; IF difficulty > 5 THEN difficulty := 5 ; RETURN]
dkong.asm lines 1633–1669 at 4d296c5 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Revised after a check by a second AI model, 2026-10-21.
- ^ abA new wave starts once no rocks are left and a 127-frame wave timer, set when the last rock goes, has run out. Each wave has two more large rocks than the one before, up to 11; the count starts at 2 when a game starts, so the waves run 4, 6, 8, 10, 11, 11 (computed).CodeComputer Archeology, Asteroids
How we know
JSR $6EFA ; {} Reset Sound, Zero Out Sound Timers JSR $6ED8 ; {} Number Of Starting Ships To $56 And Zero JSR $7168 ; {} Start of main game loop???
content/Arcade/Asteroids/Code.md#L29-L31 · upstream ↗ JSR $6885 ; {} BCS $6803 ; {}
content/Arcade/Asteroids/Code.md#L54-L55 · upstream ↗ ASL A ; Zero A, And Set Carry Flag
content/Arcade/Asteroids/Code.md#L150-L152 · upstream ↗ LDA #$02 STA $02F5 ; {ram.asteroidsPerWave}
content/Arcade/Asteroids/Code.md#L858-L859 · upstream ↗ LDA $02FB ; {ram.astdWaveTimer} BEQ $687E ; {} DEC $02FB ; {ram.astdWaveTimer} ORA $02F6 ; {ram.curAsteroidCount} BNE $680C ; {} BEQ $6809 ; {}
content/Arcade/Asteroids/Code.md#L76-L81 · upstream ↗ DEC $02F6 ; {ram.curAsteroidCount} BNE $6F8C ; {} LDY #$7F STY $02FB ; {ram.astdWaveTimer}
content/Arcade/Asteroids/Code.md#L939-L942 · upstream ↗ LDA $02F5 ; {ram.asteroidsPerWave} CLC ADC #$02 CMP #$0B BCC $7193 ; {} Branch if smaller??? LDA #$0B STA $02F6 ; {ram.curAsteroidCount} STA $02F5 ; {ram.asteroidsPerWave} … AND #$18 ORA #$04 STA $0200,X ; {ram.statusAsteroids}
content/Arcade/Asteroids/Code.md#L1182-L1197 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^ abDefender reads each wave's enemies from a table with a column for each of waves 1 to 4: landers 15, 20, 20, 20; bombers 0, 3, 4, 5; pods 0, 1, 3, 4; no mutants or swarmers at the start; landers come in groups of 5. Later waves take the fourth column plus per-wave increments, which are 0 for these counts, so they keep the fourth wave's numbers (computed).Codemwenge/defender
How we know
674*WAVE DATA 675*MAX,MIN,INTRADELT,INTERDELT 676*W1,W2,W3,W4 677WVTAB FCB 20,0,0,0 678 FCB 15,20,20,20 ;LANDERS 679 FCB 3,0,0,0 680 FCB 0,3,4,5 ;TIES 681 FCB 6,0,0,0 682 FCB 0,1,3,4 ;PROBES 683 FCB 10,0,0,0 684 FCB 0,0,0,0 ;SCHITZOS 685 FCB 10,0,0,0 ⋮
src/blk71.src lines 674–690 at e740063 · upstream ↗ 1865 LDA PWAV,X 1866 PSHS A 1867 CMPA #4 1868 BLS GETWV1 1869 LDA #4 1870GETWV1 LDU WVTAB 1871 ADDA #3 ;OFFSET ADJUST ⋮ 1878GETWV3 PULS A ;HIGHER THAN 4? ⋮ 1895GETWV4 LDB #3 ⋮ 1898 BSR WDELT ;GET YUR DELTAS
src/defa7.src lines 1864–1900 at e740063 · upstream ↗ 1145 FDB LANDV 1146 FDB MUTV 1147 FDB BAITV 1148 FDB BOMBV 1149 FDB SWRMPV 1150 FDB SWARMV ⋮ 1161PICTS FDB LNDP1 1162 FDB SCZP1 1163 FDB UFOP1 1164 FDB TIEP1 1165 FDB PRBP1 1166 FDB SWPIC1
src/amode1.src lines 1144–1166 at e740063 · upstream ↗ 271SWRMP FDB POD ⋮ 274BOMBR FDB BOMBER
src/mess0.src lines 271–274 at e740063 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^Each board's bonus timer starts at 10 × level + 40, computed in 8 bits and capped at 80, and the readout shows 100 times the value: 5,000 on level 1, 6,000 on level 2, 7,000 on level 3, and 8,000 from level 4. The listings read MAME's
dkongset (US set 1).Codefurrykef/dkdasm · Computer Archeology, Donkey KongrevisedHow we know
3746; set up initial timer 3747; timer is either 5000, 6000, 7000 or 8000 depending on level
dkong.asm lines 3746–3768 at 4d296c5 · upstream ↗ 7>>> binary 0000:roms/c_5et_g.bin + roms/c_5ct_g.bin + roms/c_5bt_g.bin + roms/c_5at_g.bincontent/Arcade/DonkeyKong/Code.md line 7 at 1adc2a7 · upstream ↗ LD A,($6229) ; {hard.workRam+229} the bonus scales with the level … ADD A,$28 ; plus 40; the readout shows 100 times this CP $51 … LD A,$50 ; clamped at 80
content/Arcade/DonkeyKong/Code.md#L3171-L3184 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Revised after a check by a second AI model, 2026-10-21.
Sources
Code
- Cantrell, Christopher. 2026. “Computer Archeology: Space Invaders.” Commit 1adc2a7. topherCantrell/computerarcheology @ 1adc2a7 · licence, all uses
- Burkley, Mark. 2025. “pacman-c: a C translation of the Pac-Man ROM.” Commit 3277e56. mburkley/pacman-c @ 3277e56 · licence, all uses
- Tunstall, Scott. 2025. “Galaxian: annotated reverse engineering.” Commit a16b402. ScottTunstall/Galaxian @ a16b402 · licence, all uses
- Willms, Jeff and Kef Schecter. 2014. “dkdasm: Donkey Kong hacking kit.” Commit 4d296c5. furrykef/dkdasm @ 4d296c5 · licence, all uses
- Howell, Lonnie, Mark McDougall, and Christopher Cantrell. 2026. “Computer Archeology: Asteroids.” Commit 1adc2a7. topherCantrell/computerarcheology @ 1adc2a7 · licence, all uses
- Jarvis, Eugene, Sam Dicker, and Robert Hargreaves. 2023. “Defender (1981) by Eugene Jarvis and Sam Dicker: the 6809 source.” Commit e740063. mwenge/defender @ e740063 · licence, all uses