From KeenWiki
Jump to navigation Jump to search

This page covers patches relating to the Nospikes in Keen 6. Nospike are teal, horned enemies notable for charging at Keen and occasionally running off of cliffs.

Sprite Type

Nospikes use sprite type 16. This is used by no other sprites. However if a different property is used, then the Nospike will crash the game when killed unless its star specs are fixed. It may be possible that this type can stun a Nospike, allowing two Nospike can collide and stun each other.

Keen 6

#Nospike sprite type
%patch $10CD9 $10

Sprite Actions

Nospikes have a rather c0omplex action structure that is not entirely understood. They are spawned sitting, which immediately leads to it walking, a four frame loop with a complex behavior. At any time there is a small chance a walking Nospike will return to sitting and a larger chance it will charge Keen if he is level with it.

Instead of one simple change when going from walking to charging the Nospike has a complicated bit of code that pairs each walking frame with a charging frame, so walking frame 1 will go to charging frame 2. This means a total of 4 action checks and 4 transformations, highly odd.

Charging is a four frame loop with a similar oddness. When the Nospike randomly stops charging (or Keen gets out of its way) it does so in the exact opposite manner as when it started charging, with each charging frame being paired with a walking frame it changes into. Nospike will also return to sitting when they charge into a wall.

Finally the same oddity occurs when the Nospike is shot, if it is not stunned by Keen's shot it will turn and charge him, with the interesting addition that the sitting Nospike will become charging frame 2. It also appears that two Nospike can collide and stun themselves, though this has not been confirmed. The stunned Nospike does nothing.

When a Nospike charges off a cliff it will enter the fall sequence, a four frame sequence that ends with a falling Nospike. Falling Nospikes will stun when they hit a solid tile.

$2460W  #Nospike sit
$247EW  #Nospike walk 1
$249CW  #Nospike walk 2
$24BAW  #Nospike walk 3
$24D8W  #Nospike walk 4
$24F6W  #Nospike charge 1
$2514W  #Nospike charge 2
$2532W  #Nospike charge 3
$2550W  #Nospike charge 4
$256EW  #Nospike hanging in air
$258CW  #Nospike make a '?'
$25AAW  #Nospike with '?'
$25C8W  #Nospike fall (Will not hit ground unless it has Nospike property)
$25E6W  #Stunned Nospike

Keen 6

#When spawned
%patch $10D22 [$2460W]

#While sitting
%patch $331AC [$247EW]

#While walking
%patch $331CA [$249CW]
%patch $331E8 [$24BAW]
%patch $33206 [$24D8W]
%patch $33224 [$247EW]

#Nospike sit (Randomly when walking)
%patch $10D4D [$2460W]

#Nospike randomly charge when walking:
%patch $10D8D [$247EW] #Walking 1 becomes...
%patch $10D94 [$2514W] #Charging 2
%patch $10D9C [$249CW] #Walking 2 becomes...
%patch $10DA3 [$2532W] #Charging 3
%patch $10DAB [$24BAW] #Walking 3 becomes...
%patch $10DB2 [$2550W] #Charging 4
%patch $10DBA [$24D8W] #Walking 4 becomes...
%patch $10DC1 [$24F6W] #Charging 1

#While charging
%patch $33242 [$2514W]
%patch $33260 [$2532W]
%patch $3327E [$2550W]
%patch $3329C [$24F6W]

#Nospike sits when it charges into a wall
%patch $11082 [$2460W]

#Nospike randomly walks when charging:
%patch $10E21 [$24F6W] #Charging 1 becomes...
%patch $10E28 [$249CW] #Walking 2
%patch $10E30 [$2514W] #Charging 2 becomes...
%patch $10E37 [$24BAW] #Walking 3
%patch $10E3F [$2532W] #Charging 3 becomes...
%patch $10E46 [$24D8W] #Walking 4
%patch $10E4E [$2550W] #Charging 4 becomes...
%patch $10E55 [$247EW] #Walking 1

#When shot, be stunned
%patch $10E81 [$25E6W]

#When shot charge Keen:
%patch $10EBC [$2460W] #Sitting Nospike and...
%patch $10EC3 [$247EW] #...walking 1 becomes...
%patch $10EC8 [$2514W] #Charging 2
%patch $10ED9 [$249CW] #Walking 2 becomes...
%patch $10EDE [$2532W] #Charging 3
%patch $10EEF [$24BAW] #Walking 3 becomes...
%patch $10EF4 [$2550W] #Charging 4
%patch $10F05 [$24D8W] #Walking 4 becomes...
%patch $10F0A [$24F6W] #Charging 1

#Two Nospike collide and stun
%patch $10F5F [$25E6W]
%patch $10F6C [$25E6W]

