Patch:Sprite Collision Tutorial

From KeenWiki
Jump to navigation Jump to search

This page deals with writing new sprite collisions for Commander Keen games. This will allow sprites to interact in different ways than they do by default. The page is divided into a number of sections, one for each game, and assumes familiarity with Patch:Sprite collision and Patch:Jump conditions. Each section is in turn divided into three subsections. The first subsection deals with fragments of code used in each game for specific things. The second subsection dissects some existing collisions in terms of previously covered code fragments. Finally the third subsection will list novel collisions not encountered in-game, also explained in terms of previously covered code fragments.

These sections will be preceded by a brief overview of collisions.

THIS PAGE CURRENTLY UNDERGOING REWRITE TO NEW FORMAT.


Collision overview

Keen Vorticons

In Keen 1-3 the collision code covers what a sprite will interact with as well as what happens. As such there are only two patches required to create a new collision. The first is the new code itself, which will either replace an old collision or uses some free space in the executable and the second makes a sprite use that new code.

As an example the following patch makes the Yorp use the Tank Robot collision (That is, it is immortal.)

Keen 1: Yorp uses Tank-bot-like collision

#New collision code: Do nothing
%patch $1A68 $55 $8B $EC $5D $C3
%patch $18D9 $1A68W #Make Yorp use new collision


Notice that the location of the collision is 'pointed to' in the second patch. The second line is not necessary in this case as it is the same as the default value. In this case we have 'orverwritten' the original Yorp collision with the new one.

The main consideration when patching a new collision is how much space is available for the new collision code. The simple 'indestructible' collision used here is only 5 bytes long and can be fit nearly anywhere. Other collision codes are larger, and if the size of the code you patch is larger than the space you have available, then you will overwrite other data and likely corrupt the game.


Keen 1

Code fragments

Change sprite's parameters (Speed, animation, action, etc)

The most basic code fragments are five byte strings used to change a sprite's parameters. Following the previous link will show that the following fragment of code changes a sprite's behavior to $489D, or that of a stunned sprite. There are 13 qualitatively different parameters to alter which control everything from the sprite's speed to its animation, direction or current behavior. As such these are used frequently in collisions; indeed making up the bulk of their code.

$C7 $44 $32 $489DW


Play sound

This code plays a sound when run. It takes one variable, the sound to play. (Anything from $0-$4F.) Complicating matters is the fact that its 'call' must be changed when the location of the code is changed. The call goes to $BEF3 and is located at $1A9B in this example. ($BEF3 - $198B - $7 = $A451.)

$B8 $00xxW  $50 $E8 $A451W  $44 $44


Border flash

This is a simple call to the border flashing code that is used only by the Vorticon. As with the sound playing code above, its call must be altered with its location. This example from the Vorticon code is located at $1DAF and calls the code at $297E.

$E8 $0BCCW


Standard stunning code

When a sprite is shot and stunned 'in the usual manner' several code fragments are combined into a 'standard stunning code' that is broadly similar across various collisions. (This example is from the Yorp collision.) It consists of three smaller fragments. The first sets the action timer to 0, the second sets how many frames of animation the stunned sequence contains. The third sets the first animation the stunned sequence will use. The fourth sets the sprite's behavior to stunned and the fifth sets its collision to 'nothing' so it can't be stunned a second time. If any one of these is missed the stunning sequence will not work correctly.

$C7 $44 $2A $0000W  $C7 $44 $2C $0002W  $C7 $44 $28 $003AW
$C7 $44 $32 $489DW  $C7 $44 $34 $3360W


Existing collisions and their components

Tank collision

This is the Tank Robot's collision code. It is so short because it basically means 'Do nothing'; the Tank is not affected by any sprites at all. This is the most basic collision a sprite can have. (It must have some sort of collision.)

Tank collision: Indestructible

#Tank Robot collision (5 bytes long)
%patch $2045 55 $8B $EC $5D $C3


