Document GAME_COMPLETION_COUNT

This commit is contained in:
Michael Miceli 2023-06-18 19:33:08 -04:00
parent d2e6d9996c
commit def22881be
4 changed files with 195 additions and 11 deletions

View File

@ -0,0 +1,181 @@
# Overview
_Contra_ is already a challenging game. However, it gets even more difficult
the more times you beat the game. This documents the ways in which beating the
game affects the behavior of subsequent playthoughs.
The game keeps track of the number of times the player(s) beat the game in the
variable `GAME_COMPLETION_COUNT`, located at CPU memory address `$31`.
Many of the HP modifications are also based on the player's "weapon strength".
This variable, called `PLAYER_WEAPON_STRENGTH`, is stored at CPU memory address
`$2f` and depends on which weapon player 1 has.
| Weapon | Strength |
|---------|----------|
| Default | 0 |
| M | 2 |
| F | 1 |
| S | 3 |
| L | 2 |
# Soldier Generation
Random soldiers are generated more quickly the more you beat the game up until
you've beaten the game 3 times. The actual delay depends on the level. Each
time you beat the game, the delay is lowered by 40 (assuming the weapon player
1 has is the same).
Soldier generation delay is calculated by the following formula
```
DELAY = INITIAL_LEVEL_DELAY - (40 * GAME_COMPLETION_COUNT) - (5 * PLAYER_WEAPON_STRENGTH)
```
| Completion Count | Result (hex) | Result (decimal) |
|------------------|--------------|------------------|
| 0 | #$81 | 129 |
| 1 | #$59 | 89 |
| 2 | #$31 | 49 |
| 3 | #$09 | 9 |
| 4 | #$09 | 9 |
All sample results assume the player's `PLAYER_WEAPON_STRENGTH` is 3 (S weapon)
and the level is 1 where the initial delay is 144. The initial level delays are
as follows (defined in `level_soldier_generation_timer`)
| Level | Delay (decimal) |
|-------|-----------------|
| 1 | 144 |
| 2 | n/a |
| 3 | 216 |
| 4 | n/a |
| 5 | 208 |
| 6 | 200 |
| 7 | 192 |
| 8 | n/a |
# Red Turret Attack Delay
Red turret attack delay is shorter if you've beaten the game once. It doesn't
get any short for subsequent wins.
| Completion Count | Result (hex) | Result (decimal) |
|------------------|--------------|------------------|
| 0 | #$28 | 40 |
| 1 | #$08 | 8 |
# Alien Fetus (Bundle) HP
The level 8 alien fetus (bundle) HP goes up as you beat the game more and more.
It is the number of times you've beaten the game + 2, so the HP goes up by 1
every time the game is beaten (until max 255 due to memory limit).
```
GAME_COMPLETION_COUNT + 2
```
| Completion Count | Result (hex) | Result (decimal) |
|------------------|--------------|------------------|
| 0 | #$02 | 2 |
| 1 | #$03 | 3 |
| 2 | #$04 | 4 |
| 3 | #$05 | 5 |
| 4 | #$06 | 6 |
| 5 | #$07 | 7 |
| ... | ... | ... |
| 253 | #$ff | 255 |
| 254 | #$00 | 0 (invincible) |
| 255 | #$01 | 1 |
# Alien Mouth (Wadder) HP
The level 8 alien mouth (wadder) HP goes up as you beat the game more and more.
The HP is calculated by the following formula
```
(2 * GAME_COMPLETION_COUNT) + PLAYER_WEAPON_STRENGTH + 4
```
| Completion Count | Result (hex) | Result (decimal) |
|------------------|--------------|------------------|
| 0 | #$07 | 7 |
| 1 | #$09 | 9 |
| 2 | #$0b | 11 |
| 3 | #$0d | 13 |
| 4 | #$0f | 15 |
| 5 | #$11 | 17 |
| ... | ... | ... |
| 124 | #$ff | 255 |
| 125 | #$01 | 1 |
| ... | ... | ... |
| 252 | #$00 | 0 (invincible) |
All sample results assume the player's `PLAYER_WEAPON_STRENGTH` is 3 (S weapon).
# Alien Spider (Bugger) HP
Level 8 alien spiders (buggers) HP goes up as you beat the game more and more.
The HP is calculated by the following formula
```
PLAYER_WEAPON_STRENGTH + GAME_COMPLETION_COUNT + 2
```
| Completion Count | Result (hex) | Result (decimal) |
|------------------|--------------|------------------|
| 0 | #$05 | 5 |
| 1 | #$06 | 6 |
| 2 | #$07 | 7 |
| 3 | #$08 | 8 |
| 4 | #$09 | 9 |
| 5 | #$0a | 11 |
| ... | ... | ... |
| 250 | #$ff | 255 |
| 251 | #$00 | 0 (invincible) |
| 252 | #$02 | 2 |
All sample results assume the player's `PLAYER_WEAPON_STRENGTH` is 3 (S weapon).
# Alien Spider Spawn (Eggron) HP
```
(GAME_COMPLETION_COUNT * 2) + (PLAYER_WEAPON_STRENGTH * 2) + 24
```
| Completion Count | Result (hex) | Result (decimal) |
|------------------|--------------|------------------|
| 0 | #$1e | 30 |
| 1 | #$20 | 32 |
| 2 | #$22 | 34 |
| 3 | #$24 | 36 |
| 4 | #$26 | 38 |
| 5 | #$28 | 40 |
| ... | ... | ... |
| 112 | #$fe | |
| 113 | #$00 | 0 (invincible) |
| 114 | #$02 | 2 |
All sample results assume the player's `PLAYER_WEAPON_STRENGTH` is 3 (S weapon).
# Alien Guardian & Boss Heart HP
The level 8 alien guardian and boss heart (final boss) HP are both calculated
according to the same formula below until the calculated HP is greater than or
equal to #$a0 (160 decimal). 160 is the max HP the alien guardian and boss
heart can be.
```
(PLAYER_WEAPON_STRENGTH * 16) + 55 + (GAME_COMPLETION_COUNT * 16)
```
| Completion Count | Result (hex) | Result (decimal) |
|------------------|--------------|------------------|
| 0 | #$67 | 103 |
| 1 | #$77 | 119 |
| 2 | #$87 | 135 |
| 3 | #$97 | 151 |
| 4 | #$a0 | 160 |
| 5 | #$a0 | 160 |
All sample results assume the player's `PLAYER_WEAPON_STRENGTH` is 3 (S weapon).

