From KeenWiki
Jump to navigation Jump to search

Sprites are pale floating creatures found in the Well of Wishes level in Keen 4. Not only are they dangerous, but they can and will shoot Keen if he floats level with them.

Some confusion may arise on this page. The enemy Sprite is different from the enemy's sprite (Code) On this page when discussing the enemy capital letters are used. Thus the Sprite's sprite.

Sprite Type

Sprites use sprite type 23, which is used only by them and doesn't really interact with other sprites. They shoot bullets of type 31, this is unique to sprite shots.

Keen 4

%patch $12593 $17 #Sprite
%patch $12688 $1F #Sprite's bullet

Sprite Actions

Sprite behavior is quite simple. It uses a floating behavior similar to that of Princess Lindsey. it will do this as long as Keen is not horizontally level with it.

When Keen is level with it the shooting sequence starts; the sprite will go to its aiming action and, if Keen stays level long enough, it will go to its shooting action. (If Keen moves away the Sprite will return to floating.)

The shooting behavior will produce a Sprite shot, then sit. This second shooting action, which looks identical to the first allows the sprite to pause a bit after releasing a shot so as not to look odd as the shot moves away.

Once produced the shot cycles between four actions that involve it moving across the screen until it hits tiles.

$37A0W #Sprite float
$37BEW #Sprite aiming
$37DCW #Sprite shooting 1 - produce shot
$37FAW #Sprite shooting 2 - sit
$3818W #Sprite's bullet 1
$3836W #Sprite's bullet 2
$3854W #Sprite's bullet 3
$3872W #Sprite's bullet 4

Keen 4

#Spawn sprite in-level
%patch $125C3 [$37A0W] #Sprite float

#Float - keep floating
%patch $3262C [$37A0W] #Sprite float

#Keen is level with sprite
%patch $12633 [$37BEW] #Sprite aiming

#Aiming sprite (Return to float by itself)
%patch $3264A [$37A0W] #Sprite float

#Keen is level long enough
%patch $12656 [$37DCW] #Sprite shooting 1

#Shooting sprite
%patch $32668 [$37FAW] #Sprite shooting 2
%patch $32686 [$37A0W] #Sprite float

#Spawn Sprite's shot
%patch $126A6 [$3818W] #Sprite's bullet 1

#Sprite's shot
%patch $326A4 [$3836W] #Sprite's bullet 2
%patch $326C2 [$3854W] #Sprite's bullet 3
%patch $326E0 [$3872W] #Sprite's bullet 4
%patch $326FE [$3818W] #Sprite's bullet 1

Sprite Behavior

Behavior values

There are three basic behaviors the Sprite uses. The first is the floating behavior, which also looks for Keen. It is this behavior that makes the sprite aim when Keen is level with it. The second behavior is the 'wait' behavior; if Keen is level with the Sprite long enough it will go to shooting. Finally the shooting behavior itself produces a Sprite shot. (It is called once per action, to avoid spamming a whole barrage of shots.) The final shooting frame has no behavior as it just has to sit. Likewise the shots have no behavior as they merely have to move until they hit something.

$11A20BB1RL #Sprite float
$11A20C18RL #Sprite aim
$11A20C3BRL #Sprite shoot (Produce shot)

Keen 4

%patch $32620 $11A20BB1RL #Sprite float

%patch $3263E $11A20C18RL #Sprite shoot

%patch $3265C $11A20C3BRL #Sprite shooting
%patch $3267A $00000000L  #Sprite sit after shooting

%patch $32698 $00000000L  #Nothing
%patch $326B6 $00000000L  #Nothing
%patch $326D4 $00000000L  #Nothing
%patch $326F2 $00000000L  #Nothing

Sprite floating behavior

These patches deal with the Sprite's behavior when it is floating, waiting to attack Keen.

Sprite floating behavior code

This is the floating behavior code for the Sprite. It involves two basic parts. First the Sprite's floating condition, its speed and how long it has been floating. Then its float direction may be modified so it floats up and down. (Brown values) In the second part Keen's location is checked for and the sprite turns to face him. It then alters it action to 'shooting'

