Gods Map Format
| Format type | Map/level |
|---|---|
| Map type | 2D tile-based |
| Layer count | 2 |
| Tile size (pixels) | 32×16 |
| Viewport (pixels) | 320×160 |
| Games |
Levels for Gods are stored in PLEVnx.MAP files, where n is the world (1-4) and x the sublevel (A or B), for eight maps in total. Every map is 128×64 tiles, and since tiles are 32×16 pixels the whole world is 4096×1024 pixels. The files are compressed with PKWARE DCL Compression; everything below describes the decompressed data.
A map file holds the tile layout, the objects placed in the level, the level's messages and its triggers. Other per-level data (hint text, enemy spawners, levers and trap doors) is in the matching PALFILS file, and the tile graphics are in the PBITS file.
All values are big-endian.
File format
The file is a short variable-length header followed by 21824 bytes of level data in four fixed-size blocks. The decompressed size is always 21824 + 4 + 2 * count bytes.
Header
| Data type | Name | Description |
|---|---|---|
| UINT16BE | count | Number of entries in the table below |
| UINT16BE | unknown | 6 or 7 in the shipped files. Never read by the game. |
| UINT16BE[count] | table | Never read by the game. |
The game only uses count to skip over the header. For a new map, all three fields can be set to 0.
Block 1: Tile planes
16384 bytes: two planes of 128×64 bytes each, stored row by row (128 bytes per row).
Plane A (first 8192 bytes) holds the tile to draw in each cell, as an index into the level's tileset.
Plane B (next 8192 bytes) holds what the cell does:
| Value | Meaning |
|---|---|
| 0 | Empty (about 55% of all cells) |
| 1 | Solid (about 40%) |
| 2 | Ladder |
| 3-255 | Event cell. Touching it runs event number value - 3 from the level's PALFILS file. |
Plane B is not fixed: doors and gates opened by triggers rewrite cells in both planes while the game runs.
Block 2: Objects
1200 bytes: 200 object records of 6 bytes each.
| Data type | Name | Description |
|---|---|---|
| UINT16BE | x | Position in pixels (top-left) |
| UINT16BE | y | Position in pixels (top-left) |
| UINT16BE | type | Object type. 0xFFFF (any negative value) is an unused slot. |
Types 0-191 are ordinary objects. Their names, categories and values are in the POBJECTS file, and they are drawn with sprite 170 + type. Types from 192 up are weapon pickups for weapon type - 192, drawn with sprite 302 + (type - 192).
Object type 69 is a tablet that shows a hint. Its x position is used as the key to look up the hint text in the PALFILS file, so each hint tablet in a level must have a unique x.
Block 3: Messages
1840 bytes: 40 message offsets followed by the message text.
| Data type | Name | Description |
|---|---|---|
| UINT32BE[40] | offsets | Offset of each message's text, measured from the start of this block. 0 means no message. |
| char[1680] | text | NUL-terminated strings |
Only the low 16 bits of each offset are used; the high word is 0 in every shipped map. Messages are shown on the message line when a trigger fires, e.g. a trap door closes beneath you or you need the treasure key.
Block 4: Triggers
2400 bytes: 100 trigger records of 24 bytes each. A trigger has up to three conditions, all of which must be true, and one action. Triggers are run by events (see plane B above), and a trigger that fires is used up until the level is entered again.
| Data type | Name | Description |
|---|---|---|
| UINT16BE | cond1Type | First condition, see below |
| UINT16BE | cond1Arg | Argument for the first condition |
| UINT16BE | cond2Type | Second condition |
| UINT16BE | cond2Arg | |
| UINT16BE | cond3Type | Third condition |
| UINT16BE | cond3Arg | |
| UINT16BE | x | Position of the action in pixels (e.g. where an object appears) |
| UINT16BE | y | |
| UINT16BE | action | Action type in the low 15 bits. If bit 15 is set, any key or consumable named in a type 1 condition is removed from the player's inventory when the trigger fires. |
| UINT16BE | actionArg | Argument for the action |
| UINT16BE | message | Message number (0-39) to show when the trigger fires |
| UINT16BE | reserved | Always 0 |
Conditions
All comparisons are strict: for example, if health equals the argument, both 7 and 8 are false.
| Type | True when |
|---|---|
| 0 | Always (unused condition slot) |
| 1 | Object type arg is in the player's inventory |
| 2 | Object type arg is not in the player's inventory |
| 3 | The player carries weapon arg |
| 4 | The player does not carry weapon arg |
| 5 | Event arg has already happened |
| 6 | Event arg has not happened yet |
| 7 | Health is greater than arg |
| 8 | Health is less than arg |
| 9 | Time spent in the level is greater than arg |
| 10 | Time spent in the level is less than arg |
| 11 | Lever arg is on |
| 12 | Lever arg is off |
| 13 | Score is greater than a threshold |
| 14 | Score is less than a threshold |
| 15 | Lives are greater than arg |
| 16 | Lives are less than arg |
Actions
For actions 2, 3, 4, 7 and 8, keys named in type 1 conditions (object types 18-23 and 127-129) are always used up, whether bit 15 is set or not.
| Type | Argument | Effect |
|---|---|---|
| 0 | Object type | Place an object at (x, y) |
| 1 | Weapon number | Place a weapon pickup at (x, y) |
| 2 | – | Open a door (2×3 cells) at (x, y) |
| 3 | row | Create a teleporter at (x, y) leading to the given cell |
| 4 | Exit number | Create a level exit at (x, y) |
| 5 | Event number | Run another event |
| 6 | – | Remove up to two nearby enemies/hazards |
| 7 | – | Open a gate |
| 8 | – | Close a gate |
| 9 | – | Close a door (2×3 cells) |
| 10 | Weapon number | Take the weapon from the player |
| 11, 12, 13 | – | Do nothing. Type 13 is commonly used just to show a message. |
| 14 | – | Reset the level timer |
Source code
From re-gods, the open-source HTML5 port:
- src/formats/map.js – map reader
- src/formats/map-writer.js – map writer
- src/game/trigger.js – trigger record parser and conditions
- src/game/trigger-actions.js – trigger actions
Credits
This file format was reverse engineered by VorticonCmdr. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)