#While stunned
%patch $33332 [$25E6W]

#When charging off a cliff
%patch $110C1 [$256EW]

#Fall off cliff sequence
%patch $332BA [$258CW]
%patch $332D8 [$25AAW]
%patch $332F6 [$25C8W]
%patch $33314 [$0000W]

#When falling Nospike hits the ground
%patch $11035 [$25E6W]

Sprite Behavior

The Nospike has three of its own behaviors. It has no behavior while sitting but has separate behaviors for walking and charging which define when it can start and stop these behaviors. It also has a unique behavior used when it charges off a cliff and needs to make a '?'. When falling and stunned it uses a general 'move through the air' behavior.

$08F41765RL #Move through the air
$10CC0079RL #Nospike walk
$10CC0106RL #Nospike charge
$10CC02D8RL #Nospike make '?'

Keen 6

%patch $331A0 $00000000L

%patch $331BE $10CC0079RL
%patch $331DC $10CC0079RL
%patch $331FA $10CC0079RL
%patch $33218 $10CC0079RL

%patch $33236 $10CC0106RL
%patch $33254 $10CC0106RL
%patch $33272 $10CC0106RL
%patch $33290 $10CC0106RL

#Nospike hanging in air
%patch $332AE $00000000L

#Nospike make a '?'
%patch $332CC $10CC02D8RL

#Nospike with '?'
%patch $332EA $00000000L

#Nospike fall
%patch $33308 $08F41765RL

#Stunned Nospike
%patch $33326 $08F41765RL

Make '?' behavior code

This is the complete (and rather simple) code for the behavior used by the Nospike when it is making a '?'. This doesn't produce the '?' directly, but interacts with its tile interaction to allow it to be dispplayed

Keen 6

#Nospike make '?'  behavior code
%patch $10F98 $55 $8B $EC $8B $46 $06 $05 $42 $00 $50 $9A $1608198ARL    $83
              $C4 $02 $5D $CB

Seeking Keen

The Nospike seeks Keen by charging towards him while walking. It also does this when shot by Keen, turning and charging in his direction.

Keen 6

#Charge towards Keen randomly while walking
%patch $10D77 [$0001W]
%patch $10D7E [$FFFFW]

#Charge towards Keen when shot by him
%patch $10EA6 [$0001W]
%patch $10EAD [$FFFFW]

Speed and Jump Height

The Nospike's walking and charging speeds are defined in its animation motion. The only other important variables are how high it jumps when stunned, either by Keen or by falling off a cliff. Notice however that the 'hanging in the air' Nospike moves down, just a very small amount ($0001W), this is important for it falling to the ground.

Animation motion

%patch $3319C [$0000W $0000W]

%patch $331BA [$0080W $0000W]
%patch $331D8 [$0080W $0000W]
%patch $331F6 [$0080W $0000W]
%patch $33214 [$0080W $0000W]

%patch $33232 [$0080W $0000W]
%patch $33250 [$0080W $0000W]
%patch $3326E [$0080W $0000W]
%patch $3328C [$0080W $0000W]

#Hanging in air
%patch $332AA [$0000W $0001W]

#Making '?'
%patch $332C8 [$0000W $0000W]

#With '?'
%patch $332E6 [$0000W $0000W]

%patch $33304 [$0000W $0000W]

%patch $33322 [$0000W $0000W]

Jump heights

#Nospike jump height when shot
%patch $10E91 [$FFE8W]

#Nospike jump height when falling and hits ground
%patch $11054 [$FFE8W]

Sprite Collision

The Nospike's collision is interesting in that it appears two Nospike can collide and stun each other, though this has never been observed. Otherwise it is deadly to Keen and takes several shots to stun.

Collision values

The Nospike always uses the same collision, except when it is stunned or falling off a cliff.

Keen 6 collision values

%patch $331A4 $10CC019ARL

%patch $331C2 $10CC019ARL
%patch $331E0 $10CC019ARL
%patch $331FE $10CC019ARL
%patch $3321C $10CC019ARL

%patch $3323A $10CC019ARL
%patch $33258 $10CC019ARL
%patch $33276 $10CC019ARL
%patch $33294 $10CC019ARL

#Charged off cliff -Hanging in air
%patch $332B2 $00000000L

#Making '?'
%patch $332D0 $00000000L

#With '?'
%patch $332EE $00000000L

%patch $3330C $00000000L

%patch $3332A $00000000L

Nospike doesn't flash when shot

This patch stops the Nospike from flashing white when shot but not stunned.

Keen 6

#Nospike doesn't flash when shot
%patch $10EAF $90 $90 $90 $90 $90

Sprite strength

The Nospike takes four hits to stun.

Sprite strength