This patch contains, and is thus incompatible with, the seeking Keen patches, the float speeds and time patch, an action patch and the 'only float up or down' patches. It should be reasonably obvious as to where they fit into the patch, and thus it is possible to combine those patches.

Keen 4

#Sprite floating behavior
%patch $125D1 $55 $8B $EC $56 $8B $76 $06 $B8 [$0008W]  $50 $FF $74 $10 $56 $9A #Floating speed = [8]
              $09DC1517RL     $83 $C4 $06 $8B $44 $3E $2B $44 $0C $3D [$0020W]  #Floating u [time]
              $7E $05 $C7 $44 $10 {$0001W}  $8B $44 $0C $2B $44 $3E $3D [$0020W]  #Floating d [time], float d direction ({$0001})
              $7E $05 $C7 $44 $10 {$FFFFW}  $8B $1E $A7D6W  $8B $47 $24 $3B $44 #Floating u direction ({$FFFF})
              $28 $73 $21 $8B $47 $28 $3B $44 $24 $76 $19 $8B $47 $0A $3B $44
              $0A $73 $07 $C7 $44 $0E [$FFFFW]  $EB $05 $C7 $44 $0E [$0001W]  $C7 #Face Keen to shoot at him
              $44 $1C [$37BEW]  $5E $5D $CB                                     #Change action to shoot

Sprite doesn't float, just sits

Both of these patches remove the floating part of the Sprite's behavior, and the first is incompatible with the second and with the above patch, as well as with all the patches the above patch is incompatible with. (For the same reasons.)

The first patch (the 'long' patch) removes the floating code from the Sprite's behavior and this new behavior can be placed anywhere, in its entirety in the executable and used by other sprites. The second patch, the 'short' patch is much smaller and tidier but can only be used as-is. It is also compatible with all the patches on this page except the above code patch and the long patch in this section. (It can be combined with the code patch above however, replacing $B8 $0008W with $EB $2E $00.)

Keen 4

#Sprite doesn't float - long patch
%patch $125D1 $55 $8B $EC $56 $8B $76 $06 $8B $1E $A7D6W  $8B $47 $24 $3B $44
              $28 $73 $21 $8B $47 $28 $3B $44 $24 $76 $19 $8B $47 $0A $3B $44
              $0A $73 $07 $C7 $44 $0E [$FFFFW]  $EB $05 $C7 $44 $0E [$0001W]  $C7 #Face Keen to shoot at him
              $44 $1C [$37BEW]  $5E $5D $CB                                     #Change action to shoot

Keen 4

#Sprite doesn't float - short patch
%patch $125D8 $EB $2E

Sprite only floats up or down

Each of the (mutually exclusive1) patches below limits the Sprite's floating direction. By default it floats up and down, but it is possible to make it float in only one direction. Sprites will float until they hit a solid tile, when they will stop, or until they float off the top or bottom of the level.

Keen 4

#Only float up
%patch $125F6 $FFFFW

#Only float down
%patch $12606 $0001W

Sprite aiming behavior

These patches deal with the Sprite's behavior when it is aiming. If Keen moves while it is aiming it stops, otherwise it shoots.

Sprite aiming behavior code

This is the complete code for the Sprite when it is aiming at Keen. The last brown variable is a return to the floating behavior. This occurs if the Sprite detects Keen has moved out of its range vertically. (The four blue variables; decreasing these four values by two will make it check for Keen vertically.)

Keen 4

#Sprite aiming Sprite behavior
%patch $12638 $55 $8B $EC $56 $8B $76 $06 $8B $1E $A7D6W  $8B $47 [$24] $3B $44
              [$28] {$73} $0D $8B $47 [$28] $3B $44 [$24] {$76} $05 $C7 $44 $1C {$37DCW}
              $5E $5D $CB

Sprite shooting behavior

These patches deal with the Sprite's behavior when it is making a shot.

Sprite shooting behavior code

This is the entire behavior code used by the shooting sprite. It produces a sprite's shot sprite with the following properties: foreground 0, clipping 3 and type $1F. These are marked in blue. The first blue variable shouldn't be messed with, it has a subtle effect on other sprite properties. It's starting action is marked in brown.

