Since map editing is quite untested, a great deal of new
information is pouring in about editing Quake levels. Not everything is here yet. I frequently update the seperate Map Specs and you
can get the latest version from Niklata's web site. Hopefully when editing
becomes more mainstream and the rate of new discoveries comes to a near stop, I won't have to tell you about (or maintain) the standalone file.

Contributors to the Map Section

Thomas Winzig - Confirmation on the model; tag's behavior. HTMLization of original Map Specs doc. Clarified several things. Reorganized the document structure a little bit.Brian Hackert - Info on how to use func_train and path_corner. Told me that targetname and target can have real names for their argument, not just numbers.Remco Stoffer - trigger_counter info, light styles, trap_shooter, some trigger_relay info, teleporting monsters, shootable buttons, and lots of other stuff.Thomas Scherning - Information on the last five brush parameters.Lars Bensmann - Information on using origin with attached brushes, a few bugfixes.Robert Jones - Info on using light tag with fires.Marc Fontaine - Correcting the Y-axis in the coord system.

Quake uses a standard left-handed (X,Y,Z) coordinate system. If you're not familiar with
the reference of "left-handed" to a coordinate system, it basically provides a tactile and visual discription
of the mechanics of the system. If you wrap your left hand around the z-axis, with your thumb facing
the positive position, and clench your hand, your knuckles will face in the direction of the positive
x-axis and your fingertips will face the postitive z-axis. Here's a picture of Quake's system:

^ z +
|
|
|
|
|------------> x+
/
/
/
/
<
y-

Some entities also need to have an angle tag that tells the direction it is facing. The values possible are listed below:

Brushes are one of the two primary components of a MAP file. Each brush defines a solid region.
Brushes define this region as the intersection of four or more planes. Each plane is defined by three
noncolinear points. These points must go in a clockwise orientation:

1st Point \ Those three points define a plane, so they must not be colinear.
2nd Point > Each plane should only be defined once.
3rd Point / Plane normal is oriented toward the cross product of (P1 - P2) and (P3 -P2)
Texture - The name of the MIP texture (without quotes).
x_off - Texture x-offset (must be multiple of 16)
y_off - Texture y-offset (must be multiple of 16)
rotation - The texture rotation angle, in degree.
x_scale - scales x-dimension of texture
y_scale - scales y-dimension of texture

The actual MAP file format is quite simple. It is simply a text file. All Quake editing
tools should support either UNIX or DOS text formats, as id's tools do.

MAP files are the development format for Quake levels. It is preferred that all editors
work with MAP files, as all tools released by id Software also use the MAP file format. A map file is
basically un-'compiled' level data. The actual MAP file is totally unusable by Quake itself until it
is coverted to a BSP file by a BSP builder such as id Software's QBSP. For a MAP file's lightmaps
to be calculated by Quake, the level must also be run through a light builder, such as LIGHT. Otherwise,
everything will be displayed at full brightness. Finally, to speed up the level and ensure proper
display, visibility lists should be calculated by a program such as VIS. The process for building
levels in Quake is quite time-consuming compared to building Doom levels, even on a fast computer.

The generalized format for a MAP file is as follows:

{
entity
{
brush (optional)
}
}
...

Comments in the MAP file are indicated by a "//" (C++ style comment).

Many entity/brush combinations can be put into a map file. All MAP files must contain
with a worldspawn entity, usually as the first entry. This entry defines all of the normal
brushes that make up the structure of the level. There should be only one worldspawn
entity per MAP file. Here's the syntax of the worldspawn class:

Attached entity brushes can have an "origin" tag. It can be used to offset where they appear in the level.

For the rest of the document, when I give you frameworks for a structure, the individual entries can be in any order, and lots are optional. I try to mark if an
entry is optional, although this has not yet been rigorously tested.

The entities define the monsters, things, but also the positions in
space where something must happen. So they are the Quake equivalent
of both the THINGS and the LINEDEF types from DOOM.

The entity definitions are made up of a series of specific details
that define what each is, where it starts, when it appears etc. Each
specific is followed by a modifier that arguments it. All definitions
have the classname specific that identifies that entity. The
classname specifics relate intimately with the
code lump and are the names of functions written in
Quake C.

