One Hit Kills

Abystus
I'm not sure if there is a tutorial for this yet (I did do some searching both in the library and through the forums.) so I decided to make this one.

Basically this is for the people still using several codes to achieve "One Hit Kills" by setting each enemy's health to 0. Most games have a death routine for their enemies, and we should take advantage of this so we can make the most compact code possible.

First we need to find any enemy health address (you should know how to do this by now). Our example address is $0626. Now that we have our health address what we need to do is set a BPW (Break on Write) to this address. From this point we have 2 options:

    Turn on the Tracer, strike the enemy and wait for the break. (My preferred method.)
    Strike the enemy, wait for the break. (Finding the death routine manually can be a pain.)


Our debugger will snap to the below ($D151):

Enemy Damage Routine (In this game it handles all standard enemy damage. This excludes bosses.)


$D147:BD 21 06  LDA $0621,X @ $0626 = #$04
$D14A:38        SEC
$D14B:E5 10     SBC $0010 = #$03
$D14D:90 4B     BCC $D19A
$D14F:F0 49     BEQ $D19A
$D151:9D 21 06  STA $0621,X @ $0626 = #$04 //We break here when an enemy is struck.


So now we just keep hitting the enemy until on the last hit the debugger snaps to the below ($D19C):


Enemy Death Routine (In this game it handles all standard enemy deaths. This excludes bosses.)



$D19A:A9 00     LDA #$00 //Load our Accumulator with 00 since our enemy is now considered dead.
$D19C:9D 21 06  STA $0621,X @ $0626 = #$04 //We break here.  Store the accumulator to make the enemy die.


Now for all you wondering how we got to this location that were not using a tracer please repeat the previous step with the tracer on. Most of the time this will be close to where the enemy damage routine is but this is not always the case. I personally prefer the tracer to make things simple especially if there are multiple branches involved before our stop at the death routine.

Now if you had your tracer on you would notice the last branch before the storing 0 to the enemy health address was [D14D:90 4B BCC $D19A].

We are wanting to make the branch above always happen when striking our enemies. To do this we make the following modification below in blue:


$D147:BD 21 06  LDA $0621,X @ $0626 = #$04
$D14A:38        SEC
$D14B:E5 10     SBC $0010 = #$03
$D14D:10 4B     BPL $D19A //Changing this to a BPL will automatically send us to the death routine everytime an enemy is struck with an attack.
$D14F:F0 49     BEQ $D19A
$D151:9D 21 06  STA $0621,X @ $0626 = #$04 //We break here when an enemy is struck.


Our Code: D14D10

Take note that some games such as this one will use a different damage/death routine for bosses than for normal enemies. If this is the case most if not all bosses will share the same routines such as these standard enemies do with each other. 


_________________________________



In addition to my other method of "One Hit Kills" there is yet another method available if you cannot seem to find the death routine or the game has strange coding when it comes to dealing with distributing damage. This method is to load the initial enemy health addresses with the lowest value possible with out instantly killing the enemies (usually 01), or in the case of Battletoads we want to load 00 into the enemy addresses as soon as they are initialized. To accomplish this we first need to find any enemy health address like before but this time we set a Break on Write to the address and wait for an enemy that uses our address to spawn in the game.

Our example enemy heath address for Battletoads is $051C. So we begin our journey below:

    Start your Trace Logger (Not really used in this tutorial, but it's good practice.)
    Set a Break on Write in the debugger on your enemy health address ($051C)
    Wait for a break that occurs when no enemies are on the screen but you are moving into a new area where enemies usually spawn (the value being written will be greater than 0).


Our debugger will snap to the below($D383):

Initialize Enemy Health Routine:


$D37F:B1 B7     LDA ($B7),Y @ $E88B = #$10 
$D381:09 0F     ORA #$0F  
$D383:9D 1A 05  STA $051A,X @ $051C = #$00


In Battletoads enemies don't die instantly when their health value is set to 0. It more or less gives you the ability (at any time) to perform the wacky finishing moves that this game is known for. Also in this game the routine that controls initializing enemy health is used for both normal and boss type enemies which is always a plus. So to make the smallest modification necessary to achieve our "One Hit Kills" for this game, we have to make the following change highlighted in blue:


$D37F:B1 B7     LDA ($B7),Y @ $E88B = #$10 
$D381:09 0F     ORA #$0F  
$D383:B9 1A 05  LDA $051A,X @ $051C = #$00


Instead of modifying the section that loads the value to be stored, we reversed the STA to a LDA (preventing the write of the health value resulting in the health address remaining at 0). Since the LDA is loading it's value from a non constant address it would require us to change both the instruction and load value (resulting in 2 separate codes). Doing it this way (modifying the STA) saved us the need for an additional code if we had chosen to modify the LDA instead.

Our Code: D383B9

In many games this type of alteration would result in enemies immediately dying when they are initialized, however some games (like this one) require an attack routine to completely dispose of it's enemies.