Rank
Difficulty that rises with what the player has achieved, such as loops cleared or weapons held, rather than with the stage alone.
On this page
Rank makes a game harder as the player does well. Contra counts loops cleared, up to 3, and reads the strongest gun either player holds; both shorten the wait between random soldiers1. Super C keeps only a flag for a beaten game and counts the players holding the spread gun2. Asteroids reads the score where Contra reads loops and guns3,1. The saucer’s size goes by count and score: the first three saucers large; after that small at random, or always from 30,000 points3. Its aim tightens with the score: the small saucer aims within 16 directions (of 256), then within 8 from 35,000 points4.
- ScoreAsteroids (1979). After the third saucer, small saucers come more often and always from 30,000 points; they aim tighter from 35,000.3,4
- Loops and gunsContra (1987). Random soldiers come faster with each loop cleared, up to 3, and with the strongest gun held.1Super C (1990). Enemies come faster once the game is beaten and for each player holding the spread gun.2
Games
| Game | Year | How | Note |
|---|---|---|---|
| Asteroids | 1979 | Score | after the third saucer, small saucers come more often and always from 30,000 points; they aim tighter from 35,000 |
| Contra | 1987 | Loops and guns | random soldiers come faster with each loop cleared, up to 3, and with the strongest gun held |
| Super C | 1990 | Loops and guns | enemies come faster once the game is beaten and for each player holding the spread gun |
Every claim about this mechanic, by game (4)
References
- ^ abcEach completed loop of the US NES Contra and the strongest gun either player holds both shorten the timer between random soldiers: from the level's start value (144 on level 1), 40 comes off per loop, counting up to 3, and 5 per point of weapon strength (S 3, M and L 2, F 1, the default 0).Codevermiceli/nes-contra-us
How we know
1736adjust_generation_timer: 1737 jsr get_soldier_gen_timer_for_lvl 1738 sta SOLDIER_GENERATION_TIMER ; soldier generation timer 1739 ldy GAME_COMPLETION_COUNT ; load the number of times the game has been completed 1740 beq @adjust_timer_for_weapon ; branch if haven't yet beat the game any times 1741 tya 1742 cmp #$04 ; compare GAME_COMPLETION_COUNT to #$04 1743 bcc @continue ; branch if GAME_COMPLETION_COUNT < #$04 1744 ldy #$03 ; maximum multiplier of increase chance for generating soldier is #$03 ⋮ 1747 lda #$28 ; lower soldier generation timer ⋮ 1752 ldy PLAYER_WEAPON_STRENGTH ; load player weapon strength (damage strength) 1753 beq @exit ; don't generate if player's weapon strength is #$00 ⋮
src/bank2.asm lines 1736–1779 at 687d651 · upstream ↗ 3270 inc GAME_COMPLETION_COUNT ; increment game completion count, used mainly to increase enemy difficulty every play-throughsrc/bank7.asm line 3270 at 687d651 · upstream ↗ 3920set_frame_scroll_weapon_strength: ⋮ 3926 sta PLAYER_WEAPON_STRENGTH ; clear player weapon strength
src/bank7.asm lines 3920–3926 at 687d651 · upstream ↗ 4096set_player_weapon_strength: ⋮ 4102 lda weapon_strength,y ; load how strong the weapon is 4103 cmp PLAYER_WEAPON_STRENGTH ; compare against current weapon strength 4104 bcc @exit ; exit and do not lower player's current weapon strength 4105 sta PLAYER_WEAPON_STRENGTH ; store current weapon strength code (#$00-#$03) ⋮ 4111weapon_strength: 4112 .byte $00 ; Regular = Weak 4113 .byte $02 ; M = Strong 4114 .byte $01 ; F = Medium 4115 .byte $03 ; S = Very Strong 4116 .byte $02 ; L = Strong
src/bank7.asm lines 4096–4116 at 687d651 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abThe US NES Super C takes 16 off the delay between random enemies once the game has been beaten and 4 for each living player holding the spread gun. The delay's start is read from an eight-entry per-level table with an index that isn't the level; the disassembly reads it as always
$80, a value the table doesn't hold, and the atlas hasn't confirmed it. Where Contra counts loops up to 3, Super C keeps a beaten-once flag that stays at 1; where Contra reads every gun's strength, Super C counts only the spread gun.Codevermiceli/nes-super-c · vermiceli/nes-contra-usrevisedHow we know
3755enemy_gen_routine_00: 3756 lda CURRENT_LEVEL ; !(BUG) a is immediately overwritten 3757 ; this should probably have been ldy CURRENT_LEVEL 3758 lda level_enemy_gen_delay_tbl,y ; y is actually PRG bank number, e.g. #$33 and not current level 3759 ; this causes the delay to always be #$80 ⋮ 3762 ldy GAME_COMPLETED ; load whether or not the game has been completed 3763 beq @adj_for_difficulty ; branch if haven't beaten the game yet ⋮ 3770 lda #$10 3771 jsr @set_enemy_gen_delay ; subtract #$10 * GAME_COMPLETED from ENEMY_GEN_DELAY ⋮ 3775 ldy ENEMY_DIFFICULTY ; load current difficulty 3776 beq @adv_routine ; branch to not adjust initial enemy generation delay 3777 lda #$04 ; difficulty is non-zero, subtract #$04 * ENEMY_DIFFICULTY from ENEMY_GEN_DELAY
src/bank-0.asm lines 3755–3779 at be6ccce · upstream ↗ 4286level_enemy_gen_delay_tbl: 4287 .byte $7b,$53,$53,$53,$53,$53,$53,$53
src/bank-0.asm lines 4286–4287 at be6ccce · upstream ↗ 165; calculate ENEMY_DIFFICULTY based on number of active players with S weapon ⋮ 172 lda PLAYER_CURRENT_WEAPON,x ; 0 = Regular, 1 = M, 2 = S, 3 = L, 4 = F 173 and #$0f ; strip rapid fire flag 174 cmp #$02 ; compare to S weapon 175 bne @next_player ; move to next player if current player doesn't have S weapon 176 iny ; increment number of players in normal state that have the S weapon ⋮ 181 sty ENEMY_DIFFICULTY ; set enemy difficulty
src/bank-0.asm lines 165–181 at be6ccce · upstream ↗ 2421 lda GAME_COMPLETED ; load whether or not the game has been completed 2422 adc #$00 ; increment game completion count (carry is set) 2423 cmp #$02 ; see if game already completed 2424 bcc @continue ; branch if first time completing game to set value to #$01 2425 lda #$01 ; game already beaten at least once, keep value of #$01 (don't set to #$02)
src/bank-f.asm lines 2421–2431 at be6ccce · upstream ↗ 1736adjust_generation_timer: ⋮ 1742 cmp #$04 ; compare GAME_COMPLETION_COUNT to #$04 1743 bcc @continue ; branch if GAME_COMPLETION_COUNT < #$04 1744 ldy #$03 ; maximum multiplier of increase chance for generating soldier is #$03 ⋮ 1752 ldy PLAYER_WEAPON_STRENGTH ; load player weapon strength (damage strength)
src/bank2.asm lines 1736–1757 at 687d651 · upstream ↗ 4111weapon_strength: 4112 .byte $00 ; Regular = Weak 4113 .byte $02 ; M = Strong 4114 .byte $01 ; F = Medium 4115 .byte $03 ; S = Very Strong 4116 .byte $02 ; L = Strong
src/bank7.asm lines 4111–4116 at 687d651 · 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.
- ^ abcEach player's saucer reload value starts at 146 when a game starts and drops by 6 each time a saucer appears, as long as the result stays 32 or more. While it is 128 or more, every saucer is the large one. Below 128, a player with 30,000 points or more always gets the small saucer; under 30,000 a random byte decides, giving the small saucer when the byte is more than half the reload value: about 3 in 4 at the first chance (122) and about 15 in 16 at the floor of 32 (computed, for evenly spread bytes).CodeComputer Archeology, Asteroidsrevised
How we know
LDA #$92 STA $02F8 ; {ram.saucerTimeReload} … STA $02F7 ; {ram.saucerTimer} Countdown Timer For When Saucer Appears
content/Arcade/Asteroids/Code.md#L136-L140 · upstream ↗ LDA $02F8 ; {ram.saucerTimeReload} SEC SBC #$06 ; Shorten Time Between Saucer Appearence CMP #$20 ; At Lowest Value? BCC $6BDD ; {} Yes, Branch STA $02F8 ; {ram.saucerTimeReload} Make The Update
content/Arcade/Asteroids/Code.md#L483-L488 · upstream ↗ LDX #$02 ; Start With Large Saucer LDA $02F8 ; {ram.saucerTimeReload} Start Checking Score When @ #$7F And Below BMI $6C30 ; {} Not There Yet, Branch Around Score Check … CMP #$30 ; 30,000 Points Or More? BCS $6C2F ; {} Yes, Branch JSR $77B5 ; {} STA $08 ; {ram.$08} LDA $02F8 ; {ram.saucerTimeReload} LSR A CMP $08 ; {ram.$08} BCS $6C30 ; {} Going To Be A large Saucer, Branch …
content/Arcade/Asteroids/Code.md#L512-L527 · 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.
- ^ abBetween shots, a live saucer counts down 10 runs of its routine, which runs every fourth frame (40 frames, computed), and the count pauses while the player's ship is waiting to return. The large saucer fires in a random direction, any of 256. The small saucer aims: it takes the ship's position minus its own on each axis, subtracts half the saucer's velocity, turns the pair into a direction with an arctangent routine, and adds a random error of −16 to +15 directions while the player has under 35,000 points, and −7 to +8 from 35,000.CodeComputer Archeology, Asteroids
How we know
LDA $5C ; {ram.fastTimer} AND #$03 BEQ $6B9A ; {} RTS
content/Arcade/Asteroids/Code.md#L457-L460 · upstream ↗ LDA $1C ; {ram.numPlayers} Number Of Players In Current Game BEQ $6C4E ; {} None, Branch LDA $02FA ; {ram.shipSpawnTimer} BNE $6C53 ; {} DEC $02F7 ; {ram.saucerTimer} Time for saucer to shoot? BEQ $6C54 ; {} Yes, branch? RTS LDA #$0A ; Time Between Saucer Shots STA $02F7 ; {ram.saucerTimer} Reset for next shot LDA $021C ; {ram.statusSaucer} Saucer Flag LSR A ; Check Saucer Size BEQ $6C65 ; {} Branch If Small One …
content/Arcade/Asteroids/Code.md#L536-L604 · upstream ↗ TYA BPL $76FC ; {} … EOR #$80 EOR #$FF … LDA #$20 RTS JSR $776C ; {} LDA $772F,X ; {}
content/Arcade/Asteroids/Code.md#L1867-L1898 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
Sources
Code
- (vermiceli), Michael Miceli. 2026. “Contra (US), annotated disassembly (vermiceli).” Commit 687d651. vermiceli/nes-contra-us @ 687d651 · licence, all uses
- (vermiceli), Michael Miceli. 2026. “Super C (US), annotated disassembly (vermiceli).” Commit be6ccce. vermiceli/nes-super-c @ be6ccce · licence, all uses
- Howell, Lonnie, Mark McDougall, and Christopher Cantrell. 2026. “Computer Archeology: Asteroids.” Commit 1adc2a7. topherCantrell/computerarcheology @ 1adc2a7 · licence, all uses