The sprite is spawned $0080W = 0.5 tiles down from the top of the Sprite's sprite. Two sounds play in this behavior, but so close together that only one is heard. They are sounds $0004 and $0026. This means the behavior contains some redundant code; namely the string $B8 $0004W $50 $9A $187409F1RL $83 $C4 $02 can be removed with no ill effects.

Changing the $0E values on line 5 to $10 will make the shot produced share the Sprite's vertical direction instead of its horizontal one. (It will shoot up and down.)

This patch contains a number of other patches on this page and so may interfere with them if they are used separately.

Keen 4

#Sprite shooting behavior
%patch $1265B $55 $8B $EC $56 $8B $76 $06 $B8 [$0001W]  $50 $9A $06BD1E11RL
              $83 $C4 $02 $8B $44 $0A $8B $1E $D8 $A7 $89 $47 $0A $8B $44 $0C
              $05 [$0080W]  $89 $47 $0C $C7 $47 $20 [$0000W]  $C7 $07 [$001FW]  $C7
              $47 $02 [$0003W]  $B8 [$0004W]  $50 $9A $187409F1RL     $83 $C4 $02
              $8B $44 $0E $8B $1E $D8 $A7 $89 $47 $0E $B8 {$3818W}  $50 $53 $9A
              $09DC118CRL     $83 $C4 $04 $B8 [$0026W]  $50 $9A $187409F1RL
              $83 $C4 $02 $5E $5D $CB

Sprite attacks vertically not horizontally

This patch causes the Sprite to attack Keen vertically (When he is above or below it) rather than horizontally. This is done by swapping all of the vertical and horizontal values in the floating, aiming and shooting code and also setting the shot's speeds to have a vertical instead of horizontal component. This makes it incompatible with a few patches used on this page.

The actual patch is quite simple, all occurrences of $24 are changed to $22, $28 to $26, $0E to $10 and $0A to $0C.

Keen 4

#Sprite attacks vertically not horizontally
%patch $1260E $22
%patch $12619 $22
%patch $12611 $26
%patch $12616 $26
%patch $1261E $0C
%patch $12621 $0C
%patch $12626 $10
%patch $1262D $10
%patch $12645 $22
%patch $12650 $22
%patch $12648 $26
%patch $1264D $26
%patch $1269D $10
%patch $126A4 $10

#Sprite bullet moves vertically
%patch $32694 $0000W $0040W
%patch $326B2 $0000W $0040W
%patch $326D0 $0000W $0040W
%patch $326EE $0000W $0040W

Sprite alternates between shooting right and left

This patch stops the Sprite from shooting in Keen's direction; instead it shoots right, then left, then right... changing shooting direction each time.

Keen 4

#Sprite shoots left then right
%patch $1260E $0A
%patch $1261E $24
%patch $12621 $24

Seeking Keen

By default the Sprite will face Keen when it is level with him. This means it will shoot towards him. This is controlled by two values in the patch below. It is thus possible to make the Sprite shoot only in one direction, or away from Keen.

Keen 4

#Shoot towards Keen
%patch $12627 [$FFFFW] #Shoot left if Keen left
%patch $1262E [$0001W] #Shoot right if Keen right


The Sprite's speed is defined in its behavior. it acts very much like Princess Lindsey, with a float speed (determining how fast it floats.) and a float up and float down time (determining how far up or down it floats. It is best if these are equal.) The aiming and shooting Sprite does not move.

By contrast the speed of the Sprite shots is defined by its animation; it has a horizontal speed of $40. (That can be altered by altering how fast it animates!)

Animation Motion

%patch $3261C [$0000W $0000W] #Speed 

%patch $32658 [$0000W $0000W]
%patch $32676 [$0000W $0000W]
%patch $3263A [$0000W $0000W] #Shooting

#Sprite bullet
%patch $32694 [$0040W $0000W]
%patch $326B2 [$0040W $0000W]
%patch $326D0 [$0040W $0000W]
%patch $326EE [$0040W $0000W]

Floating speeds

