By myst6re.
Gateways/Triggers
| Offset | Size | Data |
|---|---|---|
| 0 | 9 | Name of field (\0 terminated) |
| 9 | 1 | Control Direction |
| 10 | 6 | Unknown |
| 16 | 2 | Like [PVP] value (was a link, target page no longer exists) |
| 18 | 2 | Height to focus the camera on the character (0= Focus on the feet, 200= normal focus) |
| 20 | 8*8 | Camera Ranges |
| 84 | 2*8 | Screen Ranges |
| 100 | 32 * 12 | Gateways |
| 484 | 16 * 12 | Triggers |
Range data
Gives the limits of the camera when moving.
typedef struct {
qint16 top;
qint16 bottom;
qint16 right;
qint16 left;
} Range;
Camera Range
Each range corresponds to a background layer.
Screen Range
Always (0, 224, 320, 0) twice. The first range change the screen resolution, the second seems to do nothing.
Gateways data
Passage between fields (the exits the player walks through). There are always 12 records; unused ones have field ID 0x7FFF.
For each gateway (32 bytes, all values little-endian):
| Offset | Size | Data |
|---|---|---|
| 0 | 2 * 3 | Exit line point 1: X, Y, Z (int16) |
| 6 | 2 * 3 | Exit line point 2: X, Y, Z (int16) |
| 12 | 2 | Destination X (int16) |
| 14 | 2 | Destination Y (int16) |
| 16 | 2 | Destination walkmesh triangle ID, in the destination field’s .id (int16) |
| 18 | 2 | Destination field ID (0x7FFF = unused gateway; below 0x48 = world map, see below) |
| 20 | 2 * 4 | Unknown, not read by the gateway test (usually 0; 0x7FFF, 0xFF… in a few fields) |
| 28 | 1 | Facing direction on arrival (0–255 angle units) |
| 29 | 3 | Copies of byte 28 in 1595 of the 1632 used gateways; not read by the gateway test |
“Destination vertex” in older documents is really X, Y and the triangle ID: there is no destination Z, because the height comes from the triangle.
How a gateway fires
Field_Collision_CheckGatewayCrossing (FF8_EN.exe 0x477980) runs for the player entity after each move. For every gateway whose field ID is not 0x7FFF, it checks two things, using only X and Y (the Z values of the exit line are ignored):
- The player is within touch range of the exit line segment (
Field_Collision_PointToLineDistSq, squared distance compared with the squared touch radius of the entity). - The player’s position has changed side of the line between the previous and the current frame (the sign of the cross product flips).
When both are true, the game copies the record into the jump globals, exactly like the MAPJUMP opcode:
| Gateway value | Global | Used on arrival as |
|---|---|---|
| Destination field ID | MenuState_opcode_menu_id | New CURRENT_FIELD_ID (the line number in maplist) |
| Destination X / Y | wm2field_FieldX / wm2field_FieldY | Spawn position |
| Destination triangle | wm2field_FieldZ | Spawn walkmesh triangle (the height is computed from it) |
| Byte 28 | wm2field_FieldTarget | Facing direction |
A field ID below 0x48 selects the world map module (globalFieldNextModuleID = 7) instead of the field module (1).
Because the destination triangle is an index into another field’s walkmesh, removing or reordering triangles in a .id file can break the gateways of every field that leads to it (and the MAPJUMP opcodes that target it).
Across the 893 retail .inf files, 1632 gateways are used and 9084 are disabled by field ID 0x7FFF.
Triggers data
Doors interactions.
For each trigger:
| Offset | Size | Data |
|---|---|---|
| 0 | 6 | Vertex of corner1 |
| 6 | 6 | Vertex of corner2 |
| 12 | 1 | Door ID (or 0xFF) |
| 13 | 3 | Blank |
Function addresses
| Function | Address | Description |
|---|---|---|
Field_Collision_CheckGatewayCrossing | 0x477980 | Tests the 12 gateways against the player’s move and starts the jump |
Field_Collision_PointToLineDistSq | 0x4774A0 | Squared distance from a point to a segment (touch range test) |
Field_Walkmesh_PlaceEntitiesOnLoad | 0x477C90 | Places the party on the destination triangle when the new field loads |
Addresses are for FF8_EN.exe (2000 PC release), image base 0x400000.
Old formats
In the PC version, you can sometimes see older versions of this format, there are three that are more similar to the format of Final Fantasy VII.
672 bytes format
The first Unknown data are 4 bytes and there is no PVP field.
576 bytes format
Same as 672 bytes format + the first Unknown data in Gateways are not present (like FF7).
504 bytes format
Same as 576 bytes format + There is only one camera range and no screen range.