Keen 4-6 Action Format
The Keen 4-6 Action format is how sprites are controlled in the Keen engine series of games, including Bio Menace, Commander Keen 4-6, Commander Keen Dreams, Dangerous Dave 3, and Dangerous Dave 4.
Commander Keen 4-6 stores the various behaviors of sprites (Enemies, items, and Keen) at various locations in the executable. However sprites are organized using 'actions'; a series of 30-byte strings containing information on what animations, behaviors, etc the sprite should use. Each 'action' can be considered a 'frame' or 'animation' of a sprite and effectively controls the behaviors of that sprite for that 'frame'
A sprite's action is given when it is created, and can be changed by various behaviors. As an example, the poison slug in Keen 4 is created and made to crawl left and right. It can randomly change to a sliming slug, or be shot and transformed into a shot slug.Within the main body of the executable, each action is identified by a two byte string, its address in the text segment of said executable (Its offset from the start of the text segment, as if it were a line of text.)
Actions are not kept in a solid block, rather they are interspersed with text strings, miscellaneous game data and errors. This is why actions are identified by location, not number.
Actions are 30 bytes long consisting of 15 words:
Int Description Values Int 0: Left sprite Valid animations only Int 2: Right sprite Valid animations only Int 4: Movement parameter 0-4 Int 6: Change h 0/1 Int 8: Change v 0/1 Int 10: Delay (Anim speed) 0-8000 Int 12: H anim move amount +- any value Int 14: V anim move amount +- any value Int 16: Behavior [Start of behavior codes only] Int 18: Behavior segment [Segment values only] Int 20: Check sprites [Start of check sprite codes only] Int 22: Check segment [Segment values only] Int 24: Check tiles [Start of check tile code only] Int 26: Check segment [Segment values only] Int 30: Next action [Valid actions only]
The left and right sprites are the graphics chunks used for the sprite when it is facing left or right. (See EGAGraph Format) with the additional values of 0 (Do not display an animation or do not change a previous animation) anf -1 (Remove an animation but not the hitbox associated with it.)
This is how the game handles the sprite's movement; and is important only with sprites that have movement not associated with animation (See below.)The variable can have any value between 0-4; zero is used for sprites that don't move (Most common occurrence.), 1 for nonanimating sprites that may still need to move or hover in place, 2 is the stunned sprite value and is also used where smooth movement is needed 3 is used for 'fall' moves such as the Bounder or Mad Mushroom and 4 is used for sprites that must hit or land on the ground.
This controls whether a sprite can change its h/v position smoothly. Things that need to crawl up and down slopes for example must have a change h value of 1 (Change v is rarely used, for things that climb walls)
Delay and animation movement
The delay is how long a sprite remains in its current action, also known as its animation speed. If this is 0 the sprite will remain in its current action until something else happens. When this time has elapsed it will move on to the action given in 'Next action'
The h/v animation movement amount is how much the sprite's position will change *after* it switches to the next action. For example, slugs crawl by moving 40 pixels forward every time they animate. This 'speed' is separate from other speeds set arbitrarily in the executable.
This is a dword address giving the offset and segment of the sprite's behavior (Movement, looking for the player, etc) used during this action. The behavior is important as it controls how a sprite acts.
Two more dword addresses, similar to the behavior one and giving the address of the sprite's tile and sprite checking functions. These control how a sprite interacts with other sprites (bullets, the player, etc) and tiles (Walls, floors...)
The next action for the sprite to perform after the current action is completed. If 0, the sprite will do nothing or be erased.