Yorp collision

This collision is used by the Yorp. It reacts to either Keen's shot or the Tank Robot's shot. It uses the 'standard stun' code with the addition of a code fragment to give it an upwards speed boost. It also plays a sound when run. (The stunned Yorp sound.)

Yorp collision

#Yorp collision (64 bytes long)
%patch $1A68 $55 $8B $EC $56 $57 $8B $76 $04 $8B $7E $06 $83 $3D [$0A] {$74} $05
             $83 $3D [$0B] {$75} $27 $C7 $44 $2A [$0000W]  $C7 $44 $2C [$0002W]  $C7
             $44 $28 [$003AW]  $C7 $44 $32 [$489DW]  $C7 $44 $34 [$3360W]  $C7 $44
             $22 [$FFB0W]  $B8 [$0022W]  $50 $E8 {$A451W}  $44 $44 $5F $5E $5D $C3


Vorticon collision

The Vorticon's collision is the most complex in the game, but it too is little more than standard stunning code (but using 6 frames instead of the usual 2.) Notice however that unlike the Yorp above the sound playing code is first. Also the function of the last two lines of code is currently unknown.

Vorticon collision

#Vorticon collision (78 bytes)
%patch $1D6E $55 $8B $EC $56 $57 $8B $76 $04 $8B $5E $06 $83 $3F [$0A] {$74} $05
             $83 $3F [$0B] {$75} $40 $8B $44 $24 $FF $4C $24 $0B $C0 $75 $36 $B8
             [$0027W]  $50 $E8 $A15FW  $44 $44 $C7 $44 $2A [$0000W]  $C7 $44 $2C
             [$0006W]  $C7 $44 $28 [$0052W]  $C7 $44 $34 [$3360W]  $C7 $44 $32 [$489DW]
                 {$E8 $0BCCW}  $8B $F8 $C7 $45 $08 [$0005W] $C7 $45 $22 [$4A45W]
             $C7 $45 $0A [$0000W] $5F $5E $5D $C3

Keen 4

Code fragments

Change sprite's parameters (Speed, animation, action, etc)

The most basic code fragments are six byte strings used to change a sprite's parameters. Following the previous link will show that the following fragment of code changes a sprite's action to $1F46, or that of the raindrop splashing. There are 17 qualitatively different parameters to alter which control everything from the sprite's speed to its animation, direction or current action. As such these are used frequently in collisions.

$C7 $44 $1C $1F46W


Kill Keen

This five bye code fragment kills Keen. This will happen wherever he is, even if he is not touching the sprite that uses it. (This will not overrule god mode.) It is thus possible for one sprite to shoot another and cause Keen to die when he is on the other side of the screen. By default however it is used exclusively to react to Keen when he touches a sprite.

$9A $0B8013E9RL


Block Keen's shot

This code fragment will turn the colliding sprite's action to a smashed version of Keen's shot and play the shot smash sound. The target sprite remains unaffected.

$57 $9A $0D8F0D43RL $83 $C4 $02


Block Keen's shot, stun

This code fragment will turn the colliding sprite's action to a smashed version of Keen's shot, play the shot smash sound and change the target sprite's action into the one listed in the code fragment. Only what the target sprite becomes can be changed.

$B8 $xxxxW  $50 $57 $56 $9A $09DC1695RL $83 $C4 $06


Change action

This somewhat complicated piece of code simply changes a sprite's current action, but in a slightly more complex way than $C7 $44 $1C $xxxxW does. It can also do so in several ways. It takes two variables, though this can be hard to see. The first variable is the action to change to. The main difference between this code and $C7 $44 $1C $xxxxW is that this code causes the sprite to wait until its current action time is up, meaning there will be some delay between when the sprite is 'triggered' and when it responds. It also sets a number of other, more subtle parameters. This thus presents a more nuanced way of handling action changes to be sued when the simple approach fails.

