Hovertank 3-D
Hovertank 3-D is one of the first FPS games and the direct ancestor of most FPS games. It has EGA graphics with no textures, but with scaled sprites. Like the later Wolfenstein 3-D, this game includes different brightnesses of the same tile when viewed from the N/S or E/W.
It was followed by Catacomb 3-D, which added textures.
File formats
File name | Description |
---|---|
levelXX.hov | Game levels in Commander Keen 1-3 Level format. They use RLEW compression with the tag $FEFE. |
sounds.hov | PC speaker sounds in Inverse Frequency Sound format |
dsound.hov | Digitised sounds (see below) |
Level Format
The levels use the same format as many earlier Id/Apogee games, specifically the Commander Keen 1-3 Level format. Each level consists of two planes (a wall plane, and an object plane) which define what the level looks like.
Plane Dimensions
There don't appear to be any of the usual restrictions on dimensions that some other games using this level format have.
Any axial dimension between 1 and 64 (inclusive) is allowed, with the dimensions on one axis having no impact on the other.
You can define axis lengths greater than 64, but these tend to cause problems in the game, resulting in only part of the map being accessible.
Theoretically, this means the smallest level possible is 1x1, and the largest being 64x64.
Decompression Quirks
The levels bundled with the game seem to only store level data up to the last non-zero object code. This means that the last parts of the object plane aren't always present, so you will want to ensure your code allows for this.
Wall Plane
The wall plane contains the walls which make up the level. Each cell will contain one of the following values.
Value | Description |
---|---|
0 | Empty\Player Space |
1 | Blue Wall |
2 | Green Wall |
3 | Cyan Wall |
4 | Red Wall |
5 | Pink Wall |
6 | Yellow Wall |
7 | White Wall |
8 | Black Wall (Inverted) |
9 | Blue Wall (inverted) |
10 | Green Wall (inverted) |
11 | Cyan Wall (inverted) |
12 | Red Wall (inverted) |
13 | Pink Wall (inverted) |
14 | Yellow Wall (inverted) |
15 | White Wall (inverted) |
16 | Black Wall |
If you ignore the empty value (0), the colour of a wall is determined by the lowest 4 bits (the upper 12-bits are ignored). So for example, wall 1 and 17 are the same color, as is wall 33, etc.
The first 8 (technically 1-7) wall values are used throughout the original game. The next 8 wall values (9-15) provide inverted versions of the first 8 wall codes (the light wall is on the dark face, and the dark wall is on the light face).
Codes beyond the first 16 are still useful though for two reasons.
Firstly, code 16 allows for black\gray walls (since the slot is taken by the player space code).
The second is that these extra codes allow walls of the same colour to be divided by vertical lines. The way the renderer works, walls of the same colour\code are drawn as a single surface. By using differing codes with the same wall colours, walls with the same colour will be visually divided.
Map Boundaries
If the edges of the map aren't closed off with solid walls, the player is able to exit the map and explore beyond its bounds. This can result in instability and crash the game.
Object Plane
The object plane contains details of the items and enemies that are scattered around the level.
A maximum of 100 objects per level is allowed, with the game crashing if more objects are encountered. Note that projectiles spawned in the game count toward this limit, so having a level with either maximum, or near maximum items may result in the game crashing once things start shooting.
Each cell contains a 16-bit value which can be divided as follows.
Bits | Description |
---|---|
0-7 | Object code |
8-9 | Facing direction. Only significant for the start teleporter. |
10-15 | Unused. Generally ignored, but can cause game instability when used with the start teleporter. |
Object Codes
Value | Description |
---|---|
0 | Empty. No Object. |
1 | Hostage (male) |
2 | Drone (tentacle monster) |
3 | Enemy Hovertank |
4 | Red Gargoyle |
5 | Shield Power-up |
6 | Hostage (female) |
254 (0xfe) | Exit Teleporter |
255 (0xff) | Entry Teleporter |
Note that other codes don't spawn anything.
Direction Codes
Direction codes can be one of the following. Note that these values have been shifted right for simplicity.
Value | Description |
---|---|
0 | North facing |
1 | East facing |
2 | South facing |
3 | West facing |
Entry and Exit Teleporters
When multiple instances of an entry or exit teleporter are placed into a map, the last instance will be used. So if multiple codes are present on a single level, all except the last one will be ignored.
If these are omitted altogether, an exit teleporter will be spawned at 0,0 (upper-left corner of the level). Not placing a starting teleporter will result in the player being spawned into a void and unable to do anything (the game usually becomes unstable after this and can crash).
Hostages
The game allows any number of hostages, but the status bar only supports up to 14. Including hostages beyond this number will result in the additional hostage icons being drawn over other parts of the status bar.
If no hostages are included in a level, the level cannot be completed as nothing will trigger the exit teleporter.
Objects within Walls
Objects were not designed to be placed within walls, and will become inaccessible. A player can exit a wall when the spawn is place within one, but the wall becomes normal once the player has exited. Enemies do not exit walls when placed within them.
This is worth noting as the original missions contain a number of instances where items have been placed within walls (presumably by accident).
Level Name, Briefing, and Time Limit
These appear to be embedded in the executable binary, and not in the level data file.
Digitised sounds
dsound.hov begins with the following structure repeated once for each sound in the file.
Data type | Name | Description |
---|---|---|
UINT32LE | offset | Offset of sound data from start of file |
UINT32LE | length | Length of sound data in bytes |
UINT32LE | samplerate? | Possibly the sample rate of the sound |
UINT16LE | flags | See Inverse Frequency Sound format |
The sound data immediately follows. The offset of the first file can be used to discover the number of sounds in the file (either by reading the header up until this point, or dividing the first file's offset by 14.)
Source code
The source code of this game was released by Flat Rock Software on June 4, 2014. It can be downloaded from GitHub.