WFA Design notes for 3.5


This addendum is a for the distributed GTK manual with additions/corrections/enhancements made by the coders for the mod Weapons Factory Arena. All due credit and acknowledgement is given to the original authors of the parent of this document.

Before installing, it should be noted that this version is a single client-only version. Only one connection is allowed, host player, and the AI is allowed to connect as well, but anyone who tries to connect to this version that is not localhost will get kicked immediately. Additionally, some things may break... that is probably the case with all betas. This could be even considered alpha, but the functionality is there so we call it beta. We are working on the documentation at this point.

The authors would like to thank the many supporters of WFA level editing who made this work possible. We have a team of designers that are always pushing the limits of what can be done with the stock Quake III Arena engine, at no cost to the player. To the designers, it's a way to express their gratitude for having the tools to accomplish a foundation for creativity to be expressed within the game. For the coders, its a way to enable you to do whatever you want within the engine.

Additionally, many of hours went into testing this new code for mapping, from the compiler in which we support (Q3map2) to the code within the modification itself. Of these, special acknowledgements go to the following:

Static (Shayne Uhr)
ydnar (Randy Rigg)
erp (for miscellaneous random words of wisdom)

Note: This version of the manual is meant to coincide with GtkRadiant and Q3map2. While we do not claim this manual is accurate, we do solidly and proudly state that it's inaccuracies are wildly inaccurate. Some parts may be very outdated, specially all the ones dealing with entities. But the core additions are still very relevant. If you are willing to help maintaining this version more up to date get in touch with us ( 

Note: The designers wished to adhere to the GTKRadiant 1.1.3 until the GTK team releases a stable editor that resembles the same functionality of it's predecessors. Gripes and complaints are not noted nor appropriate, but sometimes sarcasm will be evident.


Weapons factory arena is very CPU  intensive. Anyone who has designed in baseq3 and then loaded their map into WFA has already seen the difference in fps from the code alone. Although this drop is noticeable, it is possible to keep efficiency to the maximum to overcome this issue. Designing for the WFA engine, when it comes down to performance, takes a whole new meaning for what can be done with the stock components of the main quake3.exe executable. Familiarity with openGL, stock quake3 source code, and hardware configurations can be the greatest help. VIS is important when dealing with the corrections that were made within the code, as is maximum surfaces drawn within any player's point of view. Then again, you can just wing it and pray.

Custom surface flags

Since the beginning of 1.29, the ability to add custom surface parms (custinfoparms) has been available to designers. WFA has additional footsteps, as well as a new contents ladder which is required for code reasons. Make sure the custominfoparms.txt is within the working scripts directory, and be sure to add the switch 
to the bsp stage. 

This is mandatory in order for these custom contents and surface flags to work.

New Gametypes

One of the toughest parts of mapping is designing for multiple game types if you unfamiliar with how entities are spawned. Basically, and this is the low-down, WFA maps will not really spawn correctly in any other mode then 4 (ctf) and 8 (commandpoint). Because of this, it's not really necessary to have many deathmatch spawns all over the place. It is required to have at least one playerstart and deathmatch as well as an intermission; it is imperative that they are present.

Command point is basically Domination, where there are 3 entites per map and each team can control any one of those points. Kamikazi, plasmabombs, lasers, alarms are not distance related to these points; it will be something new for most players not familiar with the gametype. The best comparison for the wfa designer who has never mapped for q3 is a chaos of team deathmatch along with command points as goals. The default cap limit so far is 1000. Each team receives a point for each second a point is in their control. You can also spawn any ent within that gametype, so feel free to mix it up as you see fit. 

In addition, all maps for 3.5 must have commandpoint embedded in them otherwise they will not fire up unless they are launched in developer mode. This is important, as older maps will not function without these gametypes and may crash a server. As a 'filter' to read this manual before mapping, if you do not put a "gametype" "ctf" on flags, they will spawn in Domination mode. This was a conscious design decision.

Also I must add that client predicted items, such as teleporters and pushes (again CLIENT predicted) should have separate target entities for their target keys spawned according to their game types. We could fix this (its part of the pickTarget part and entity load order), but it's not a big deal and the fix would be far worse for slower systems then the simple solution for the designer to just not do it. Just remember this so WeridThings(tm) don't happen.

The entities.def