%patch $125D9 [$0008W] #Floating u/d speed
%patch $125EF [$0020W] #Floating u time
%patch $125FF [$0020W] #Floating d time

Sprite Collision

The Sprite and its shots use the 'kill Keen' collision used by various deadly sprites. This means that the sprite does not ahve its own unique collision.

Collision values

Keen 4

%patch $32624 $09DC1752RL #Misc kill

%patch $32642 $09DC1752RL #Misc kill

%patch $32660 $09DC1752RL #Misc kill
%patch $3267E $09DC1752RL #Misc kill

#Sprite's shot
%patch $3269C $09DC1752RL #Misc kill
%patch $326BA $09DC1752RL #Misc kill
%patch $326D8 $09DC1752RL #Misc kill
%patch $326F6 $09DC1752RL #Misc kill

Sprites stunnable

This patch takes the first frame from the Sprite's shot and makes it into a stunned action for the Sprite. The Sprite is still lethal to Keen but will stun when shot, falling until it hits the ground.

Keen 4

#Sprite's shots have 3 frames
%patch $126A6 $3836W
%patch $326FE $3836W

#Sprite uses new collision
%patch $32624 $2EE70146RL
%patch $32642 $2EE70146RL
%patch $32660 $2EE70146RL
%patch $3267E $2EE70146RL

#Stunned sprite action (1st frame of old bullet)
%patch $32688 $01B4W $01B4W $0002W $0000W $0000W $00F0W $0000W $0000W
              $09DC16C9RL   $00000000L    $09DC176ERL   $3818W

#New Sprite collision, react to Keen's shot, kill Keen
%patch $2EFB6 $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 $3818W  $50 $57 $56 $9A $09DC1695RL
                          $83 $C4 $06 $5F $5E $5D $CB


The Sprite has only two frames, floating and aiming\shooting. The Sprite shot has four frames. The sprite is cleverly set up so that it looks as if the Sprite has to 'think' about whether Keen is level long enough to be shot.

Keen 4

%patch $30712 [$01AFW] #Sprite Cache start
%patch $3075C [$01B7W] #Sprite cache end

#Sprite floats
%patch $32610 $01AFW $01AFW
%patch $3261A $000AW        #Reaction speed

%patch $3262E $01B0W $01B2W
%patch $32638 $0028W        #Pause before returning to floating (Keen gone)

%patch $3264C $01B1W $01B3W
%patch $32656 $0028W        #Pause while making shot
%patch $3266A $01B1W $01B3W
%patch $32674 $001EW        #Pause before returning to floating

#Sprite's bullet
%patch $32688 $01B4W $01B4W
%patch $32692 $000AW        #Animation speed
%patch $326A6 $01B5W $01B5W
%patch $326B0 $000AW        #Animation speed
%patch $326C4 $01B6W $01B6W
%patch $326CE $000AW        #Animation speed
%patch $326E2 $01B7W $01B7W
%patch $326EC $000AW        #Animation speed

Sprite positioning and shooting

Since the Sprite's shot is so much shorter than it, it is spawned $0080W, 8 pixels, or half a tile down from the top of the sprite.

Keen 4

#Sprite shooting height
%patch $1267C [$0080W]


As noted in the shooting behavior section the Sprite makes 'two sounds when shooting but only one of them can be heard. It is best to eliminate the first sound when modding to avoid the possibility of unwanted interference.

Keen 4

#Sprite sounds
%patch $12690 $04 #Sprite shoots (Keenshot sound; not normally played)
%patch $126B3 $26 #Sprite shoots sound

#Sprite sounds
%patch $1268F $EB $0A #Sprite shoots (Keenshot sound; not normally played)
%patch $126B2 $EB $0A #Sprite shoots sound

Clipping and foreground

Sprites have no clipping, meaning they can pass through even solid tiles. Their foreground value is also 0, meaning they will appear behind all foreground tiles.

Keen 4

#Sprite foreground variable
%patch $1259D $0000W

Keen 4

#Sprite clipping
%patch $125A2 $0000W

Sprite-tile interaction

