"//" marks a comment which extends to the end of the current line
Note that () and {} characters require white space around them.
A map consists of a series of entities delineated by {}
An entity consists of a series of either epairs or brushes, one per "line".
An epair is a pair of quoted (via "quotes") strings. The first string of the pair is the key, the second string the value. epairs are used to populate the dictionary of the entity.
A brush is a simple, convex polytope delineated by {}. The format of a brush is as follows:
{ [optional vertex list] <plane spec> <texture name> <texcoord spec> [optional flags] <plane spec> <texture name> <texcoord spec> [optional flags] <plane spec> <texture name> <texcoord spec> [optional flags] ... }
That is, an optional vertex list followed by a number of surface specs, one per line.
The optional vertex list, found in map files produced by Quest3d, is denoted by a colon followed by a number indicating the number of vertexes in the list. Following this, one per line, come the 3d coordinates of the vertexes, one vertex per line. The vertex coordinates are listed in X Y Z order.
There are two formats for the plane spec, selected via the presence (vertex mode) or absence (plane point mode) of the vertex list.
In vertex mode, the plane spec directly describes the shape of the surface polygon. It is simply a number indicating the number of vertexes, followed by a set of 0 based indexes, enclosed in (). The indexes indicate which of the vertexes from the vertex list to use. When compiling the map, only the first 3 vertexes are significant: they are used as the 3 points for calculating the plane.
In point plane mode, the plane spec consists of three point vectors, each enclosed in ().
The three points (from either mode) are then used to calculate the plane normal and offset:
n = (p0 - p1) x (p2 - p1) # normal d = p1 . n # offset
The texture name is just a simple string (no spaces) that specifies the name of the texture within the wadfile.
The texcoord spec is black magic. :) It can be either: (halflife style)
[ sx sy sz s ] [ tx ty tz t ] r s_scale t_scale
or (quake style)
s t r s_scale t_scale
In quake style, the basis vectors for s and t (sv and tv) are taken as the most appropriate axial plane for the surface plane. In halflife style, they're given directly via sv = (sx sy sz), tv = (tx ty tz). sv and tv are then transformed by rotating around their perpendicular by r degrees. How this interacts with halflife style is currently unknown. When rendering, the texture coords (rs, rt) for vertex v are calculated as:
rs = v . sv + s rt = v . tv + t
The optional flags indicate various options for the surface. So far, the only flag supported is "detail", indicating that the brush is a detail brush and not to be used for visibility calculations. If any surface has the detail flag set, the whole brush is affected.
Example map file (vertex mode):
// -- // -- Created with Quest // -- // Quest Group Name: World // Quest Group Flags: 1 // Quest Group Color: 0 { "classname" "worldspawn" "wad" "quake101.wad" { :8 -32 -96 8 -32 32 8 128 32 8 128 -96 8 -32 -96 0 -32 32 0 128 32 0 128 -96 0 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 0 3 7 ) wmet4_4 0 0 0 1 1 4 ( 7 3 2 6 ) wmet4_4 0 0 0 1 1 4 ( 6 2 1 5 ) wmet4_4 0 0 0 1 1 4 ( 1 0 4 5 ) wmet4_4 0 0 0 1 1 4 ( 4 7 6 5 ) wmet4_4 0 0 0 1 1 } { :8 -32 -104 104 -32 -96 104 128 -96 104 128 -104 104 -32 -104 8 -32 -96 8 128 -96 8 128 -104 8 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 0 3 7 ) wmet4_4 0 0 0 1 1 4 ( 7 3 2 6 ) wmet4_4 0 0 0 1 1 4 ( 6 2 1 5 ) wmet4_4 0 0 0 1 1 4 ( 1 0 4 5 ) wmet4_4 0 0 0 1 1 4 ( 4 7 6 5 ) wmet4_4 0 0 0 1 1 } { :8 136 -96 104 128 -96 104 128 96 104 136 96 104 136 -96 8 128 -96 8 128 96 8 136 96 8 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 0 3 7 ) wmet4_4 0 0 0 1 1 4 ( 7 3 2 6 ) wmet4_4 0 0 0 1 1 4 ( 6 2 1 5 ) wmet4_4 0 0 0 1 1 4 ( 1 0 4 5 ) wmet4_4 0 0 0 1 1 4 ( 4 7 6 5 ) wmet4_4 0 0 0 1 1 } { :8 -32 96 104 -32 104 104 128 104 104 128 96 104 -32 96 8 -32 104 8 128 104 8 128 96 8 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 0 3 7 ) wmet4_4 0 0 0 1 1 4 ( 7 3 2 6 ) wmet4_4 0 0 0 1 1 4 ( 6 2 1 5 ) wmet4_4 0 0 0 1 1 4 ( 1 0 4 5 ) wmet4_4 0 0 0 1 1 4 ( 4 7 6 5 ) wmet4_4 0 0 0 1 1 } { :8 -32 96 -24 -32 32 -24 -32 32 8 -32 96 8 -40 32 8 -40 32 -24 -40 96 -24 -40 96 8 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 5 6 7 ) wmet4_4 0 0 0 1 1 4 ( 2 1 5 4 ) wmet4_4 0 0 0 1 1 4 ( 6 5 1 0 ) wmet4_4 0 0 0 1 1 4 ( 4 7 3 2 ) wmet4_4 0 0 0 1 1 4 ( 7 6 0 3 ) wmet4_4 0 0 0 1 1 } { :8 -40 -96 104 -40 96 104 -32 96 104 -32 -96 104 -32 -96 8 -32 96 8 -40 96 8 -40 -96 8 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 3 2 5 ) wmet4_4 0 0 0 1 1 4 ( 5 2 1 6 ) wmet4_4 0 0 0 1 1 4 ( 6 1 0 7 ) wmet4_4 0 0 0 1 1 4 ( 7 0 3 4 ) wmet4_4 0 0 0 1 1 4 ( 4 5 6 7 ) wmet4_4 0 0 0 1 1 } { :8 -32 -96 112 -32 96 112 128 96 112 128 -96 112 -32 -96 104 -32 96 104 128 96 104 128 -96 104 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 0 3 7 ) wmet4_4 0 0 0 1 1 4 ( 7 3 2 6 ) wmet4_4 0 0 0 1 1 4 ( 6 2 1 5 ) wmet4_4 0 0 0 1 1 4 ( 1 0 4 5 ) wmet4_4 0 0 0 1 1 4 ( 4 7 6 5 ) wmet4_4 0 0 0 1 1 } { :8 136 96 -24 136 32 -24 136 32 8 136 96 8 128 32 8 128 32 -24 128 96 -24 128 96 8 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 5 6 7 ) wmet4_4 0 0 0 1 1 4 ( 2 1 5 4 ) wmet4_4 0 0 0 1 1 4 ( 6 5 1 0 ) wmet4_4 0 0 0 1 1 4 ( 4 7 3 2 ) wmet4_4 0 0 0 1 1 4 ( 7 6 0 3 ) wmet4_4 0 0 0 1 1 } { :8 -32 32 -24 -32 96 -24 128 96 -24 128 32 -24 -32 32 -32 -32 96 -32 128 96 -32 128 32 -32 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 0 3 7 ) wmet4_4 0 0 0 1 1 4 ( 7 3 2 6 ) wmet4_4 0 0 0 1 1 4 ( 6 2 1 5 ) wmet4_4 0 0 0 1 1 4 ( 1 0 4 5 ) wmet4_4 0 0 0 1 1 4 ( 4 7 6 5 ) wmet4_4 0 0 0 1 1 } { :8 -32 96 8 -32 104 8 128 104 8 128 96 8 -32 96 0 -32 104 0 128 104 0 128 96 0 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 0 3 7 ) wmet4_4 0 0 0 1 1 4 ( 7 3 2 6 ) wmet4_4 0 0 0 1 1 4 ( 6 2 1 5 ) wmet4_4 0 0 0 1 1 4 ( 1 0 4 5 ) wmet4_4 0 0 0 1 1 4 ( 4 7 6 5 ) wmet4_4 0 0 0 1 1 } { :8 -32 96 0 -32 104 0 128 104 0 128 96 0 -32 96 -24 -32 104 -24 128 104 -24 128 96 -24 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 0 3 7 ) wmet4_4 0 0 0 1 1 4 ( 7 3 2 6 ) wmet4_4 0 0 0 1 1 4 ( 6 2 1 5 ) wmet4_4 0 0 0 1 1 4 ( 1 0 4 5 ) wmet4_4 0 0 0 1 1 4 ( 4 7 6 5 ) wmet4_4 0 0 0 1 1 } { :8 -32 24 0 -32 32 0 128 32 0 128 24 0 -32 24 -24 -32 32 -24 128 32 -24 128 24 -24 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 0 3 7 ) wmet4_4 0 0 0 1 1 4 ( 7 3 2 6 ) wmet4_4 0 0 0 1 1 4 ( 6 2 1 5 ) wmet4_4 0 0 0 1 1 4 ( 1 0 4 5 ) wmet4_4 0 0 0 1 1 4 ( 4 7 6 5 ) wmet4_4 0 0 0 1 1 } { :8 64 -96 32 64 -64 32 128 -64 32 128 -96 32 64 -96 24 64 -64 24 128 -64 24 128 -96 24 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 0 3 7 ) wmet4_4 0 0 0 1 1 4 ( 7 3 2 6 ) wmet4_4 0 0 0 1 1 4 ( 6 2 1 5 ) wmet4_4 0 0 0 1 1 4 ( 1 0 4 5 ) wmet4_4 0 0 0 1 1 4 ( 4 7 6 5 ) wmet4_4 0 0 0 1 1 } { :8 64 -48 32 64 -16 32 128 -16 32 128 -48 32 64 -48 24 64 -16 24 128 -16 24 128 -48 24 4 ( 0 1 2 3 ) wmet4_4 0 0 0 1 1 4 ( 4 0 3 7 ) wmet4_4 0 0 0 1 1 4 ( 7 3 2 6 ) wmet4_4 0 0 0 1 1 4 ( 6 2 1 5 ) wmet4_4 0 0 0 1 1 4 ( 1 0 4 5 ) wmet4_4 0 0 0 1 1 4 ( 4 7 6 5 ) wmet4_4 0 0 0 1 1 } } { "classname" "info_player_start" "origin" "96 -80 64" } { "classname" "info_player_deathmatch" "origin" "96 -80 64" } { "classname" "light_globe" "origin" "48 0 96" }