#Nospike's strength
%patch $10D35 [$0004W]

Nospike doesn't charge when shot

This patch simplifies the Nospike's collision by preventing it from changing its action and direction to charge Keen when it is shot. Instead it will simply ignore Keen's shots. (Though the right number of shots will still stun it.)

Nospike doesn't charge when shot

#Nospike doesn't charge when shot
%patch $10E97 $57 $9A $0CA60EC2RL    $83 $C4 $02 $5F $5E $5D $CB


The Nospike's animations are quite straightforward; eight are used for walking and another eight for charging. (Notice the faster animation speeds when charging, which makes the Nospike charge faster.) A single frame is used when sitting and all four frames of falling off a cliff. The animation speed in the 'make ?' frame is important, it is how long the Nospike hangs in the air with a '?' above it's head. The other animation speeds are a little more complex, but affect the look of the falling Nospike.

The '?' animation itself is defined in the Nospike's code. It lasts as long as the Nospike is in the right actions.

Keen 6 Animations

%patch $3244A [$012AW] #Nospike cache start
%patch $3249A [$013CW] #Nospike cache end

#'?' animation
%patch $10FD8 [$013CW]

%patch $33190 $012AW $012AW
%patch $3319A $005AW        #Time standing still

%patch $331AE $0137W $0133W
%patch $331B8 $000AW        #Animation speed
%patch $331CC $0138W $0134W
%patch $331D6 $000AW        #Animation speed
%patch $331EA $0139W $0135W
%patch $331F4 $000AW        #Animation speed
%patch $33208 $013AW $0136W
%patch $33212 $000AW        #Animation speed

%patch $33226 $012FW $012BW
%patch $33230 $0004W        #Animation speed
%patch $33244 $0130W $012CW
%patch $3324E $0004W        #Animation speed
%patch $33262 $0131W $012DW
%patch $3326C $0004W        #Animation speed
%patch $33280 $0132W $012EW
%patch $3328A $0004W        #Animation speed

#Hanging in air
%patch $3329E $012AW $012AW
%patch $332A8 $0014W        #Pause before '?'

#Making a '?'
%patch $332BC $012AW $012AW
%patch $332C6 $005AW        #Animation speed

#With '?'
%patch $332DA $012AW $012AW
%patch $332E4 $0014W        #Time after '?' removed before falling

%patch $332F8 $012AW $012AW
%patch $33302 $0000W        #Wait until hit ground

%patch $33316 $013BW $013BW
%patch $33320 $0000W        #Animation speed

Sprite positioning

The Nospike spawns 24 pixels or 1.5 tiles higher then where it is placed in-level. This must be changed with its sprite height as it is used to make the Nospike move along the ground.

The '?' sprite is produced 8 pixels up and 1 tile right of the Nospike's top left hitbox corner.

Keen 6

#Nospike spawn height
%patch $10CF5 [$FE80W] #1.5 tiles upwards

#'?' spawn position
%patch $10FDF [$0080W] #8 pixels up
%patch $10FE6 [$0100W] #1 tile right

Clipping and foreground

The Nospike uses a value of 0 for its foreground parameter, useful since it charges into walls and along floors. This value keeps it behind most sprites and all fore tiles. The '?' image is foreground 3, appearing in front of most sprites and tiles as it's meant to be noticed.

Nospike foreground parameter

#Nospike foreground parameter
%patch $10CE3 [$0000W]

#'?' foreground parameter
%patch $10FD1 [$0003W]

Probability and randomness

The Nospike can start a level moving either right or left, with a 50:50 chance of doing either.

There is a certain probability that a walking Nospike will become a sitting Nospike, this is quite low so that the Nospike doesn't continually stop when walking. There is also a separate probability of the Nospike charging at Keen when he is level with it. If the first probability is high, then the second will be reduced (since the Nospike will be too busy sitting to charge.)

When charging there is a small probability of the Nospike returning to walking. This is independent from the other two. This is affected by whether Keen is level with and\or in front of the Nospike at the time.

Keen 6 randomness

#Chance of walking Nospike starting level moving right
%patch $10D00 $80

#Chance of walking Nospike sitting
%patch $10D46 $10

#Chance of walking Nospike charging
%patch $10D64 $20

#Chance of charging Nospike walking
%patch $10E08 $08

Sprite-tile interaction

When sitting or walking the Nospike use a generic 'stay on platforms' interaction code. But when charging they use a unique code that lets them charge off of cliffs. When hanging in the air with an without a '?' they use another generic interaction that just draws the sprite.

When producing a '?' the Nospike uses a unique tile interaction that also draws the '?' onscreen. When falling it uses yet another interaction to slam into the ground. Finally when stunned it uses the generic 'stunned sprite' interaction.