The entity list in WFA is unique. Although you may be familiar with it, it is important to note what it is and what it does. The entities.def is a file for reference for the editor that allows the designer to place objects within the level that determine how the game is actually played. This is extremely customizable, but the meat and potatoes of the def is the list of the entities themselves which cannot be changed. You can't just add a "func_shadowspawn" if you wanted to, but you can change the color of a "func_static" insofar how it appears in the editor, likewise size of ents and colors.

The main difference between WFA and baseq3 maps is the lack of weapons and powerups. All players start with their assigned weapons when they spawn. Ammo can be spawned, however weapons never will be. Powerups also can be spawned, due to the nature of the weapon system it is possible, however the general public frowns upon this as do the coders. A nurse with regenerative powers built in who picks up a Regen will do odd things, as will a cloaked assassin who decides to uncloak while holding the invisibility. Although these items do spawn, it is strongly advisable not to use them except where needed for the AI.

All entities have a key assigned to them, if you wish, as "wf_team" "1" for red, "wf_team" "2" for blue, and trigger multiples have a new key "wf_team" "3" for ai considerations. The "wf_team" "3" can be used to fool the ai into believing they can activate the multiple (no team can), since most maps do not have any other entities that spawn, usually, for bots to form a valid route or weight system. This is a shortcoming, but is powerful if used correctly.

Also it is noted that all func_movers such as doors, rotating doors, static's, explosives you can now grapple to. If the state changes (door starts opening) the grapple will disengage.

A brief note of new entities specific to WFA 3.5:

func_flagevents: This entity will fire at it's targets when the appropriate event occurs. This is only spawns in CTF.
-------- SPAWNFLAGS --------
BlueFlagTaken : Triggers ONCE when the blue flag is taken.
BlueFlagDrop : Triggers ONCE when the blue flag is dropped.
BlueFlagCap : Triggers ONCE when the blue flag is captured.
BlueFlagRet : Triggers ONCE when the blue flag is returned.
RedFlagTaken : Triggers ONCE when the red flag is taken.
RedFlagDrop : Triggers ONCE when the red flag is dropped.
RedFlagCap : Triggers ONCE when the red flag is captured.
RedFlagRet : Triggers ONCE when the red flag is returned.
-------- KEYS --------
gametype: "commandpoint" or "ctf"

func_gameevents: This entity will fire at it's targets when the appropriate event occurs.
-------- SPAWNFLAGS --------
WarmUpEnded : Triggers ONCE when the Warmup ends.
OverTimeStart : Triggers ONCE when OverTime starts.
RedTeamLeads : Triggers ONCE when the red team takes the lead.
BlueTeamLeads : Triggers ONCE when the blue team takes the lead.
TeamsAreTired: Triggers ONCE when teams are tied.
-------- KEYS --------
gametype: "commandpoint" or "ctf"

func_domevents: This entity will fire at it's targets when the appropriate event occurs. This only spawns in COMMANDPOINT.
DOMPOINT1RED : Triggers ONCE when Domination Point 1 becomes RED.
DOMPOINT1BLUE : Triggers ONCE when Domination Point 1 becomes BLUE.
DOMPOINT2RED : Triggers ONCE when Domination Point 2 becomes RED.
DOMPOINT2BLUE : Triggers ONCE when Domination Point 2 becomes BLUE.
DOMPOINT3RED : Triggers ONCE when Domination Point 3 becomes RED.
DOMPOINT3BLUE : Triggers ONCE when Domination Point 3 becomes BLUE.
-------- KEYS --------
gametype: "commandpoint" or "ctf"

func_door_rotating: Rotating door entity. By default, the door will activate when player walks close to it or when damage is inflicted to it.
-------- KEYS --------
gametype: "commandpoint" or "ctf"
wait : number of seconds before door returns (default 2, -1 = return immediately)
targetname : if set, a func_button or trigger is required to activate the door.
health : if set to a non-zero value, the door must be damaged by "health" amount of points to activate (default 0).
dmg : damage to inflict on player when he blocks operation of door (default 4). Door will reverse direction when blocked unless CRUSHER spawnflag is set.
team: assign the same team name to multiple doors that should operate together (see Notes).
distance : how many degrees the door will open
light : constantLight radius of .md3 model included with entity. Has no effect on the entity's brushes (default 0).
color : constantLight color of .md3 model included with entity. Has no effect on the entity's brushes (default 1 1 1).
model2 : path/name of model to include (eg: models/mapobjects/pipe/pipe02.md3).
origin : alternate method of setting XYZ origin of .md3 model included with entity (See Notes).
wf_team : can be set to "1" (red) or "2" (blue)
inskyroom: when set to 1, entity will be visible through the skyportal's camera
-------- SPAWNFLAGS --------
START_OPEN : the door will spawn in the open state and operate in reverse.
SILENT : Don't play sounds.
CRUSHER : door will not reverse direction when blocked and will keep damaging player until he dies or gets out of the way.
REVERSE : if you want the door to open in the other direction, use this switch.
TOGGLE : wait in both the start and end states fro a trigger event.
X_AXIS : open on the X axis.
Y_AXIS : open on the Y axis.
-------- NOTES --------
If you want doors to operate together, you have to team them manually by assigning the same team name to all of them. Setting the origin key is simply an alternate method to using an origin brush. When using the model2 key, the origin point of the model will correspond to the origin point defined by either the origin brush or the origin coordinate value.