There are several ways the code may be run, with slightly different results. Each is given a line here.

$B8 $xxxxW  $50 $FF $76 $06 $9A $09DC120ARL     $83 $C4 $04
$B8 $xxxxW  $50 $56 $9A $09DC120ARL     $83 $C4 $04


Create new sprite

This code creates an entirely new sprite. This is used not only in collisions, but also behaviors, when a sprite shots for example. It is also used when a sprite is first created. It takes one variable, 'sprite creation type' that is either 0 or 1. What this code does is create a new sprite and set 'all' of its variables to certain default values (That differ depending on the creation type.) This simplifies what would otherwise be a complicated piece of code. However there are still some variables that will need to be set after this code is run to avoid the game crashing.

This results in the complete code being a segment of spawn code, containing code segments found on this page an example of which is listed also in this section. The sprite's relative position and its action must be defined, other variables are optional. In the example below the sprite's type is set to 1, its activity variable is set to 3, it's vertical position $FFE4W from its creator sprite (up a bit.) and finally its vertical speed to $FFD8W. Then the 'change action' code is run, changing its action to $215CW.

Note that the created sprite's variable code differs from that used elsewhere on this page. It uses $C7 $47 instead of $C7 $44. This keeps it distinct from its 'parent' sprite.

Sprite creation code
$B8 $0001W  $50 $9A $06BD1E11RL     $83 $C4 $02
Set up new sprite code example
$8B $1E $D8 $A7 $C7 $07 $0001W  $C7 $47
$02 $0003W  $8B $44 $0A $89 $47 $0A $8B $44 $0C $89 $47 $0C $C7
$47 $16 $FFE4W  $C7 $47 $18 $FFD8W  $B8 $215CW  $50 $53 $9A
$09DC118CRL $83 $C4 $04


Existing collisions and their components

Stunned Blue Bird collision

This collision is used by the Blue Bird when it is already stunned. It can be seen that it responds only to Keen's shot type ($03) and that when it does so it executes two pieces of code. The first is a sprite variable change that sets its horizontal speed to 0. The second is a 'stop shot and stun' that turns the Bird into the stunned bird. ('Resetting' its stun time.)

Blue bird collision

%patch $102FA $55 $8B $EC $56 $57 $8B $76 $06 $8B $7E $08 $83 $3D [$03] {$75} $13
              $C7 $44 $16 [$0000W]  $B8 [$22E2W]  $50 $57 $56 {$9A $09DC1695RL}
              $83 $C4 $06 $5F $5E $5D $CB


Blue Bird collision

This collision is used by the Blue Bird normally. It reacts to two sprite types; Keen and his shot. When reacting to Keen it runs the 'kill Keen' code. When reacting to Keen's shot it runs three code fragments. The first two are sprite variable changes and set the Bird's horizontal speed to 0 and its clipping to 1. (The first because it is stunned, the second because the flying bird needs a different clipping to the stunned bird.) the third fragment is the 'stun and block Keen's shot' code.

Blue bird collision

%patch $102C0 $55 $8B $EC $56 $57 $8B $76 $06 $8B $7E $08 $83 $3D [$02] {$75} $09
              {$9A $0B8013E9RL}     $5F $5E $5D $CB $83 $3D [$03] {$75} $18 $C7 $44
              $16 [$0000W]  $C7 $44 $06 [$0001W]  $B8 [$22E2W]  $50 $57 $56 {$9A $09DC1695RL}
                          $83 $C4 $06 $5F $5E $5D $CB


Sleeping Cloud collision

This collision is used by the sleeping Cloud; it reacts to Keen only and executes one piece of code, that to change its action to a waking cloud.

Keen 4

#Cloud collision
%patch $10B7D $55 $8B $EC $56 $8B $76 $08 $83 $3C [$02] {$75} $0F $B8 [$28BEW]  $50
              $FF $76 $06 $9A {$09DC120ARL}     $83 $C4 $04 $5E $5D $CB