The Sprite uses the 'sit' tile collision. That is, it does not really care about tiles at all and would only interact with them if given clipping. Its shot however uses the 'enemy projectile' tile collision; this is also used by Darts; it will vanish if it hits a tile with a blocking property such as walls or floors.

Keen 4

%patch $32628 $09DC176ERL #Sit

%patch $32646 $09DC176ERL #Sit

%patch $32664 $09DC176ERL #Sit
%patch $32682 $09DC176ERL #Sit

#Sprite's shot
%patch $326A0 $11A20CA1RL #Enemy projectile
%patch $326BE $11A20CA1RL #Enemy projectile
%patch $326DC $11A20CA1RL #Enemy projectile
%patch $326FA $11A20CA1RL #Enemy projectile

Action type

The floating sprite needs to respond instantly to Keen, and so has an action type of 2. While aiming and shooting it needs to sit still, with an action type of 1. Finally its shots move smoothly with an action type of 1.

Keen 4

%patch $32614 {$0002W} #Sprite floats

%patch $32650 {$0000W} #Sprite aiming
%patch $3266E {$0000W} #Sprite shooting
%patch $32632 {$0000W} #Sprite sees Keen has gone

%patch $3268C {$0001W} #Sprite's bullet 1
%patch $326AA {$0001W} #Sprite's bullet 2
%patch $326C8 {$0001W} #Sprite's bullet 3
%patch $326E6 {$0001W} #Sprite's bullet 4

Deprotect and stick to ground

Sprites and their shots do not need to stick to the ground or deprotect their animations. They thus have value 0 for both these variables.

Keen 4

#Floats so doesn't change
%patch $32616 [$0000W $0000W] #Floating

%patch $32634 [$0000W $0000W] #Aiming
%patch $32652 [$0000W $0000W] #Firing
%patch $32670 [$0000W $0000W] #Firing - sit

%patch $3268E [$0000W $0000W] #Bullet 1
%patch $326AC [$0000W $0000W] #Bullet 2
%patch $326CA [$0000W $0000W] #Bullet 3
%patch $326E8 [$0000W $0000W] #Bullet 4

Sprite spawn code

Only partial spawning code for the sprite is available. In the initiation code notice the two difficulty checks (Allowing three difficulty appearances.) and the Sprite cache being set ($C7 $06 $CB7DW $0001W.)

In the spawning code the last blue highlighted value is the sprite action the sprite uses as it proceeds to act in-level. $C7 $02 $xxxxW sets the sprite activity, $C7 $07 $xxxxW sets the sprite type, $C7 $20 $xxxxW sets the foreground value.

Sprites always start the level moving down and right, in a unique way. $B8 $0001W sets a value 1, which is then pasted to the sprite's horizontal ($0E) and vertical ($10) direction variables.

Keen 4

#Location of initiation code
%patch $EEA5 [$02A7W] #Easy Sprite (At $EB97)
%patch $EEB1 [$029DW] #Medium Sprite (At $EB8D)
%patch $EEB3 [$0293W] #Hard Sprite (At $EB83)

#Sprite Initiation code
%patch $EB83 $83 $3E [$7A6CW]  {$03 $7D} $03 $E9 $0270W  $83 $3E [$7A6CW]  {$02 $7D}
             $03 $E9 $0266W  $FF $76 $FC $57 $9A {$11A20B5FRL}     $83 $C4 $04
             $C7 $06 $CB7DW  $0001W  $E9 $0251W

#Sprite spawn code
%patch $1257F $55 $8B $EC $33 $C0 $50 $9A $06BD1E11RL     $83 $C4 $02 $8B $1E
              $D8 $A7 $C7 $07 [$0017W]  $C7 $47 $02 [$0001W]  $C7 $47 $20 [$0000W]
              $C7 $47 $06 [$0000W]  $8B $46 $06 $B1 $08 $D3 $E0 $89 $47 $0A $8B
              $46 $08 $D3 $E0 $89 $47 $3E $89 $47 $0C $B8 [$0001W]  $89 $47 {$0E}
              $89 $47 {$10} $B8 [$37A0W]  $50 $53 $9A $09DC118CRL     $83 $C4 $04
              $5D $CB