Sprite tile interactions

%patch $331A8 $08F41831RL

%patch $331C6 $08F41831RL
%patch $331E4 $08F41831RL
%patch $33202 $08F41831RL
%patch $33220 $08F41831RL

%patch $3323E $10CC0399RL
%patch $3325C $10CC0399RL
%patch $3327A $10CC0399RL
%patch $33298 $10CC0399RL

#Hanging in air
%patch $332B6 $08F4180ARL

#Making a '?'
%patch $332D4 $10CC02ECRL

#With '?'
%patch $332F2 $08F4180ARL

%patch $33310 $10CC033ARL

%patch $3332E $08F419AFRL

Action type

Most of the Nospike's actions are unspectacular and thus are type 0. Only when falling down and being stunned does it need to move smoothly, using type 2 actions.

Sprite action types

%patch $33194 [$0000W]

%patch $331B2 [$0000W]
%patch $331D0 [$0000W]
%patch $331EE [$0000W]
%patch $3320C [$0000W]

%patch $3322A [$0000W]
%patch $33248 [$0000W]
%patch $33266 [$0000W]
%patch $33284 [$0000W]

#Hanging in air
%patch $332A2 [$0000W]

#Making a '?'
%patch $332C0 [$0000W]

#With '?'
%patch $332DE [$0000W]

%patch $332FC [$0002W]

%patch $3331A [$0002W]

Deprotect and stick to ground

The Nospike needs to stick to the ground while walking\charging and thus uses a value of 1 for this variable in its walking actions, as well as when sitting.

Sprite deprotect, stick

%patch $33196 [$0000W $0001W]

%patch $331B4 [$0000W $0001W]
%patch $331D2 [$0000W $0001W]
%patch $331F0 [$0000W $0001W]
%patch $3320E [$0000W $0001W]

%patch $3322C [$0000W $0001W]
%patch $3324A [$0000W $0001W]
%patch $33268 [$0000W $0001W]
%patch $33286 [$0000W $0001W]

#Hanging in air
%patch $332A4 [$0000W $0000W]

#Making a '?'
%patch $332C2 [$0000W $0000W]

#With '?'
%patch $332E0 [$0000W $0000W]

%patch $332FE [$0000W $0000W]

%patch $3331C [$0000W $0000W]

Sprite spawn code

In the initiation code notice the Nospike cache being set ($C7 $06 $CD37W $0001W.) Also notice the three difficulties of Nospike that are possible.

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 and $C7 $20 $xxxxW sets the foreground value. Finally $D3 $E0 $05 $xxxx is how far down (Or more usually up) the sprite is spawned from where it is placed. This is necessary for sprites that walk on the ground as they can only be placed in the level at multiples of 16 pixels high while their actual height can be anything.

The Nospike starts the level moving either left or right with a 50:50 chance of either. $C7 $47 $10 $xxxxW is the vertical direction the sprite starts moving in, either $0001W (Facing down), $FFFFW (Facing up) or $0000W (Neither, never used.) $C7 $47 $0E $xxxxW is the horizontal direction.

Keen 6

#Location of initiation code
%patch $E9AE [$02B0W] #Easy Nospike (At $E6D0)
%patch $E9B0 [$02A6W] #Medium Nospike (At $E6C6)
%patch $E9B2 [$029CW] #Hard Nospike (At $E6BC)

#Nospike initiation code
%patch $E6BC $83 $3E {$75A8W}  [$03] {$7D} $03 $E9 $0201W  $83 $3E {$75A8W}  [$02] {$7D}
             $03 $E9 $01F7W  $57 $56 $9A {$10CC0005RL}     $83 $C4 $04 $C7 $06
             $CD37W  $0001W  $E9 $01E4W  

#Nospike spawn code
%patch $10CC5 $55 $8B $EC $33 $C0 $50 $9A $069A1E25RL     $83 $C4 $02 $8B $1E
              $66 $A9 $C7 $07 [$0010W]  $C7 $47 $02 [$0001W]  $C7 $47 $20 [$0000W]
              $8B $46 $06 $B1 $08 $D3 $E0 $89 $47 $0A $8B $46 $08 $D3 $E0 $05
              [$FE80W]  $89 $47 $0C $9A $1CF30034RL     $3D [$0080W]  $7D $0B $8B
              $1E $66 $A9 $C7 $47 $0E [$0001W]  $EB $09 $8B $1E $66 $A9 $C7 $47
              $0E [$FFFFW]  $8B $1E $66 $A9 $C7 $47 $10 [$0001W]  $B8 [$2460W]  $50
              $53 $9A $08F41219RL     $83 $C4 $04 $8B $1E $66 $A9 $C7 $47 $44
              [$0004W]  $5D $CB