+==========================================================================================+ |Jazz Jackrabbit Level file format: | +==========================================================================================+ The Jazz level files contain a surprising amount of data, controlling everything from sprite behavior to Jazz's jump height and more. There is enormous redundancy and a notable lack of logic that makes you wonder just what the Epic team was smoking. The level files can be divided roughly into 17 'blocks' of data, some RLE compressed, others not. It appears each RLE block is loaded seperately, while the plain blocks affect variables in the game. Blocks 6, 8 and 13 seem to be read only by Epic's level builder. They are name lists and any data you want can be stored in them without affecting the level. When totally decompressed levels are 61'980 bytes long, give or take a few extras. Of this, about 50 bytes remains of unknown function. **************************** OVERVIEW: block0: Level header (Uncompressed) block1: Mapping block2: Transparency block3: Masking block4: Special behaviour block5: Events block6: Event names block7: Animation block8: Animation names block9: Level properties 1 (Uncompressed) block10: Jazz animation list block11: Derbis animation list (Uncompressed) block12: Attack block13: Attack names block14: Level properties 2 (Uncompressed) block15: Unknown block16: Level properties 3 (Uncompressed) **************************** **************************** BLOCK 0: LEVEL HEADER **************************** 0 39 Signature Level signature. The first three bytes are what the game uses to make sure the file is a Jazz level **************************** BLOCK 1: LEVEL MAP **************************** COMPRESSED: 0 2 RLE size Size of the compressed data block, excluding the size bytes 2 ? RLE data Compressed RLE data UNCOMPRESSED: 0 32768 Level map 64 rows -> 256 tiles -> 2-byte tile entries Each tile in the level is represented by two values, the first being the tile used at that position , the second being the event used. As you'd expect the possible values for both are 0-255 Tiles are listed starting from 0,0 (Top left) in the level and moving across rows and down columns. This is the largest RLE block as it compresses poorly **************************** BLOCK 2: TRANSPARENCY **************************** COMPRESSED: 0 2 RLE size Size of the compressed data block, excluding the size bytes 2 ? RLE data Compressed RLE data UNCOMPRESSED: 0 256 Trans data 256 tiles -> 1-byte tile entries 256 entries, one for each possible tile in a Jazz tileset (Maximum size of a tileset is 256 tiles.) Each entry can have either of two values, $00 or $01 Any tile which is used as a sun tile or has a 'foreground with transparency' event placed over it in-level (Even if the tile HAS no transparency.) will need a value of $01 in this table, or else it will look terrible when Jazz touches it. (This is the problem with the sun tile in Muckamuk.) The table can be entirely filled with $01 values in a pinch, but this will significantly increase level loading times and the memory Jazz uses, since each tile must be loaded into memory 8 times **************************** BLOCK 3: TILE MASK **************************** COMPRESSED: 0 2 RLE size Size of the compressed data block, excluding the size bytes 2 ? RLE data Compressed RLE data UNCOMPRESSED: 0 2048 Tile masks 256 tiles -> 8 rows per tile -> 1-BIT per 4x4 block in each row Tileset tiles are divided into 4x4 blocks (Thus making each tile an 8x8 array.) and each of these can be masked (Solid.) or unmasked. This basically defines what Jazz can 'hit' for each tile Each 4x4 block in each tile row has a BIT value of 0 or 1, so a tile's mask consists of 8 bytes. A 'fall through' tile is represented by $0000000000000000 and a totally solid one by $FFFFFFFFFFFFFFFF **************************** BLOCK 4: SPECIAL BEHAVIOR **************************** COMPRESSED: 0 2 RLE size Size of the compressed data block, excluding the size bytes 2 ? RLE data Compressed RLE data UNCOMPRESSED: 0 8192 Spec beh 16 possible behaviors -> 512-byte 'behavior segments' An interesting case. The block is divided into 16 'segments' and an event will start reading data at the start of the segment given by its 'special behavior' value. So for example a value of 0 starts reading at 0, 2 at 1024 and so on BEHAVIOR: 0 8192 Spec beh ? 2 Beh length The length, in two-byte units, of the special behavior +2 ? Behavior Each special behavior can take up as much space as you want (Well, no more than the entire block.) Behaviors are made of two-byte'steps', each step is an x,y position, relative to the event's starting position at 0,0 Thus it is that 'special behavior' means 'move around in this pattern' Each two-byte step lasts 1/32 of a second and the x,y position must be multiplied by 8 to get the location in pixels when the level is played Once again, behaviors can be any length and take up more than one segment. Jazz reads x steps of data then returns to the start and repeats; the events does NOT have to move in a circle or return to its starting position, it may even leave the screen entirely **************************** BLOCK 5: EVENT PROPERTIES **************************** COMPRESSED: 0 2 RLE size Size of the compressed data block, excluding the size bytes 2 ? RLE data Compressed RLE data UNCOMPRESSED: 0 4064 Properties 127 events -> 32-byte event entries This controls almost EVERYTHING about what an event (Enemies, items, ammo, everything but Jazz pretty much...) in a level does. EVERYTHING. Note that event 0 is special, containing information controlling other events, for example it must be totally blank if you want shooting events to face both ways when firing In-level, events greater than 127 behave the same as the event 128 less than them, except the tile they start at has all its transparent pixels turned black EVENT ENTRIES: ? 1 Difficulty Difficulty level event first appears in (0-3 = Easy-Turbo) Event will appear in the level for any difficulty equal to or greater than this. (If it is an event number larger than 127, the black-transparency still appears on any difficulty.) +1 1 Blank +2 1 Reflect Obscure, either 0 or 63 often has no effect, but must be 63 in Technoir for the water to reflect Jazz off itself +3 1 Blank +4 1 Behavior How sprite moves, there is a big list of the possible hard-coded values you can use, such as 'walk left and right' or 'fall to ground' +5 1 Left anim Sprite uses this animation when left of Jazz or facing left +6 1 Right anim Sprite uses this animation when right of Jazz or facing right +7 1 Blank +8 1 Magnitude 'Strength of effect'; if a event has some effect on Jazz, this is how strong it is. Values less than 128 are positive (Down, right...) those greater are negative (Up, left...) This is used, for example by springs to push Jazz up (With values like 246) If an event has no effect, this is usually set to 255 (-1) +9 1 Health How many shots from Jazz an event can take before being destroyed. (This is increased by 1 in the harder difficulties.) If this is 0 then the event either cannot be shot, or cannot be killed. Note that things like carrots have this set to 0. Anything not 0 makes the event 'flash' when shot +10 1 Type Event type, enemy, item, time, etc... The two types that affect the game are 'hurt Jazz' (If this has a health above 0 it counts as an enemy point when shot.) and 'item' (Counts as an item point when destroyed.) +11 1 Points How many points Jazz gets when the event is destroyed (Shot or grabbed.) is this value * 10 +12 1 Attack What attack the event uses. The first 5 attacks (See later.) are also used by Jazz as his shots, but can still hurt him. Values between 0-31 +13 1 Attack fr Attack frequency, how often (In 32ths of a second) an event attacks (Shoots) +14 1 Blank +15 1 Speed How fast an event moves +16 1 Blank +17 1 Anim speed How fast an event animates +18 2 Blank +20 1 Number Event number, totally useless as far as I can see and can be handled automatically +21 1 Sound The sound played when this event is 'used' Usually by being shot or grabbed (Carrots, orbs) or by Jazz touching it (Springs, tubes) This makes use of the sound list, found in block 9 later on +22 1 Multi 1 Multi-purpose; usually the value of many different effects, including the x-axis to warp to, destruct replacement tile, and immortality\speed boost duration +23 1 Multi 2 Used less often than 1 for e.g. Y-axis to warp to and 'bridge sink depth' +24 1 Bridge len Length of bridge typ events. = length in tiles \ 2 +25 1 Medivo len Length of the Medivo-ball-type event's chain, similar to above. +26 1 Medivo dir Direction Medivo balls start moving in, in degrees from 12-o-clock +27 1 TNT TNT type events need this, and the previous 4 bytes set to $09 +28 1 Death anim What animation is displayed when an event is destroyed (Shot or grabbed.) +29 1 Death anim2 Same as above, identical in fact, due to animations needing left and right values, but destruction not really HAVING a left\right +30 1 Attk anim l Animation used by an event attacking left +31 1 Attk anim r Animation used by an event attacking right **************************** BLOCK 6: EVENT NAMES **************************** COMPRESSED: 0 2 RLE size Size of the compressed data block, excluding the size bytes 2 ? RLE data Compressed RLE data UNCOMPRESSED: 0 2032 Names 127 events -> 16-byte names The names of events in a level, often kept blank or making little sense NAME ENTRY: ? 1 Length Length of name +1 ? Name Name. 'Extra' bytes are kept blank or not read **************************** BLOCK 7: ANIMATION SEQUENCES **************************** COMPRESSED: 0 2 RLE size Size of the compressed data block, excluding the size bytes 2 ? RLE data Compressed RLE data UNCOMPRESSED: 0 8192 Animations 128 animations -> 64-byte animation entries This controls what sequence of sprites is displayed when an event has a particular animation number. Any animation number above 127 behaves like that value - 128 except that 6 copies of the animation appear in a 'splatter' effect (Useful for shot animations.) The values of the sprites used in each sequence are obtained by combining the level's sprite file with MAINCHAR.000. A level typically has between 231-255 sprites, most of them Jazz-related. There are four types of animation, default Jazz (Usually the same in each level, but not always, used for Jazz, carrots, ammo, etc, the basic stuff.) Enemy (Different in each level, but tend to use the same kinda image numbers.) nonsense (Look weird, usually containing Jazz images and not used for anything.) and empty (Contain one image, image 0.) ANIMATION ENTRIES: 0 8192 Animations 128 animations -> ? 2 Spawn x,y Where, relative to the top left of the tile an event is placed on, a new event (E.g. bullet.) is produced if and when the current event 'shoots' it out. Usually blank except for attack animations like Jazz shooting +2 1 Acc anim Accessory animation to use. Accessory animations DO animate and count as a place to injure an enemy. +3 2 Acc spanw Where, relative to the top left of the tile an event is placed on, the accessory animation (E.g. Boss Devan's ship's gun turret.) is located if there is one. Usually blank, but used a lot in boss animations. +5 1 Start y Where, relative to the top of the tile an event is placed on, the animation starts. (There is no x value for this.) This is because many images are odd sizes. +6 1 Anim num Number of images in the animation loop, 0-19 +7 19 Anims Images used in animation loop, the same image can be used more than once, and often is, for example the orbette animation uses the same image six times in a row. If the value 255 (-1) is used, this means 'blank' (0 is an animation, remember.) This is used for things like hidden springs. +26 19 X move The movement, in pixels, horizontally of EACH INDIVIDUAL image in the animation loop. This allows images of different widths to move smoothly, or for the same image to move about as if it was several +45 19 Y move The movement, in pixels, vertically of EACH INDIVIDUAL image in the animation loop. This allows images of different heights to move smoothly, or for the same image to move about as if it was several (e.g orbettes use this trick.) **************************** BLOCK 8: ANIMATION NAMES **************************** COMPRESSED: 0 2 RLE size Size of the compressed data block, excluding the size bytes 2 ? RLE data Compressed RLE data UNCOMPRESSED: 0 2048 Animations 128 animations -> 16-byte animation entries Pretty much identical to block 6, except these are names for animations. Almost always blank, except in boss levels NAME ENTRY: ? 1 Length Length of name +1 ? Name Name. 'Extra' bytes are kept blank or not read **************************** BLOCK 9: LEVEL PARAMETERS **************************** This section is the first uncompressed block after the header and contains numerous lists of things affecting the level. It signals the start of the 'tail' of the level. STRUCTURE: 0 144 Names 16 entries -> 9-bytes each Usually blank, names of the level blocks (Used when compiling levels.) same format as previous name lists and make interesting reading 144 9 Misc Usually blank, once used to load compressed level blocks 153 64 Snd pitch 32 sounds -> 2-byte sound entries Each of these entries is for a sound in the level, and defines how much a sound is squashed (Shortened and raised in pitch.) This lets Jazz use a single sound like several. For example the sound GODLIKE is used for the 'got item' and 'got shield' sounds, the only difference being this value. Note that the same sound can have MORE than one pitch value, and often does, that most sounds have a 'default' value for this even though they shouldn't really have to (Lazyness!) and that not all entries need to be filled. 217 288 Snd name 32 sounds -> 9-byte sound entries Sound names. Unlike other names, these actually have a function; if the name doesn't match one in the SOUNDS.000 (Or SOUNDS.00X where X is the episode Jazz is playing.) no sound will play. As such you have only a limited number of options here. This list also gives each sound a number (0-31) that is related to byte 22 of events. Once again the same name CAN be used more than once The name entries of course follow the usual format established above, but with the total length being 9 bytes instead of 16 505 1 Music len Length of the music file name 506 12 Music name Name of the music file played as background music in this level. Can be balnk 'Extra' bytes are not read or kept blank 518 1 Start len Length of name of movie file 519 12 Start nam Name of level start movie, this file is not actually used anymore 531 1 End len Length of name of movie file 532 12 End name Name of level end movie, usually played at the end of a section. Can also be blank if you don't want something played 558 24 Blank 583 2 Jazz x Jazz's start position x 585 2 Jazz y Jazz's start position y 587 1 Next lev Next level number (.000 etc) 588 1 Next world Next world number (LEVEL0, etc) 589 2 Jazz jump Jazz's jump height, this is negative (Up.) and is the height in tiles divided by two. Default is $FFF5 (5 tiles) 591 2 ??? Unknown, varies between levels, an always negative value that is probbably some sort of level, like that water that follows it. 594 2 Water Water height, in pixels from level top. If it is too low (The value is too high, usually above $07D0.) then the level may look odd at the start (The sky will be multicolored; see block 14) If the water level is below the level bottom, water related events will not work. 595 1 Jazz an sp How fast Jazz animates (Default is 119) 596: 2 ??? Unknown, allways $01 $1E **************************** BLOCK 10: JAZZ ANIMATION LIST **************************** COMPRESSED: 0 2 RLE size Size of the compressed data block, excluding the size bytes 2 ? RLE data Compressed RLE data UNCOMPRESSED: 0 352 Jazz anim 88 entries -> 4-bytes each The Jazz animation list, controlling what animations Jazz uses in-level. Usually pretty standard except in special levels like Birdland. The first 19 are used often, the next 25 are mostly tutlette but have some use Each entry consists of two two-byte values, on for facing left, the other for facing right. (Notably no value is above $00FF...) The important ones are as follows: ----------------------- ------------------------------------------------------------------------------- 01.) J Walk 02.) J Jump 03.) J Airspin 04.) J Shoot 05.) J Duck 06.) J Fall 07.) J Hurt 08.) J Lean on wall 09.) J Hover 10.) J Stand 11.) J Bored 12.) J Balance on edge 13.) J Look u\d* 14.) J Swim 15.) J Run 16.) J Die on hoverboard 17.) J Sucked 18.) J Stop 19.) J Spring up .... .... .. . *First value is look up, second is look down ----------------------- ------------------------------------------------------------------------------- **************************** BLOCK 11: DERBIS ANIMATION LIST **************************** STRUCTURE: 0 4 Anims Animations used by... stuff. There are 4 entries, each one byte long. These are animations for 'derbis' type phenomena. For example, the first is the invincibility sparkles that surround Jazz. The second is the 'Devan head' that appears in boss fights (In normal levels it is $09, bosses $7E) The last two are some sort of explosions (Unknown) Be aware that these are handled special, a RANDOM image from the selected animation is picked and animated. If you change it to animation that doesn't have a large enough number of images then ones from the next (And the next!) animation will be used as well. This can look... messy. The values are almost always the same in every level. **************************** BLOCK 12: ATTACK **************************** COMPRESSED: 0 2 RLE size Size of the compressed data block, excluding the size bytes 2 ? RLE data Compressed RLE data UNCOMPRESSED: 0 640 Attacks 32 entries -> 20-byte attacks 'Attacks' spawn another event from an existing one. Usually this means shooting and what is formed are bullets. This block deals with how these events behave for EVERYTHING, Jazz, enemies, the bird... Jazz uses the first four attacks (Blaster, etc; the TNT attack is different and can be used no matter what.) The bird uses the lastone (31) The 'unknown weapon' is attack 4 and most enemies use one or two optional ones. Note that attacks can also be things like bubbles or fragments, they are most ingeniously used. Indeed, even enemies can be spawned here (Deserto) Note also that TWO attacks can be produced (RF missile) so everything is a bit doubbled up STRUCTURE: ? 2 Sprite 1 Sprites to use for attack 1 when facing l\r (For spawn event this is the EVENT number to spawn.) +2 2 Sprite 2 Same as above, for the second attack (E.g. RF missiles) +4 2 Speed x 1 Speed l\r for first attack (Blaster speed = 1) +6 2 Speed x 2 Same as above,for second attack +8 2 Speed y 1 Speed up/down for attack 1 (RF missile y speed = 2) +10 2 Speed y 2 Same as above, for second attack +12 2 Gravity 1 How strongly an attack feels gravity; this makes it fall faster and faster the longer it's active. (Launcher) unlike y speed which is constant. Note that just like previous values, the left and right attacks have different values Note that this value is only useful if the attack is of type 2-4 (See below for attack types.) Note also that if this is 4 or higher the attack becomes a spawned event. (E.g the lizard generator in Deserto.) +14 2 Gravity 2 Same, for second attack +16 1 Death anim What animation the attack shows when it is destroyed (Hits stuff or is shot) +17 1 Death snd What sound the attack makes when it is destroyed +18 1 Type Attack type, 0: Normal 1: Shoot l/r at same time (A max of FOUR shots at once can appear if this is used with RF missile type attacks.) 2,3: Fall under gravity and smash, 4: Launcher (Fall and bounce) +19 1 Start snd Sound made when the attack appears (The shooting sound) **************************** BLOCK 13: ATTACK NAMES **************************** COMPRESSED: 0 2 RLE size Size of the compressed data block, excluding the size bytes 2 ? RLE data Compressed RLE data UNCOMPRESSED: 0 672 Attacks 32 entries -> 21-bytes each Contains the names of the attacks used in the previous block. Usually empty, each entry consists of a length byte and a name up to 20 characters in length. **************************** BLOCK 14: LEVEL PROPERTIES **************************** STRUCTURE: 0 1 Sky type How the sky looks; value between 0-15. This affects three things, firstly the sky (Is it seen [Transparent] or is it grey? ), water color (What color is it? Does it get darker as Jazz sinks? Can it even be seen?) and 'movement sensitive palette' (The tiles that color animate as Jazz moves up and down in a level; if these are stalled you have 112 extra colors for your palette.) +--+-------------------+-------------------+-------------------+------------------+ |# | Sky visible? |Black backgrounds? | Water color? | Move palette? | +--+-------------------+-------------------+-------------------+------------------+ |0 | No | No | Invisible | Looks odd | |1 | No | Yes | Invisible | No | |2 | Yes (Normal) | Yes | Invisible | Yes | |3 | Yes (Odd start) | Yes | Dark green | Green-yellowish | |4 | Yes (Odd start) | Yes | Green | Green tinge | |5 | Yes (Odd start) | Yes | Dark purple | Purple tinge | |6 | Yes (Odd start) | Yes | Purple | Pink tinge | |7 | Yes (Odd start) | Yes | Yellow | Yellow tinge | |8 | No | No | Invisible | Yes | |9 | No | Yes | Invisible | Yes | |10| Yes (Odd start) | Yes | Invisible | Yes | |11| Yes (Odd start) | Yes | Lagunicus blue | Green-yellowish | |12| Yes (Odd start) | Yes | Lag Green | Green tinge | |13| Yes (Odd start) | Yes | Lag purple | Purple tinge | |14| Yes (Odd start) | Yes | Lag pink | Pink tinge | |15| Yes (Odd start) | Yes | Lag yellow | Yellow tinge | +--+-------------------+-------------------+-------------------+------------------+ 1 1 Sun? Do we use a sun tile? $01 = yes 2 1 Sun tile Sun tile, this and next 3 tiles is used. 3 11 Jazz snd Jazz's sounds as follows: 13 11 Anims Jazz acessory animation list, 21 1-byte entries as follows: ----------------------- ------------------------------------------------------------------------------- SOUNDS: 01.) Nothing 02.) Jazz jump 03.) Jazz hurt 04.) Jazz bored 05.) Bored??? 06.) Nothing??? 07.) Levend count 08.) Level done 09.) Nothing??? 10.) J lose bird 11.) Uploop? ANIMATIONS: 01.) Nothing 02.) Nothing 03.) Nothing 04.) 4 shield gem 05.) Hoverboard l 06.) Hoverboard r 07.) Bird l 08.) Bird r 09.) ??? 10.) Nippious* 11.) 1 shield gem * If this value is 1, Jazz shivers and slides (Icy) if 2 or above he shivers but doesn't slide, 0 is a normal level. ----------------------- ------------------------------------------------------------------------------- **************************** BLOCK 15: UNKNOWN **************************** COMPRESSED: 0 2 RLE size Size of the compressed data block, excluding the size bytes 2 ? RLE data Compressed RLE data UNCOMPRESSED: 0 32 ??? 8 entries -> 4-bytes each usually blank, this appears to be redundant data used by the Epic level editor to do with level blocks **************************** BLOCK 16: LEVEL PROPERTIES 2 **************************** STRUCTURE: 0 3 Blank 3 1 World check World checksum. Start with the value 208 + (World number); if [(world number) \ 2] is even then we add 2, if it is odd, we subtract 2. The value for 0,1,2... is thus 210,211,208,209,214... 4 1 Level check Level checksum. If INT[(level extension) \ 4] is even, then this is [(level extension) + 4] if it is odd then this is [(level extension) - 4] This creates a pattern of ++++----++++... 5 2 Easy en Number of enemies needed to be shot on easy\med for 100%, Epic calculated this by counting every 'hurt' type event on easy that could be shot, sometimes causing an error since not all hurt events were destructable. 7 2 Hard en Same as above but for the hard difficulty; should be equal or larger to the previous value, and calculated in a similar way 9 2 Turbo en Same as above 11 2 Items Items to get to get 100% at level end; since items aren't supposed to increase in number with difficulty as enemies do, this is for all difficulties 13 1 Block len Length of block extension, should of course be $03 14 3 Block Block file to use is BLOCKS.XXX where the numbers here are in plain text (E.g '032') The most common string is '999' meaning 'the same as the level ending' but you will notice say, boss levels, are forced to use the block number specifically