View File

@ -9539,10 +9539,11 @@ alien_mouth_routine_ptr_tbl:
.addr enemy_routine_remove_enemy ; CPU address $e806 from bank 7 .addr enemy_routine_remove_enemy ; CPU address $e806 from bank 7
; set mouth hp and draw open mouth super-tile ; set mouth hp and draw open mouth super-tile
; alien mouth hp = (#$02 * GAME_COMPLETION_COUNT) + (PLAYER_WEAPON_STRENGTH + #$03) ; alien mouth hp = (#$02 * GAME_COMPLETION_COUNT) + (PLAYER_WEAPON_STRENGTH + #$04)
alien_mouth_routine_00: alien_mouth_routine_00:
lda PLAYER_WEAPON_STRENGTH ; load player's weapon strength lda PLAYER_WEAPON_STRENGTH ; load player's weapon strength
adc #$03 ; add #$03 to player weapon strength adc #$03 ; add #$04 to player weapon strength (carry is always set here)
; because the carry flag is set from the cmp #$10 check before to run `exec_level_enemy_routine`
sta $08 ; store PLAYER_WEAPON_STRENGTH + #$03 in $08 sta $08 ; store PLAYER_WEAPON_STRENGTH + #$03 in $08
lda GAME_COMPLETION_COUNT ; load the number of times the game has been completed lda GAME_COMPLETION_COUNT ; load the number of times the game has been completed
asl ; double the number of times the game has been completed asl ; double the number of times the game has been completed
@ -9919,12 +9920,14 @@ alien_spider_set_ground_vel_and_routine:
lda #$04 ; a = #$04 lda #$04 ; a = #$04
jmp set_enemy_routine_to_a ; set routine to alien_spider_routine_03 jmp set_enemy_routine_to_a ; set routine to alien_spider_routine_03
; alien spider hp = weapon strength + completion count + 1 ; alien spider hp = weapon strength + completion count + 2
;
set_alien_spider_hp_sprite_attr: set_alien_spider_hp_sprite_attr:
lda PLAYER_WEAPON_STRENGTH ; load player weapon strength lda PLAYER_WEAPON_STRENGTH ; load player weapon strength
adc GAME_COMPLETION_COUNT ; add with the number of times the game has been completed adc GAME_COMPLETION_COUNT ; add with the number of times the game has been completed
adc #$01 ; add #$01 adc #$01 ; add #$01
sta ENEMY_HP,x ; set enemy hp (weapon strength + completion count + 1) sta ENEMY_HP,x ; set enemy hp (weapon strength + completion count + 2)
; 2 because the carry flag is set from the cmp #$10 check before to run `exec_level_enemy_routine`
lda #$60 ; a = #$60 lda #$60 ; a = #$60
sta ENEMY_ANIMATION_DELAY,x ; set enemy animation frame delay counter sta ENEMY_ANIMATION_DELAY,x ; set enemy animation frame delay counter
lda ENEMY_Y_POS,x ; load enemy y position on screen lda ENEMY_Y_POS,x ; load enemy y position on screen

View File

@ -4062,13 +4062,12 @@ set_player_weapon_strength:
rts rts
; table for weapon strength code (#$05 bytes) ; table for weapon strength code (#$05 bytes)
; Regular = Weak
; M = Strong
; F = Medium
; S = Very Strong
; L = Strong
weapon_strength: weapon_strength:
.byte $00,$02,$01,$03,$02 .byte $00 ; Regular = Weak
.byte $02 ; M = Strong
.byte $01 ; F = Medium
.byte $03 ; S = Very Strong
.byte $02 ; L = Strong
; run logic based on players current state ; run logic based on players current state
; #$00 falling into level ; #$00 falling into level

View File

@ -32,7 +32,8 @@ DELAY_TIME_HIGH_BYTE = $2b ; the high byte of the delay
LEVEL_ROUTINE_INDEX = $2c ; the index into level_routine_ptr_tbl of the routine to run LEVEL_ROUTINE_INDEX = $2c ; the index into level_routine_ptr_tbl of the routine to run
END_LEVEL_ROUTINE_INDEX = $2d ; offset into either end_level_sequence_ptr_tbl or end_game_sequence_ptr_tbl END_LEVEL_ROUTINE_INDEX = $2d ; offset into either end_level_sequence_ptr_tbl or end_game_sequence_ptr_tbl
DEMO_FIRE_DELAY_TIMER = $2e ; the number of frames to delay before starting to fire when demoing DEMO_FIRE_DELAY_TIMER = $2e ; the number of frames to delay before starting to fire when demoing
PLAYER_WEAPON_STRENGTH = $2f ; the damage strength of the player's current weapon (see weapon_strength) bits 0-2 of P1_CURRENT_WEAPON,x PLAYER_WEAPON_STRENGTH = $2f ; the damage strength of the player's current weapon (see weapon_strength) based on bits 0-2 of P1_CURRENT_WEAPON,x
; Default = #$00, M = #$02, F = #$01, S = #$03, L = #$02
CURRENT_LEVEL = $30 ; #$00-#$09, #$00 to #$07 represent levels 1 through 8. #$9 is interpreted as game over sequence CURRENT_LEVEL = $30 ; #$00-#$09, #$00 to #$07 represent levels 1 through 8. #$9 is interpreted as game over sequence
GAME_COMPLETION_COUNT = $31 ; the number of times the game has been completed (final boss defeated) GAME_COMPLETION_COUNT = $31 ; the number of times the game has been completed (final boss defeated)
P1_NUM_LIVES = $32 ; P1 number of lives, #$00 is last life, on game over stays #$00, but P1_GAME_OVER_STATUS becomes #$01 P1_NUM_LIVES = $32 ; P1 number of lives, #$00 is last life, on game over stays #$00, but P1_GAME_OVER_STATUS becomes #$01