I have chosen the terms ``specific'' and ``arg'' for the two
different parts of each detail of the definition. These terms may or
may not suit but, they will have to do until we learn what id calls
them.

Specifics Args Description
--------------------------------------------------------------------------------
"classname" "name" // Type of entity to be defined (mandatory)
"origin" "X Y Z" // Coordinates of where it starts in space.
"angle" "#" // Direction it faces or moves (sometimes in degrees)
"light" "#" // Used with the light classname.
"target" "t#" // Matches a targetname.
"targetname" "t#" // Like a linedef tag.
"killtarget" "#" // How much damage the model causes when it shuts on you?
"spawnflags" "#" // Used to flag/describe an entity that is not default.
"style" "#" // Used to flag/describe an entity that is not default.
"message" "string" // Message displayed when triggered (/n for linebreaks)
"mangle" "X Y Z" // Point where the intermission camera looks at
{BRUSH INFO} // In entities that describe triggers/doors/platforms, etc,
// the brush info is inserted into the entity brackets,
// delimited by another set of brackets.
specifics/args present only in models:
"speed" "#" // How fast the model is moved.
"wait" "#" // How long a pause between completion of movement or
// return to original position (in seconds or 10ths)
"lip" "#" // Seems to be a means of adjusting the starting position.
"dmg" "#" // How much damage the model causes when it shuts on you?
"health" "#" // How much damage the model takes before it triggers
"delay" "#" // Time before event is triggered
"sounds" "#" // How much damage the model causes when it shuts on you?
"wad" "wadfile" // The wad2 graphics file used by the world for textures.
"height" "#" // How high a platform will raise
---------------------------------------------------------------------------------
{
"specific1" "arg1" // The first descriptors (usually classname)
"specific2" "arg2" // The second
... // Etc...
{
<INSERT BRUSH INFO HERE> // for entities like doors/triggers/platforms/etc
}
}

Note: The term model refers to a combination of a brush
and an entity. One or more brushes are bound to an entity, which
controls the behavior of the brushes. All brushes are contained
within models.

The model numbers in the compiled BSP (*x) comes from the order in
which the models are stored in the models structure. These numbers
are originally derived from the order of the models in the source MAP file.

The worldspawn model is a bounding box that defines the
extents of the whole world.

The models are defined by a bounding box of the max and
min(x,y,z). Therefore they are always parallel to the
horizontal planes. This would seem to exclude any ramp-like
structures that move.

Have you been wondering how you can get events to trigger when a monster dies, as first
seen in E1M2 with the demons? Well, it's not too difficult. When you attach a
target tag to a monster, the monster's death will trigger the event. I believe
(not tested) that if other monsters have a targetname tag the same as a monster
with the target tag, the target event will only occur when all monsters with
a matching targetname tag are dead. The monster with the target tag need not
have the targetname tag.

The trigger_count class is quite an interesting trigger.
You know of the area in E1M1 where you have to hit the three switches to open the door?
Well, that's done using a trigger_counter. Each of the buttons you hit has its
target property set so it points to a trigger_counter.
The trigger_counter has its count tag set to three. Each time a switch is
hit, the trigger_counter's count property will decrement by one.
When it reaches zero, it will open the door. Each button can only be triggered once as
it has a wait of -1. Here's an example given to me by Remco Stoffer:

Unlike in Doom-Engine games, you can precisely teleport monsters into new locations in Quake. To do so, you must first create a out of reach area for the monsters to reside in. Give this area a trigger_teleport tag and assign a targetname tag to it. Create a teleport_destination where you want the monster to appear. Now, you must create a trigger whose target property points to the trigger_teleport's targetname. When this trigger is activated, the monster in the room will teleport to the teleport_destination. Make sure that there is only one monster per room and one room per teleport_destination. Otherwise, when the teleport is triggered, all the monsters will telefrag each other (like what happens in E1M7 when you win).

The behavior of buttons can be altered in many ways. By default, buttons are activated by pressing them (moving near them). Buttons can be made shootable by giving them a health tag. Unless you want to have to shoot the button tons of times, set the health tag to "1". If you want to have the button flash when you shoot it, you must include all of the button animation textures in the level. You can just put them on brushes outside the level.