Egg collision

The Egg's collision looks exceedingly complex; however it can be broken up into smaller segments which can be easily explained. The first thing to focus on is its reactions to Keen and his shot. This is slightly circuitous.

On the first line if Keen's shot type is detected then the check for Keen's type is skipped. After the check for Keen's type the code checks to see again whether it is dealing with Keen's shot. If so it executes the first code fragment, the 'stop Keen's shot' code. The rest of the code is the same for Keen and his shot.

The first thing done is to change the Egg into a large shell fragment. To do this two sprite variables are changed (Type and sprite activity variable.) and the 'change action' code run.

Following this a series of other sprites is created out of thin air using the 'create new sprite' code. In total four sprites are created and their variables set. This makes up the bulk of the collision code. The Bird's creation code is complicated by a code segment that makes it check for Keen and face him.

Keen 4

#Egg collision
%patch $100A7 $55 $8B $EC $56 $57 $8B $76 $06 $8B $7E $08 $83 $3D [$03] {$74} $08
              $83 $3D [$02] {$74} $03 $E9 {$0136W}  $83 $3D [$03] {$75} $09 $57 $9A
              $0D8F0D43RL $83 $C4 $02 $C7 $04 [$0001W]  $C7 $44 $02 [$0003W]  $B8 #Make large shell
              [$213EW]  $50 $56 $9A $09DC120ARL     $83 $C4 $04 $B8 $0001W  $50
              $9A $06BD1E11RL     $83 $C4 $02 $8B $1E $D8 $A7 $C7 $07 [$001BW]  #Make Bird
              $C7 $47 $02 [$0001W]  $8B $44 $0A $89 $47 $0A $8B $44 {$0C $2D} [$0080W]
%patch $10108     $89 $47 $0C $8B $44 $0A $8B $1E $A7D6W  $3B $47 $0A {$73} $0B
              $8B $1E $D8 $A7 $C7 $47 $0E [$0001W]  $EB $09 $8B $1E $D8 $A7 $C7
              $47 $0E [$FFFFW]  $8B $1E $D8 $A7 $C7 $47 $10 [$0001W]  $B8 [$21B6W]
              $50 $53 $9A $09DC118CRL     $83 $C4 $04 $B8 [$0001W]  $50 $9A
              $06BD1E11RL $83 $C4 $02 $8B $1E $D8 $A7 $C7 $07 [$0001W]  $C7 $47 #Make left shell
              $02 [$0003W]  $8B $44 $0A $89 $47 $0A $8B $44 $0C $89 $47 $0C $C7
              $47 $16 [$FFE4W]  $C7 $47 $18 [$FFD8W]  $B8 [$215CW]  $50 $53 $9A
              $09DC118CRL $83 $C4 $04 $B8 [$0001W]  $50 $9A $06BD1E11RL     $83
              $C4 $02 $8B $1E $D8 $A7 $C7 $07 [$0001W]  $C7 $47 $02 [$0003W]  $8B #Make right shell
              $44 $0A $89 $47 $0A $8B $44 $0C $89 $47 $0C $C7 $47 $16 [$001CW]
              $C7 $47 $18 [$FFD8W]  $B8 [$217AW]  $50 $53 $9A $09DC118CRL     $83
              $C4 $04 $B8 [$0001W]  $50 $9A $06BD1E11RL     $83 $C4 $02 $8B $1E
              $D8 $A7 $C7 $07 [$0001W]  $C7 $47 $02 [$0003W]  $8B $44 $0A $89 $47 #Make up shell
              $0A $8B $44 $0C $89 $47 $0C $C7 $47 $16 [$0000W]  $C7 $47 $18 
           [$FFC8W] $B8 [$2198W]  $50 $53 $9A $09DC118CRL     $83 $C4 $04 $5F $5E
              $5D $CB