You may need to play with adding clip brushes to the ent in order to achieve the result you are expecting.

worldspawn Please note the Q3map2 documentation for other keys. This below is new.
trailbroadcast: 1 or not at all. Used for farplanedist, if you use a farplanedist and have areas where the railgun doesn't show up when you fire it far away, use this key and a value of 1.

dom_point: This entity is the "Domination Point" for the commandpoint mode.
count: "Count (1-3)" : 1
-------- NOTES --------
count relates to the hud, 1 = alpha, 2 = beta, 3 = omega.
message : name of the location (text string). Above names are used if this is not set.
THIS ENT IS SUSPENDED. Bots are not attracted to it. You should use a trigger multiple that is keyed "wf_team" "3" tied to a target_give tied to another ent that resides within this ent.

misc_portal_sky: This is a True portal sky. This is used to project its view origin from a miniature map room onto all nodraw sky in the level. This includes caulk.
-------- SPAWNFLAGS --------
USE_SURFACE : If you're using curves/patches and see "sparklies" gaps between brushes you can't fix, you may use this option and add misc_portal_sky_surface near places you would see the sky.
-------- KEYS --------
gametype: "commandpoint" or "ctf"
-------- NOTES --------
USE_SURFACE changes misc_portal_sky so it's only seen if you're in view of a surface entity.
Movers will not be visible through this unless the "inskyroom" key/value of "1" is set in the mover's key list

misc_portal_sky_surface: Portal Sky surface. This is used to project its local PVS origin to a player. You must use a misc_portal_sky, and keep in mind it's always drawing 'underneath' your brushwork.

trigger_noflight: Any player that touches this will be considered by the code to be in a "No-Fly Zone". Recons in this area cannot use their jetpack.
-------- KEYS --------
gametype: "commandpoint" or "ctf"
-------- NOTES --------
Extensive use of this will have an adverse effect on the CPU usage of a server (just like using a lot of trigger hurts.)

func_particle: By far the most complex entity. Basically, it spawns some particles.
-------- KEYS --------
target : Target the spawner at a target_position.
gametype: "commandpoint" or "ctf"
targetname : If set, a func_button or trigger can turn this spawner on and off.
xrandom : Adds randomness to the particle spawn in the X-Axis. (Default is 0.)
yrandom : Adds randomness to the particle spawn in the Y-Axis. (Default is 0.)
zrandom : Adds randomness to the particle spawn in the Z-Axis. (Default is 0.)
pcolor : This is a set of normalized RGB values for the color of the particles. (Default is 1.0 1.0 1.0, See Notes Below.)
velocity : Modifies the particle velocity. (Default is 100)
duration : Controls the life of each particle, in milliseconds. (Default is 3000.)
frequency : Controls how often the spawner generates a particle. (Default is 0. See Notes below.)
speed : Controls the upward drift speed of particle movement for MODE_2 only.(See notes below.)
width : Sets the starting width of the particles (Default is 1.)
height : Sets the starting height of the particles (Default is 1.)
srandom : Allows individual particle sizes to be randomized within one spawner. (Default is 0. See Notes below.)
endsize : Sets a multiplier to be used with the width and height to determine the end size of the particles when their durations expire. (Default is 1. See Notes below.)
ptype : Determines which graphic is used for each particle sprite. (Default is 1, See Notes Below.)
-------- SPAWNFLAGS --------
START_ON : The particle spawner will start in the ON position, spawning particles.
MODE_2 : Alternate particle behavior mode, see notes below.
-------- NOTES --------
Func_particle is a fairly complicated entity. The xrandom, yrandom, and zrandom parameters allow you to increase the particle spread in all directions. A good starting place is around 50 in each to direction for a mild spread. If you leave them all at 0 you will get a straight line of particles. Velocity modifies the "force" that propels the particles in the direction of your target_position. The default is 100 and is generally a good starting point unless you need your particles to go long distances.
Duration controls how long a particle will stay around before fading itself out of existance. You want this number as low as possible while still generating the effect you are after. A particle that hits a solid object (like a floor) will be deleted automatically and will not float down to lower levels. Frequency controls how many particles the spawn spits out per unit of time. The default is 0 which allows the spawner to go at full speed. A setting of 10 will lessen the number of particles significantly so do not set this value too large initially.
Pcolor allows you to select the color of the particles being emitted. This key requires 3 normalized RGB values in x.x format, each separated by a space. This is the same format as the color key for light entities. It should look something like this: 0.4 0.9 0.2

