Painkeep v2 - Smash your opponents with all the Pain you can dish out. Deathmatch mod - make other players "die." Disclaimer - this is a free product with no warranty - see disclaimer.txt for details. Codename - Cataboligne - programmer and proud shovel owner.

Post tutorial Report content RSS feed Quake c - using map entity spawn functions to load Quake III maps in Darkplaces

Darkplaces can load Quake III maps. This tutorial will demonstrate how to get the most of those maps by using quake-c to populate them with quake one entities.

Posted by numbersix on Sep 30th, 2012
Intermediate Server Side Coding.

When you load a map in quake, all the objects that move (monsters and other objects) or a player can interact with (weapons, ammo, armor, etc.) are loaded by a special quake-c function called an entity spawn.

This will be a two part tutorial.

1. Demonstrate how to manage a quake map entity spawn function.
2. Demonstrate how to develop the code to load quake 1 entities on a Quake III map loaded in Darkplaces.

Part 1:

The Quake map entity spawn functions.

When the engine is loading a map and sees a set of brackets { } with "classname" in it it tries to call a quake-c function named by the classname field. Any fields specified that match entity fields ("origin", "name", etc.) are loaded into the new entity before the spawn function is called.

If you want to put a weapon in a quake map, you place this code in a map, usually with a map editor:
(The reason you want to use a map editor, is that the editor calculates the origin for you.)

// entity 24
"classname" "weapon_lightning"
"origin" "48 16 0"

This will cause the engine to spawn a lightning gun at that origin when the map is loaded. This is done with a quake-c spawn function:

/*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
void() weapon_lightning =
precache_model ("progs/g_light.mdl");
setmodel (self, "progs/g_light.mdl");
self.weapon = 3;
self.netname = "Thunderbolt";
self.touch = weapon_touch;
setsize (self, '-16 -16 0', '16 16 56');
StartItem ();

This quake-c code called from the map load section of the engine loads a lightning gun on the map. The origin is set from the data supplied in the map file as shown above.

So if you want to put custom entities in a map, you need the { } code for the map (including origin, brush blocks and other stats) and the corresponding quake-c spawn function. This system is very flexible and makes customization of maps contents very easy. What appears on a map is controlled dynamically from quake-c. This eliminates the necessity of recompiling maps or the quake engine to change entity appearance.

If you wanted a Quake mod to change the base weapons around in deathmatch you could simply rename the weapon spawn functions (found in items.qc):

void () weapon_supershotgun
void () weapon_nailgun
void () weapon_supernailgun
void () weapon_grenadelauncher
void () weapon_rocketlauncher
void () weapon_lightning

You could move those around to change nailguns into lightnings, supershotguns into rocket launchers, and so on. Note that this would radically affect single player / coop and might not have decent ammo balance.

Part 2:

Darkplaces (a Quake one game Engine) can load Quake III maps. (It DOES NOT run Quake III the game - there is a large difference!)

Why do you want to?
Because there are loads of awesome Quake III maps. Example:

Download the complete source file q3items.qc and mod here:

There is one issue - the entity definitions used by Quake III are different from those in Quake.
That means Quake III maps under darkplaces will have few weapons, no ammo, and almost none of the other entities.

Unless you follow this tutorial to create spawn functions to translate the Quake III items to Quake.

Quake III has the following item spawn functions:

// these functions can be defined just like this in quake-c
void() weapon_bfg =
void() weapon_plasmagun =
void() weapon_machinegun =
void() weapon_shotgun =
void() weapon_gauntlet =
void() weapon_grapplinghook =
void() weapon_railgun =
void() ammo_bullets =
void() ammo_grenades =
void() ammo_lightning =
void() ammo_bfg =
void() ammo_slugs =
void() item_armor_combat =
void() item_armor_body =
void() item_armor_shard =
void() item_health_small =
void() item_health_large =
void() item_health_mega =
void() item_quad =
void() item_regen =
void() item_invis =
void() item_enviro =
void() item_haste =
void() item_flight =
void() holdable_medkit =
void() holdable_teleporter =
void() info_player_intermission =
void() target_position =
void() trigger_push =
void() misc_teleporter_dest =
void() target_teleporter =
void() misc_teleporter =
void() play_sound =
void() target_speaker =
void() trap_shooter =
void() shooter_grenade =
void() shooter_plasma =
void() shooter_rocket =

// these function can not be defined - they already exist in quake 1
// this is good, these weapons will load on any quake 3 map darkplaces loads
//void() weapon_rocketlauncher =
//void() weapon_grenadelauncher =
//void() weapon_lightning =
//void() item_health =

// these functions can not be defined because they are quake-c variables!
// Lord Havoc has solved this problem with the method below
//void() ammo_shells =
//void() ammo_rockets =
//void() ammo_cells =

// use these for spawn functions that quake-c blocks because they are variables
// just append spawnfunc_ to them - darkplaces will try spawnfunc_ammo_cells() if ammo_cells() fails
void() spawnfunc_ammo_cells =
void() spawnfunc_ammo_rockets =
void() spawnfunc_ammo_shells =

Now it is simply a matter of copying the code from the spawn functions you wish to substitute.
Or you could try this:

// make this a quake lightning gun
void() weapon_bfg =
self.classname = "weapon_lightning"; // for touch function

// spawn cell boxes
void() spawnfunc_ammo_cells =
// call to prevent suspended items from falling - defined seperately
// if (self.spawnflags & SUSPENDED) q3_suspend();

self.spawnflags = self.spawnflags | 1; // make it a big box - note conflicts with suspend
self.aflag = 50; // q3 ammo boxes contain more ammo

void() ammo_bfg =
// call to prevent suspended items from falling - defined seperately
// if (self.spawnflags & SUSPENDED) q3_suspend();

self.spawnflags = self.spawnflags | 1; // make it a big box - note conflicts with suspend
self.aflag = 100; // q3 ammo boxes contain more ammo

void() ammo_lightning =
// call to prevent suspended items from falling - defined seperately
// if (self.spawnflags & SUSPENDED) q3_suspend();

self.spawnflags = self.spawnflags | 1; // make it a big box - note conflicts with suspend
self.aflag = 50; // q3 ammo boxes contain more ammo

Download the complete source file and mod here:

Painkeep v2.x includes this code tweaked for the painkeep mod.

When Chaos Archon: is released Quake III maps will be supported at a high level of detail where entities are concerned.

Post a comment

You are not logged in, your comment will be anonymous unless you join the community. Or sign in with your social account:

Send Message
Release date
Released 2010
Mod watch
Start tracking
Related Games
Quake First Person Shooter
Related Engines
DarkPlaces engine
DarkPlaces engine GPL Released 2000
Related Groups
Dark Places engine team
Dark Places engine team Developer with 15 members
qc Hardware & Tech with 30 members
QuakeDB Fans & Clans with 148 members