Repository navigation
zone
A Zone in Firefall represents an area that you play in, eg New Eden, Devils Tusk.
The world data is defined in chunk files and the Zone file primarily contains additional data that apply for the whole area. It also references the chunks that should be loaded. Multiple zones can use the same chunks.
Zones files contain a timestamp that must match the server, or an error will be thrown and the client will not connect.
The chunks used for a zone can be retrieved either from the Zone file or from the SDB using the dbzonemetadata::ZoneChunkLinker table.
To get the list of chunks for a zone from the Zone file, look under the ZONE_CHUNK_INFO layer (0x20400) for the CHUNK_INFO_RANGE layers (0x10000).
Each range is five uint32s: the cube face, min x, max x, min y and max y.
Then get all the chunk reference layers (0x10101) and get the X and Y values from them.
The references don't store the cube face, it's the one of the range their X and Y fall into.
The name can be made from this data like this. {CubeFaceId}_{X:D4}_{Y:D4}.gtchunk, i.e. X and Y padded to four digits, e.g. 1_0241_0918.gtchunk.
The chunk files are found in a sub folder called chunks in the same folder as the zone files.
The game client appears to use both the data from the zone file and the data from the SDB to setup the game world. There must be at least 1 zone chunk linker record present for the given zone id and the game will use that chunk as a base. This means that the linked chunk has to be present in the zone file and that other chunks must be adjacent to it. E.g., if the SDB references 5_0444_1746, the zone file must reference 5_0444_1746 and could also reference 5_0445_1746, 5_0446_1746 and so on.
The size of a chunk is 512x512. Each zone has an origin of [0, 0, 0]. In a zone with just 1 chunk, this means that chunk will span -256 to +255 on both axis.
However, when the zone has more than 1 chunk (e.g. most zones), exactly which chunk to place at the center point is a little uncertain.
For all maps except Coral Forest and Sertao, finding the center point of the chunk range x and y coordinates independently seem to do the job.
To calculate the coordinates of a specific chunk, determine the chunks index within the chunk zone range using its chunk coordinates, and then determine the relative offset to the index of the chunk placed in the center.
The console command Loc gives you the in-game position in World-Position. In QA-Position, the two first numbers are the chunk X and Y coordinates, followed by the X,Y,Z position within the chunk, giving X and Y in the range 0.0 to 1.0.
The format of the Zone file is made up of a header and then a series of layers(or called nodes) that can have sub layers.
| Field | Type | Notes |
|---|---|---|
magic |
char[4] |
ZONE |
version |
int32 |
8 in 1962 |
timestamp |
uint64 |
Unix time in milliseconds, e.g. 1461290383710 for Sertao in 1962 |
nameLength |
int32 |
Length of the name including the null terminator |
name |
char[nameLength] |
The zone name and its terminator |
root |
Layer | The ZONE layer (0x30000) with everything else below it |
Older readers took the timestamp for microseconds and left the null terminator of the name in the stream.
ulong NodeMarker;
int NodeType;
int Length;
byte[] NodeData;
Layer[] SubLayers;A layer starts with a marker of 0x12ED5A12ED5B12ED following that is an int for the node type id and another int for the length of the layer.
Inside the layer can be layer data and sub layers.
The layer data comes before the sub layers, and can be found if you scan from the offset of the Length item in the current layer to the next layer marker, or the end of the layer data.
The marker is optional. The client reads the first 8 bytes of a layer header and only reads id and length after them when they're the marker, otherwise those 8 bytes already are the id and the length. worldDir and worldMap files use these unmarked layers, zones and chunks always write the marker.
FauFau's GtLayer treats a layer as a container only when its whole data consists of marked layers, everything else stays a data layer.
Keep in mind that a layer with its own data in front of its children reads as a single data layer that way.
The GtChunks use the same layer format, but of course the types of nodes that appear differ between the files.
The same goes for scZone and bnv files, the environment layer (0x50001) below ZONE_DEFAULT_ENVIRONMENT is the same in all of them.
When determining how to parse the layer based on the node type, the parent node type should be taken into account, because within the gtchunks there appears to be cases of the node type ids overlapping.
| Name | ID | Description |
|---|---|---|
| ZONE |
0x30000 (196608) |
Root layer |
| ZONE_SKYBOX |
0x20000 (131072) |
Skybox Record |
| ZONE_DEFAULT_ENVIRONMENT |
0x20100 (131328) |
Default Environment, holds an environment layer (0x50001) |
| ZONE_MELDING |
0x20200 (131584) |
Melding perimeters |
| ZONE_WATER |
0x20300 (131840) |
Water |
| ZONE_CHUNK_INFO |
0x20400 (132096) |
Parent layer for the chunk references |
| ZONE_MELDING_HEIGHT_MAP_DATA |
0x20700 (132864) |
Melding height map |
| ZONE_PATH |
0x20800 (133120) |
Paths |
| ZONE_WORLD_CHUNK_IMPORT |
0x20900 (133376) |
Starts with ENWF, see ENWF
|
| ZONE_135168 |
0x21000 (135168) |
Bounds |
| ZONE_PROP_ENCOUNTER_NAME_REGISTRY |
0x21200 (135680) |
Prop encounter name registry |
| ZONE_PROP |
0x21400 (136192) |
Props, 0x50000 layers like in the chunks |
| ZONE_CAMERA_SEQUENCE |
0x21500 (136448) |
Camera sequences |
| ZONE_TRANSFER_BOUNDS |
0x21600 (136704) |
Transfer bounds |
| ZONE_SUBZONE_REGION |
0x21700 (136960) |
Sub zone regions |
| CHUNK_INFO_RANGE |
0x10000 (65536) |
The cube face and the x and y range of the chunks |
| CHUNK_INFO_REF |
0x10101 (65793) |
A reference to a gtchunk: uint32 x, uint32 y and the SDB ChunkRecord id |
| CHUNK_INFO_REF2 |
0x10100 (65792) |
A reference to a gtchunk, not used by the 1962 zones |
The names come from the 010 template. 1962 zones only use 0x10101 references, 12 bytes each. Earlier versions of this page had the two reference ids the other way around.
- Reader has been implemented in FauFau: Zone.cs. It reads the whole layer tree with
GtLayerand lists the chunk files withZone.GetChunks().