Ptype allows you to select the graphic used on each particle sprite. WFA includes 8 "pre-made" particle images and allows 2 "custom" images per map. To use a custom image, you must make a shader named <mapname>_particle1 or <mapname>_particle2 where mapname is the BSP name (without directory structure) of your map (For instance, cancer1-wfa_particle1.) The pre-made particle descriptions are listed below :

Type 1 Generic particle
Type 2 Generic bubble (Under Water Only)
Type 3 Large Flare
Type 4 Small Flare
Type 6 Snow Flake
Type 7 Four Point Star
Type 8 Steam Puff
Type 9 <mapname>_particle1 CUSTOM PARTICLE GRAPHIC
Type 10 <mapname>_particle2 CUSTOM PARTICLE GRAPHIC

The last two types must be a black and white jpg for color to work. See the particle shader in the pak for examples of already sepcified sprites.

MODE_2 changes the way the particles behave significantly. Instead of being effected by gravity, they work in the opposite (somewhat like smoke.) They try to rise towards the ceiling based on the speed parameter (if set to 0, they defy gravity.) Additionally, when modifying the X,Y,and Z-randoms the ORIGIN is modified, not the trajectory. This allows for the creation of particle "fields."

The srandom key allows you to randomize particle sizes within one spawner. The same random value is applied to both the height and the width to preserve the size ratio for any given particle. The formula for particle size looks like this:

randomSize = ( <random fraction between 0 and 1> * <the Srandom key> );
height = <the height key> + randomSize;
width = <the width key> + randomSize;
endheight = (<the height key> + randomSize) * <the endsize key>;
endwidth = (<the width key> + randomSize) * <the endsize key>;

In short, you never want the srandom key to be larger than the height or the width. This would potential cause particles with a negative size since the srandom key represent the MAXIMUM deviance that can occur for any particle. This number can be positive or negative. 

The endsize key is a multiplier that is applied to the width and height to determine the end size of the particles when their durations expire. You can use this to cause particles to shrink or grow during the course of their lives (But not both, and size change is linear.) This number is positive for growth and negative for shrinkage.

As an additional note, you CAN point this entity at a moving entity (such as a door or a func_train) and it will adjust the direction of the spray of particles as its target entity moves around the world. It does not currently adjust it's velocity.
Keep in mind that the 'origin' of a door is not necessarily the center. If you want to point it to a mover, it -can help- to make a small brush as the center of the mover and select that brush first when creating the entity.

Where to get help

Most of the time the designers are really busy. This is expected. Fell free to go to and travel to the wfamaps forrum. Our resident forum troll Dizzy might make fun of you, but all the [FNL] guys are like that so heed them no mind. Post your question, and someone will get back to you.

Yep, most of us are on IRC at any one time at channel #wfamaps. Fell free to visit and ask a question. It does help to post first, and don't be surprised if no one is around at first; it doesn't mean you are being ignored. just be patient. If you are using Q3map2 and have a specific q3map2 question, visit #q3map on the same server.

Recommended Tools

Q3map2: (Still in alpha, a16 last stable build, check forums for more information)
GTK Radiant: (1.1.3 supported, use betas at your own risk)
WFA Client and beta files:

Parting Notes

Patience, and check yourself before you wreck yourself.
Read all documentation. Just because bspc.txt is for bots doesn't mean it isn't for humans.
Always use snapshots.
Make sure visdatasize is small. It should take longer to BSP the level then it does to VIS it.
Always use -fast and -fastgrid for light, -fastbounce and -bouncegrid for radiosity.
Always use -meta for bsp
Have fun, always. If its not fun, its not worth doing.