Confaq42
NOTE: All of the information on this page is from around 1999. Some of it is outdated, some of it is just plain incorrect -- this page exists merely to get you started with the very basics of CONs and does not cover any of the additional features introduced in EDuke and EDuke32. In the original DOS Duke 3D, the CON scripting language was relatively limited, and was mainly used to code simple AI routines for monsters and manipulate the player's inventory amounts. Most aspects of the game, such as weapon firing rates, camera positioning, and physics, could not be altered. By contrast, in EDuke32 virtually all aspects of the game can be accessed and manipulated via events, structures and variables, none of which are covered in this document. Nevertheless, this document still serves as a useful introduction to CON coding.
A GENERAL CON OVERVIEW
Con File Editing - An Introduction
Con file editing is one of the coolest aspects of Duke Nukem 3D, and can be very productive in making Total Conversions and other game add-ons. Although it can look very difficult at first, editing con files is very easy and a fun way to make one of the coolest games in history even cooler.
How does one edit con files you ask? Any text editor will do. I personally use Microsoft Wordpad (not Word) to edit con files (this program comes with Windows 95), but you can use any text editor you wish. The Microsoft Notepad program is not large enough to edit con files (the files are too big for notepad to handle), but the DOS editing program works quite well. Simply open up your favorite text editor and open the con file that you wish to edit.
OK - You've opened a con file, but what do I do now? Well, if you're really serious about con file programming, you need to read through this FAQ. Even if you're not so serious about editing con files, quickly skim through this FAQ to find out how to edit some of the easiest parameters and settings in Duke Nukem 3D. You can do some very cool stuff with con files, so stick with it if you don't get it right away. If you have ever done any programming, you will instantly be able to edit con files.
The most important instruction, however, for editing con files is simply - Have fun! This stuff shouldn't make you frustrated - if you aren't getting something, take a look through this FAQ, or visit the editing and hacking forum at Dukeworld. I personally hope you enjoy your con editing experience.
DEFS.CON
This con file is the file where all basic definitions are made. Definitions for sounds, actors (sprites), and some other miscellaneous items can be found in this file. This file is included by the game.con at compile time (when the game is run).
USER.CON
This con file is one of the easiest to edit. Parameters such as weapon strengths, health values, ammo values, level names, quotes, names of sounds, names of episodes (version 1.4 and 1.5 only), names of difficulty levels (version 1.4 and 1.5 only), and more exist in this con file. This is a fun con to edit, especially if you never wish to get deeply involved into con editing and hacking. This file is also included by the game.con at compile time (when the game is run).
GAME.CON
This con file is the largest and the most complicated con file to edit. This file holds all the code for most actors in the game (some of the actors are hard coded). Most of the primitives available are used in this con file, and things can get quite complicated if you don't know where to start. This file gets compiled first at compile time, and includes (#include) the other two con files provided by 3D Realms. This is the con file to work with if you seriously want to get into con editing and hacking.
CON BUILDING BLOCKS
What is an action?
An action is used to give a group of sprites, usually which are animated (as in an enemy movement or other such animated examples), a name. The structure for this primitive is:
action <name> <startframe> <frames> <viewtype> <incvalue> <delay>
<name>
This is the name of the action. This is simply a string which can be up to 64 characters in length.
<startframe>
This is the relative starting frame number (relative to the main sprite of the action that is). For example, if you want the Pigcop to look like the atomic health, you need to give the starting frame a number of -1900 since the Pigcop sprite is located at 2000 and the atomic health sprite is located at 100 (100 minus 2000, is -1900).
<frames>
This value is the total number of frames in the action.
<viewtype>
This value determines whether the sprite is one sided (it looks the same no matter what angle you see it from) or 3-Dimensional. Legal values for this parameter are:
- 0: Single image - It always faces the player no matter where they look from.
- 5: Five images - The first image is looking from the front, the second is 45 degrees from the front, the third is from the side, the fourth is 45 degrees from the rear (135 degrees from the front), and the fifth value is looking from the rear. The second, third, and fourth are used for either side of the image.
- 7: Seven images - Same as 5, except there are seven images, with images 2, 3, 4, 5 and 6 are on both sides. Image 4 is the side images, 1 and 7 are the front and rear respectively. These increment every 30 degrees.
- 8: Eight images - The first image is looking from the front, the second is 45 degrees from the front to the left, the third is from the left side, the fourth is 135 degrees from the front to the left, the last/fifth value is looking from the rear, the sixth is 135 degrees from the front to the right, the third is from the right side and the fourth is 45 from the front to the right.
<incvalue>
This parameter specifies the "direction" of the animated frames. A value of 1 causes the animation to go forwards (Example: The animation starts at tile #20, goes to #21, then to #22, etc.). A value of -1 causes the animation to go backwards (Example: The animation starts at tile #20, goes to #19, then to #18, etc.).
<delay>
This determines how long each frame of the animation lasts. Bigger values allow each frame to last longer.
What is an actor?
An actor is a sprite that will perform some function (spawn another sprite, give the player ammo, etc.) by performing several lines of code.
The structure for this primitive is:
actor <name> <strength> <action> <speed> <aifunction> {actor code} enda
<name>
This parameter is usually a string (such as PIGCOP) that is used to set the initial sprite of the actor. If you look in DEFS.CON, you will see that PIGCOP is defined to be 2000, meaning that the initial sprite for the PIGCOP actor is sprite #2000.
<strength>
This is the "health" value of the actor. If a value of 0 is used, the actor cannot be destroyed.
<action>
This parameter is the action that the actor is to use initially.
<speed>
This is the rate of movement of the current actor. A value of 0 means that the actor cannot move.
<aifunction>
The actor's initial ai routine. This is really only used with monsters.
{actor code}
Now that we have defined our actor, we have to write its code. Each time the actor being referenced is called (and this happens every frame for most animated actors), the code here is executed. This can be many lines of code, since you are grouping them together with the curly braces.
enda
This parameter signals the end of the actor definition.
Notes:
In version 1.3D of Duke Nukem 3D, new actors cannot be added. The name of an existing actor, its corresponding code, and the artwork itself can be changed to add new actors (if you want to go to all of this trouble).
In versions 1.4 or 1.5, however, you can create your own actors (without having to replace existing ones). See the section on "useractor" for more information on this.
What is an ai?
An ai is an "artificial intelligence" routine. This is basically a set of code that an actor follows when said actor is instructed to do so. The structure for this primitive is:
ai <name> <action> <speed> <type>
<name>
This is a name to identify this ai routine later on.
<action>
This value is the name of the action that the actor will cycle through when he uses this ai function (i.e. - the animation it will use).
<speed>
The rate of movement of the character when using this ai function. Negative values are allowed in this parameter.
<type>
Determines the type of ai routine. The ai types are already programmed into the game so you can't change these. Some of the legal types are:
- faceplayer: Actor faces the player's current position.
- geth: Actor travels in a horizontal direction.
- getv: Actor travels in a vertical direction.
- randomangle: Actor will change to a random angle when it touches a wall or when the actor is currently being shot at by the player. Only seems to work when the actor is a monster.
- faceplayerslow: Actor faces the player's current position but slower than the regular faceplayer command.
- spin: Actor spins in circles.
- faceplayersmart: The actor will face slightly ahead of the player's current position, making it possible for monsters to "lead" you a little bit.
- fleeenemy: Actor faces directly away from the player.
- jumptoplayer: Actor attempts to jump.
- seekplayer: Actor tries to find and move to the nearest player.
- furthestdir: Actor faces the furthest distance from the closest player.
- dodgebullet: Actor attempts to avoid all shots directed at him.
You can use more than one ai at the same time by listing them in order in the code that you write. For example: randomangle dodgebullet fleeenemy
What is a state?
A state is a set of code that you will use several times (this is very useful in that you don't have to write the same code over and over). The usage for this primitive is as follows:
state <name> {code} ends
<name>
This is the name of your state function. Can be any string.
{code}
This is simply the lines of code that you want to have executed when the state is called. This can be any number of lines you want.
ends
This parameter signals the end of the state definition.
Here is an example of a state:
state findgoldenapple // Start and name the state itself. { quote 150 // This is the code to execute... addphealth 10 } ends // End of state. Now returns to its caller.
To call a state from your code, simply type the following:
state <name>
The <name> parameter is simply the state that you want to call.
What is a useractor?
[This function only works with versions 1.4 and 1.5]
The useractor command is a new addition to versions 1.4 and 1.5. It allows people to create their own actors without having to replace old ones. It's usage is almost exactly like regular actors.
The structure of the useractor command is as follows:
useractor <type> <name> <strength> {actor code}
<type>
This parameter is the type of actor that you want to create. The legal values are as follows:
- enemy : The actor's code will not be executed until approximately 1 second after the player has spotted the actor.
- notenemy : The actor's code will not be executed until the player has spotted the actor.
- enemystayput : The actor will not leave the current sector when the player goes out of sight (i.e. - the actor can no longer "see" the player). This is most useful in custom enemy creation.
<name>
This parameter is usually a string (such as PIGCOP) that is used to set the initial sprite of the actor. If you look in DEFS.CON, you will see that PIGCOP is defined to be 2000, meaning that the initial sprite for the PIGCOP actor is sprite #2000.
<strength>
This is the "health" value of the actor. If a value of 0 is used, the actor cannot be destroyed.
{actor code}
This is the code that the actor will run. This code includes the following items:
<action>
This parameter is the action that the actor is to use initially.
<speed>
This is the rate of movement of the current actor. A value of 0 means that the actor cannot move.
<aifunction>
The actor's initial ai routine. This is really only used with monsters.
What is an if construction?
If statements are perhaps the most powerful aspect of CON file editing. If statements evaluate the specified condition, and run code based on the returned value of the evaluation.
Here is an example:
ifphealthl MAXPLAYERHEALTH addphealth MAXPLAYERHEALTH else quote 999
This simple example simply says this:
If the player's health is less than MAXPLAYERHEALTH (which by default is 100), add MAXPLAYERHEALTH to the player's current health. Else, if the player's health is not less than MAXPLAYERHEALTH, print quote number 999
A COMPLETE PRIMITIVE LISTING
The Complete Primitive List
Note by TerminX: this list is outdated and obsolete. See this page for the current list of primitives.
The following is a complete listing of all the "primitives" that can be placed into Duke Nukem 3D CON files. Primitives are simply commands and syntax in code that can control and test the items in the game.
If you find any errors in this section, e-mail me at: jonahb@3dportal.com
//
This is used (just like in C\C++) to denote comments. Everything after this comment mark is ignored by the compiler. A space must follow this comment mark, or the compiler will generate an error.
/* and */
These two marks are used to create comment blocks (just like in C\C++). Place the /* at the beginning of the area you wish to ignore, and the */ at the end of the area you wish to ignore. This is a handy way to create large comments or to ignore an entire section of code.
{ and }
These symbols are used to group several lines of code into one block of code (also called a function). Used just like C\C++.
action <name> <startframe> <frames> <viewtype> <incvalue> <delay>
See section 2.1 for an in-depth look at this primitive.
action <name>
Starts the action specified by <name>.
actor <name> <strength> <action> <speed> <aifunction> {actor code} enda
See section 2.2 for an in-depth look at this primitive.
addammo <weapon> <amount>
Adds the <amount> of ammunition to the current or closest player's value for the appropriate <weapon>. Legal values for <weapon> can be found in section 4.1.
addinventory <item> <amount>
Adds <amount> to the current or closest player's value for the appropriate <item>. Legal values for <item> can be found in section 4.2.
addkills <amount>
Adds <amount> to the current or closest player's kill count.
addphealth <amount>
Adds the value <amount> to the current or closest player's health. Only the atomic health actor can boost the player's health value over the MAXPLAYERHEALTH value.
addstrength <value>
Adds <value> to the strength (health) of the current actor.
addweapon <weapon> <ammo>
Gives the current or closes player the specified <weapon> with an initial amount of ammunition equal to <ammo>. Legal values for <weapon> can be found in section 4.3.
ai <name> <action> <speed> <type>
See section 2.3 for an in-depth look at this primitive.
ai <name>
Makes the ai function <name>, the current actor's current ai routine.
Immediately leave the current state or actor code.
cactor <actor>
Change from the code of the current actor to the code of the actor identified by <actor>. All initialization values of the specified <actor> are ignored when this primitive is used.
clipdist <value>
The <value> parameter can be any value from 0 to 255. When a sprite or actor is blocked (by setting blocking with the [B] key in Build or through the use of the cstat primitive in GAME.CON), a "force field" (for lack of a better term) is set up around the sprite. The clipdist value determines how close an actor can get to the sprite before being blocked by that invisible "force field". The lower the value, the closer the player or an actor can get. A clipdist of 255 equals the distance of the largest grid size in Build which equals 1024 Build units. The default for <value> seems to be 32. The same effect can also be achieved in Build by placing the cursor on the sprite (in 3D mode) and pressing the [ALT]+[D] key combination. Also, it would appear that this only works on a sprite that rotates with the player. If (in Build's 3D mode) you press the [R] key to align the sprite to the grid or to the floor, altering the clipdist primitive has no effect. In addition, this attribute does not work on all sprites. At this time there is no explanation for why this primitive should either work or not work.
count <number>
Sets the current actor's count to <number>.
cstat <mask>
This primitive manually sets some various flags for an actor (a sprite). All previous settings are lost when this function is used. The legal values for <mask> can be found in section 4.4.
cstator <mask> (Used in Versions 1.4 and 1.5 Only)
This primitive manually sets some various flags for an actor (a sprite). All previous settings are not lost when this function is used; they are simply added together. This is a little like the "or" in C\C++. The legal values for <mask> can be found in section 4.4.
debris <type> <amount>
This primitive causes debris to fly around the actor. The <type> parameter is the sprite group used for the debris. Legal values are: SCRAP1, SCRAP2, SCRAP3, SCRAP4, SCRAP5, and SCRAP6. The higher the <amount> value, the more debris.
debug <parameter>
Prints the value of <parameter> to the current output buffer. If a standard game is loaded, with the default output buffer being used, it will print the value to the screen. If the output buffer is changed (for example: "duke3d.exe -map test.map /q8 > test.log"), the standard output will be printed to the output buffer "test.log". You then can open this file later to look at the values that were printed out.
define <string> <value>
This primitive makes <string> equal <value>. This allows you to use the string (which is a lot easier to remember) in your coding. The following example sets the string MAXPLAYERHEALTH to the value of 100.
EXAMPLE: define MAXPLAYERHEALTH 100
definelevelname <eps> <lvl> <mapname> <par time> <3drealms>
Defines a level name where the episode number is <eps>, the level number is <lvl>, the map name (a string) is <mapname>, the par time is <par time>, and the 3D Realms time is <3drealms>.
definequote <value> <string>
Sets <string> equal to <value>. This is used when printing quotes at the top of the screen while in the game (it saves you from having to type the quote over and over).
defineskillname <skill> <string> (Used in Versions 1.4 and 1.5 Only)
Makes <string> equal the desired difficulty level (which is <value>). Legal values for <skill> are: 0, 1, 2, and 3. The higher the number, the harder the skill level. This is only used for setting the text of the skill levels on the skill level selection screen.
definesound <value> <file> <pitch1> <pitch2> <priority> <type> <volume>
The <value> parameter is the name of the sound (you make this up). The <file> parameter is the .voc or the .wav file that the game will try to find to use for this sound. The <pitch1> and <pitch2> are random pitch variations (these can be both negative and positive). The <priority> is the importance of the sound (telling the game that this sound has priority over other sounds). Values of 0 to 255 inclusive are acceptable for <priority>, with larger numbers being more important. The <type> is the type of sound in the game. Legal values for <type> are: The <volume> is the volume of the sound, ranging from -32,767 to 32,767. Negative values are louder and positive values are softer.
definevolumename <episode> <name> (Used in Versions 1.4 and 1.5 Only)
Defines title for each episode where <episode> is the episode number and <name> is the name it will get.
This is used in "if-else" statements. This returns true if the last function returned false.
Closes an actor or useractor function.
endofgame <number>
Ends the game after <number> counts. For example, a value of 180 would end the game after approximately 6 seconds (30 = 1 second). A value of 52 is used to end each episode. This primitive obviously appears to exist as a "sleep" function of sorts. I believe that this is used to allow the death sequence of the boss to be completely viewed by the player, but this is only one suggestion as to its proper use.
Closes a state function.
Let the current actor fall until it hits a surface.
This is the main function which "starts" the game. It gets all the hard coded values passed as parameters. The values that get passed can not be changed during gameplay. There are too many parameters for this primitive to list here, so take a look at the user.con file.
Sets the palette of the current actor back to the color before the last change.
globalsound <sound>
Play sound that can be heard everywhere in the map. The <sound> value is the name of the sound to play (not the filename of the sound).
guts <type> <amount>
Same as debris but then for body parts. Legal values for <type> can be found in section 4.5. The <amount> value determines the amount of guts to make fly.
hitradius <radius> <1> <2> <3> <4>
Make an explosion (not the actual animation but just the damage). The <radius> value is the radius, <4> is how much damage is done in first quarter of circle (right near the center of the circle), <3> is how much damage is done in second quarter of circle, etc.
ifaction <action>
Test if the current actor is executing the giving <action>. The <action> parameter is defined by the action primitive (see section 2.1).
ifactioncount <number>
Tests if the actor has displayed a set <number> of frames since the last call to resetactioncount.
ifactor <actorid>
Returns true if the current actor is equal to <actorid>.
Test if the current actor already <activated>, where <activated> means spotted by a player or he has spotted the player. It seems that an actors code isn't executed at all until one of the above events occur. You can notice this in the game. If you create a map where an actor (i.e. health) is lifted into the sky, he doesn't fall down to the ground until you spot it! (I'm not 100% sure about this one).
ifai <ainame>
Tests if the current actor is using the ai function <ainame> which was defined with the ai primitive (see section 2.3).
ifangdiffl <angle> (Used in Versions 1.4 and 1.5 Only)
Returns true if the angle between the current actor and the player is less than <angle>. 360 degrees is a value of 2048.
Returns true when an actor is away from all walls (including sector divisions (red lines)) in the game.
Returns true if the current actor is being shot at (bullets are coming close to the actor).
Tests if the current actor can see the player. It also seems to have another function. It seems as if you need to call this function to give an actor a new position to walk to when using the seekenemy and some other ai functions. If you don't call this when using that ai function he will just walk up to your previous position and just stop there!
Returns true if the current actor can see the player.
Returns true if the current actor can shoot the player (which seems to be the only target the actor has).
ifceilingdistl <number>
Returns true if the distance between the current actor's center and the ceiling is less than <number>.
ifcount <number>
Returns true if the current actor's local counter has reached <number> counts.
Returns true if the current actor has no strength (health) left. The actor must have had health at some point for this to return true.
iffloordistl <number>
Returns true if the distance between the current actor's center and the floor is less than <number>.
ifgapzl <number>
Tests if the distance between the floor and the ceiling at the actor's location is less than <number>.
ifgotweaponce <number>
If <number> is set to 0, in multiplayer games of either cooperative or dukematch with the no spawn option turned on, the player can only get the weapon if they don't already have it. If <number> is set to 1, in multiplayer games of either cooperative or Dukematch with the no spawn option turned on, the player cannot get the weapon at all.
Tests to see if the player is pressing the use key (which is the spacebar by default).
Returns true if the current actor has been hit by a weapon.
Returns true if the following parameters are true: "ifinspace" is true and the ceiling (or floor) palette on the BigSpace texture is 0. This primitive is basically useless, since it is called a split second before the player dies from the vacuum of space.
Checks if current player is in space. "Space" means when the floor or ceiling is parallaxed and the texture is one of the space textures.
Tests if the current actor is in a sector with a lotag of 2 (underwater sectors).
ifmove <name>
Returns true if the current actor is using the movement defined by <name>.
Returns true if the current game is a cooperative game.
Tests if the current actor is not playing any sound effects.
Returns true if the current actor has stopped moving. This is used to test if an actor is "stuck" against a wall (usually a monster stuck near a door) - at which point the "operate" primitive can be used to allow the stuck actor to try and free himself.
Returns true if the current actor is in a sector with a lotag of 1 (above water sector) and is on or near the surface.
Tests if player is outside. A player is outside when he is in a room with parallaxing on.
ifp <type>
Returns true if the current <type> is true. Legal values for the <type> parameter can be found in section 4.6.
ifpdistg <number>
Tests if the current or closest player's distance is greater than <number>. A value of 1024 is equivalent to the largest grid size in Build.
ifpdistl <number>
Tests if the current or closest player's distance is less than <number>. A value of 1024 is equivalent to the largest grid size in Build.
ifphealthl <number>
Tests if the player's health is less than <number>.
ifpinventory <item> <amount>
The <item> value is the inventory item to be tested. The <amount> value is the amount to test for. This function will return true when the <item> is not equal to the <amount> value. Legal values for <item> can be found in section 4.2.
For monsters, tests if monster respawn mode is turned on. For items, tests if item (weapons, ammo, etc.) respawn mode is on.
ifrnd <number>
Generates a random probability of something happening. The <number> value divided by 256 is the chance that something will happen. So a value of 256 would happen all the time (256/256 = 1 = 100%).
ifspawnedby <actor>
Checks if the current actor was spawned by <actor>.
ifspritepal <number>
Tests if the palette of the current actor is equal to <number>.
Tests if the current actor has been squished. This can be caused by the actor being shrunken and stepped on, or squished by a falling sector (i.e. - the ceiling height of the sector at one point or another is the same height at the floor height of the sector).
ifstrength <number>
Tests if current actor has <number> strength (health) left.
ifwasweapon <weapon>
Tests what weapon the actor has been hit by. This primitive appears only to work after the "ifhitweapon" primitive is called. The legal values for <weapon> can be found in section 4.7.
include <filename>
Includes <filename> in the compiling process.
Removes the current actor from the map.
lotsofglass <amount>
Spawns glass shards, much like when a window has broken. The <amount> parameter determines the number of glass shards to spawn.
mail <number> (Used in Versions 1.4 and 1.5 Only)
This primitive spawns some envelope sprites. The <number> value is the amount of mail to spawn.
Plays the sound assigned to the microphone sprite in Build (the microphone sprite's hitag is the sound number to be played). This might be available for use on other sprites (other than the microphone that is). I'm not 100% sure.
money <number>
This primitive is used to spawn a specified <number> of dollar bill sprites.
move <name> <horizontal> <vertical> <directions>
Assigns <name> to a <horizontal> and <vertical> velocity, with optional <directions>. See section 4.10 for a listing of valid <directions>. Also used to tell an actor to move with the desired velocities and directions.
music <episode> <m1> <m2> ...
Defines the music used for each level in each episode. The <episode> parameter is the episode number, with the individual music files following the episode number. This is usually defined in user.con.
The nullop primitive is another way to signify empty braces - {}.
This primitive is used to allow the current actor to operate, which simply means that the current actor can open a door if one is nearby. The actor should not constantly operate, because the door will close again if the actor operates immediately after operating the first time.
palfrom <intensity> <red> <green> <blue>
This primitive is used to flash a specified color (set by mixing the <red>, <green>, and <blue> parameters) on the screen with a specified <intensity> amount. The values for the any of the parameters can be anything between 0 and 64.
paper <number> (Used in Versions 1.4 and 1.5 Only)
Spawns some paper sprites, which then float down to the ground. The <number> parameter is the amount of paper to spawn.
The current or closest player will perform a "quick kick".
The current or closest player will look down and step on the nearest actor (if one is near).
quote <number>
This primitive prints quote <number> at the top of the screen. All game quotes can be found and are defined in user.con.
Sets the action counter to 0. This counter counts the number of frames of animation that the current actor has displayed.
Set the current actor's local counter to 0.
In a multiplayer game, this primitive spawns the player at one of the multiplayer starting positions, with the default amount of ammo, armor, and health. In a single player game, this primitive simply restarts the current level.
This primitive activates up to 9 respawn actors who have the same lotag as the current actor's hitag.
shoot <weapon>
Allows the current actor to shoot - eject - fire the specified <weapon>. Legal values for <weapon> can be found in section 4.8. The direction that the <weapon> is fired depends on the AI function of the actor.
sizeat <x> <y> (Used in Versions 1.4 and 1.5 Only)
Immediately resizes the current actor to <x> width and <y> height.
sizeto <x> <y>
Gradually resizes the current actor to <x> width and <y> height.
This primitive makes the current actor sleep for
sound <sound>
This primitive plays a specified <sound>. The <sound> parameter is the name of the sound to be played (these can be found in user.con).
soundonce <sound>
This primitive plays a specified <sound>. The sound cannot be activated again until it has completely finished playing.
spawn <actor>
Creates a new actor (defined by <actor>) in the map. Some special actors can be spawned to create some neat effects. See section 3.4 for more information on which actors are special to the spawn primitive.
spritepal <number>
Changes the current actor's palette to <number>. Legal values for <number> can be found in section 4.9.
state <statename> {code} ends
This is used to construct a state function. See section 2.4 for a more detailed description of what this does.
state <statename>
This primitive calls a state function with <statename> being the name of the state function. The state function must be above where this line is called.
stopsound <sound>
Stops the currently playing <sound> from playing.
strength <number>
This primitive changes the strength (health) of the current actor to <number>.
Starts the current or closest player's "tipping" routine.
This primitive spawns the player's currently selected weapon when the player dies in the game.
This primitive tilts the screen to one side when called.
Predefined State Functions
The following is a listing of (most) state functions that already exist in the GAME.CON file. You can alter these to your liking, but the default functions are described here. The states are listed in order of appearance (at least in the 1.4/1.5 CON files).
state jib_sounds
Plays one of those nice sounds like "What a mess" or "Let God sort em' out".
state standard_jibs
Spawns some random body parts.
state genericshrunkcode
Shrink an actor and stomp on it if you are within the correct distance.
state genericgrowcode (Versions 1.4/1.5 Only)
Make the current actor grow and then explode.
state blimphitstate
Spawn an explosion and debris, kill the actor, and some other stuff...
state rats
Spawn some rats.
state toughgalspeech (Versions 1.4/1.5 Only)
The sounds to play when the tough girl talks.
state jibfood (Versions 1.4/1.5 Only)
Make food disappear when shot and spawn some gross jibs.
state breakobject (Versions 1.4/1.5 Only)
Code that makes all the breakable objects in versions 1.4 and 1.5 break when shot by the player.
state headhitstate
Gets called when player is hurt badly. The screen tilts when the player gets hit and his health is very low.
state burningstate
Set the current actor on fire.
state steamcode
Update steam sprite, subtract health from player who is near, etc.
state random_ooz (Versions 1.4/1.5 Only)
Spawns some ooze.
state burningbarrelcode
Code for a burning barrel.
state getcode
Gets an item and prepares it for respawn (if necessary).
state randgetweapsnds
Plays a random sound when a weapon is picked up by the player. Examples are "Groovy" or "Come get some!".
state getweaponcode
Gets the current weapon and prepares it for respawn if necessary.
state respawnit
Respawn items in a multiplayer game.
state quikget
Get code for the atomic health or other items. Does not cause the sprite to respawn.
state quikweaponget
Get code for weapons.
state firestate
Updates flames, checks to see if Duke is burning himself, etc.
state drop_ammo
Drops ammo if the odds for dropping it are right.
state drop_battery
Drops chaingun ammo if the odds for dropping it are right.
state drop_sgshells
Drops shotgun ammo if the odds for dropping it are right.
state drop_shotgun
Drops shotgun if the odds for dropping it are right.
state drop_chaingun
Drops chaingun if the odds for dropping it are right.
state random_wall_jibs
Spawns blood on the walls when an enemy is shot and near a wall.
state femcode
Takes care of the female actors in the game.
state killme
Lets some women say "kill me" when the player presses the space bar near her.
state tipme
Lets Duke give some women a dollar bill and say "Wanna dance" or "Shake it baby".
state toughgaltalk (Versions 1.4/1.5 Only)
Make the tough girl talk when the player presses [SPACE].
state troop_body_jibs
Spawns some trooper body parts.
state liz_body_jibs
Spawns some lizard body parts.
state standard_pjibs
Spawns some Duke body parts.
state handle_dead_dukes
The code for making blood pools, etc. when Duke dies. Also handles the disappearing for Duke's body in multiplayer.
state check p_standard
Makes the animations of Duke walking when walking, jumping when jumping, etc.
state rf
Changes the cstat to 4 ifrnd 128, else it makes the cstat 0. This is used in flipping corpse sprites so they don't all look the same.
There are too many enemy states to put here, but they all cover the basic artificial intelligence routines for each enemy.
Known Bugs and Problems
- Bug #1: Calling an ai routine (from an actor or state) that is already running, will cancel the ai routine, leaving the actor or state frozen in its code execution. The only known workaround for this bug is to make sure that the ai routine you want to call isn't already running.
- Bug #2: Sometimes con files don't want to compile properly, especially when user code or actors is added. The fix for this is extremely simple: A blank line must appear at the end of every con file that you edit. Some problems can occur with this bug, so it is recommended to check this before compiling your con files.
Special Notes
- Note #1: There are several special actors that can be used with the spawn primitive. These special actors are as follows:
- EXPLOSION2 - When this actor is called for the first time, it will create light, which can be used to create some minor lighting effects. NOTE: You can do the same thing in EDuke32 with the flash parameter.
- FRAMEEFFECT1 - When this actor is spawned, a blurring effect is caused on the affected actor. This is used to make the blurring effect when monsters in the game are shrunk with the shrink ray weapon. If you are using steroids, then your view of yourself (and other players in multiplayer) will be blurred.
- Note #2: It appears that the "ifhitweapon" primitive must be executed if a weapon is to damage an actor. If it is not, the actor cannot be destroyed.
- Note #3: The "move" primitive seems to cancel any running commands when called. I'm currently not 100% about this fact, but I have heard this rumor several places.
- Note #4: The BLIMP actor uses the "debris" primitive, but it spawns ammunition, inventory items, and weapons instead.
- Note #5: The ATOMICHEALTH actor is the only actor capable of raising the player's health value above MAXPLAYERHEALTH.
- Note #6: Removing an actor's image from the .art files prevents them from being spawned in the game. Tile number 0 (the ugly, brown, brick wall) will be spawned in their place.
LEGAL VALUES
Values for addammo
KNEE_WEAPON PISTOL_WEAPON SHOTGUN_WEAPON CHAINGUN_WEAPON RPG_WEAPON HANDBOMB_WEAPON SHRINKER_WEAPON TRIPBOMB_WEAPON DEVISTATOR_WEAPON FREEZE_WEAPON HANDREMOTE_WEAPON GROW_WEAPON [Versions 1.4 and 1.5 Only]
Values for addinventory and ifpinventory
GET_STEROIDS GET_HEATS GET_BOOTS GET_SHIELD GET_SCUBA GET_HOLODUKE GET_JETPACK GET_FIRSTAID GET_ACCESS
Values for addweapon
PISTOL_WEAPON SHOTGUN_WEAPON CHAINGUN_WEAPON RPG_WEAPON HANDBOMB_WEAPON SHRINKER_WEAPON TRIPBOMB_WEAPON DEVISTATOR_WEAPON FREEZE_WEAPON GROW_WEAPON [Versions 1.4 and 1.5 Only]
Values for cstat and cstator
1 = Make sprite blockable ("B" in BUILD) 2 = Make sprite 'see-through' 4 = Flip sprite around x-axis 8 = Flip sprite around y-axis 16 = Draw sprite as wall texture (vertically flat) 32 = Draw him as floor texture (horizontally flat) 64 = Make sprite one sided 128 = Half submerged 256 = Make sprite solid ("H" in BUILD) 32768 = Invisible
Note: To use more than one setting add the values together (264 = solid (256) + upside-down (8). 256 + 8 = 264).
Values for guts
JIBS1 JIBS2 JIBS3 JIBS4 JIBS5 JIBS6 HEADJIB/LEGJIB/ARMJIB (trooper parts) LIZMANHEAD1/LIZMANARM1/LIZMANLEG1 (lizman\newbeast parts) (Note: NEWBEAST spawns these with a spritepal of 6.) DUKETORSO/DUKELEG/DUKEGUN (duke parts)
Values for ifp
pstanding = Duke is standing pwalking = Duke is walking prunning = Duke is running pducking = Duke is ducking pfalling = Duke is falling pjumping = Duke is jumping phigher = Duke is higher than the current actor (?) pshrunk = Duke is has been shrunk pjetpack = Duke is flying with the jetpack ponsteroids = Duke is using his steroids ponground = Duke has his both feet on the ground palive = Duke hasn't died yet pdead = Duke has been killed pfacing = Duke is facing the current actor
Values for ifwasweapon
KNEE SHOTSPARK1 (Pistol, Chaingun, or Shotgun) RPG SHRINKSPARK FREEZEBLAST FIRELASER SPIT RADIUSEXPLOSION (All hitradii) COOLEXPLOSION1 FIREEXT GROWSPARK [Versions 1.4 and 1.5 Only]
Values for shoot
KNEE SHOTSPARK1 (The Pistol) SHOTGUN CHAINGUN RPG SHRINKER FREEZEBLAST FIRELASER SPIT BOUNCEMINE MORTER COOLEXPLOSION1 BLOODSPLAT1 BLOODSPLAT2 BLOODSPLAT3 BLOODSPLAT4 GROWSPARK [Versions 1.4 and 1.5 Only]
Values for spritepal
The following is a listing of all the legal values for the spritepal primitive. Palettes can effect 3 different 'layers' of a tile. The easiest way to understand these 3 different 'layers' is by using the stripper sprite. The 3 'layers' are: Background (her skin), Foreground (her clothes), and Minor Foreground (money, accessories, etc).
0 = Normal 1 = All colors become blue 2 = All colors become red 3 = Normal, exactly 0. Is used to actor some effects that needs a pallete that is not 0 (like parallex, that shots doesn't dissapers on it if using a pallete) 4 = All colors become a single black (#000) 5 = Red become brown. 6 = All colors become green with inverted brightness (Night Vision green) 7 = All colors become yellow 8 = All colors become green 10 = All blue become dark red 11 = All blue become green (same as 22, 22 is used by Assault Trooper) 12 = All blue become gray (same as 18) 13 = All blue become dark gray 14 = All blue become dark green (used by Nuke Button) 15 = All blue become brown 16 = All blue become dark blue 17 = All brown become blue and all blue becomes green 18 = All blue become gray (same as 12) 19 = All brown become red and all blue becomes gray 20 = All brown become blue and all blue becomes gray 21 = All Blue become red (used by Assault Captain and mini Battlelord) 22 = All blue become green (this is used by Assault Trooper, same as 11) 23 = All blue become yellow 24 = All gray become red and all red become gray 25 = All green become red
Legal Direction Values
- faceplayer: Actor faces the player's current position.
- geth: Actor travels in a horizontal direction.
- getv: Actor travels in a vertical direction.
- randomangle: Actor will change to a random angle when it touches a wall or when the actor is currently being shot at by the player. This direction value can be used with the move command to change the direction of any actor. To do this, use the following in your actor code: move 0 randomangle
- faceplayerslow: Actor faces the player's current position but slower than the regular faceplayer command.
- spin: The actor's angle changes in a clockwise fashion (i.e. - the actor spins clockwise).
- faceplayersmart: The actor will face slightly ahead of the player's current position, making it possible for monsters to "lead" you a little bit.
- fleeenemy: Actor faces directly away from the player.
- jumptoplayer: Actor attempts to jump.
- seekplayer: Actor tries to find and move to the nearest player.
- furthestdir: Actor faces the furthest distance from the closest player.
- dodgebullet: Actor attempts to avoid all shots directed at him.
EXAMPLES
Example 1: Increase Duke Nukem's Health
Difficulty Level: Easy
To start out on the CON editing path, let's do something extremely easy. We are going to increase Duke Nukem's maximum health from 100 to 200. We also need to increase his Atomic Health (we'll take it to 400) so that picking up Atomic Health actually does something!
First, open up the user.con file, and scroll down until you see the following line:
define MAXPLAYERHEALTH 100
Now change that number, so that the line looks like this:
define MAXPLAYERHEALTH 200
Now look for the line that looks like this:
define MAXPLAYERATOMICHEALTH 200
And change it to this:
define MAXPLAYERATOMICHEALTH 400
Now you are finished! Easy huh? Well, we'll now move on to something a little more difficult.
Example 2: Rubber Trash Cans Spawn Health When Destroyed
Difficulty Level: Easy
In this example, we will make the rubber trash can spawn health, but only 50% of the time, when it is destroyed by an explosion.
Open the game.con file and scroll down to these lines of code:
actor RUBBERCAN WEAK ifaction RUBCANDENT { ifactioncount 16 { strength 0 action RUBCAN break } } else ifhitweapon { ifwasweapon RADIUSEXPLOSION { state rats ifrnd 48 spawn BURNING debris SCRAP3 12 killit } else action RUBCANDENT } enda
We need to add the following lines to the code in order to make the health spawn 50% of the time (instead of the rats).
ifrnd 128 // 50% of the time... { spawn COLA // ... spawn the +10% health ... killit // ... then delete the trashcan from the map. } else (Here we put the rest of the code)
But where do we put this set of code? Well, we first have to find where the code checks to see if the trash can has been hit by an explosion. You see that line that says ifwasweapon? That line of code checks to see if the trashcan was hit by the weapon stated there; the RADIUSEXPLOSION. So we need to place the weapon right in that section of code. The finished product will look like this:
actor RUBBERCAN WEAK ifaction RUBCANDENT { ifactioncount 16 { strength 0 action RUBCAN break } } else ifhitweapon { ifwasweapon RADIUSEXPLOSION { ifrnd 128 { spawn COLA killit } else { state rats ifrnd 128 // See note #1. spawn BURNING debris SCRAP3 12 killit } } else action RUBCANDENT } enda
NOTE #1: Notice that we changed the ifrnd statement from 48 to 128. Why did we do that? Well, when you stack ifrnd statements up like they are, the chances of something happening are very small. For example:
ifrnd 128 ifrnd 128
This statement tells the sub-code to happen only 25% of the time. How did I get that number? Well, the value of 256 is 100%, so the value of 128 is 50%. Then 50% of 50% is 25%. If it sounds confusing, just work through it again and you should pick it up.
Example 3: Booby-trapped Ammunition
Difficulty Level: Intermediate
In this example, we will make chaingun ammo turn deadly - but only for 25% of the time.
Let's take a look at the chaingun ammo code, which can be found in the GAME.CON file:
actor BATTERYAMMO fall ifmove RESPAWN_ACTOR_FLAG state respawnit else ifp pshrunk { } else ifp palive ifpdistl RETRIEVEDISTANCE ifcount 6 ifcanseetarget { addammo CHAINGUN_WEAPON CHAINGUNAMMOAMOUNT quote 63 ifspawnedby BATTERYAMMO state getcode else state quikget } enda
You see all those if statements there under the second else? That is the area that we want to add our code to. We need to add the following lines to the code, so that 25% of the time, the chaingun ammo explodes.
ifrnd 64 // 25% of the time, the following code should be executed. { hitradius 1024 WEAKEST WEAK MEDIUMSTRENGTH TOUGH // define the damage spawn EXPLOSION2 debris SCRAP2 2 sound PIPEBOMB_EXPLODE killit } else // in other cases, add the ammo amount to the player. { addammo CHAINGUN_WEAPON CHAINGUNAMMOAMOUNT quote 63 ifspawnedby BATTERYAMMO state getcode else state quikget }
So let's add our code to the ammunition. This is what the final product will look like:
actor BATTERYAMMO fall ifmove RESPAWN_ACTOR_FLAG state respawnit else ifp pshrunk { } else ifp palive ifpdistl RETRIEVEDISTANCE ifcount 6 ifcanseetarget ifrnd 64 { hitradius 1024 WEAKEST WEAK MEDIUMSTRENGTH TOUGH spawn EXPLOSION2 debris SCRAP2 2 sound PIPEBOMB_EXPLODE killit } else { addammo CHAINGUN_WEAPON CHAINGUNAMMOAMOUNT quote 63 ifspawnedby BATTERYAMMO state getcode else state quikget } enda
Now, when you go into the game, every 25% (or roughly) of the time you should get hurt by an explosion. Cool way to make booby-traps, huh?
Example 4: Break the "Unbreakable" Plate (Versions 1.4/1.5 Only)
Difficulty Level: Intermediate
If you have ever played through Duke Nukem, you should hopefully have noticed the "unbreakable" plate in the sushi bar (episode 3, level 1). There is one plate the 3D Realms forgot about coding, and so it cannot be broken like the others can. What better a mistake for us to fix!
This coding session will only work with versions 1.4 or 1.5 of Duke Nukem 3D, because we will need to make use of the "useractor" function.
The plate that is in question is in slot #851 (you can take a look at it in Build or Editart). To make this slot an actor, we first need to define it in the defs.con file. Open up the defs.con file, and place the following line somewhere in this file:
define SUSHIPLATE99 851
I prefer putting these types of lines in order of appearance by tile number, much like 3D Realms did. Scroll down to the lines that say:
define MASKWALL13 830 define HURTRAIL 859
and put our define statement between the two lines that are there (because 851 is between 830 and 859).
Now save your work and close this file.
Now open the game.con file and place the following lines of code anywhere in the file:
useractor notenemy SUSHIPLATE99 WEAK // define it as a useractor ifhitweapon { lotsofglass 7 sound GLASS_BREAKING killit } enda
Now, when you enter into the game, you can shoot the plate and it will break! Yay! We just fixed a bug in Duke Nukem 3D!
Example 5: Make Duke eat some food (Versions 1.4/1.5 only)
Difficulty Level: Intermediate
In this example, we are going to make use of the food that appears in a few of the levels in Episode 4 (Versions 1.4 and 1.5 only). We will make Duke eat the food when he is near enough to it, and we will add 10 health points to his health when he eats it. We also will make him say "Ooh, I needed that!" when his health is below 20.
First, open up the user.con file, and scroll down to the line that says:
definequote 124 MAP HAS A DIFFERENT NUMBER OF PLAYERS
This is the last quote defined by 3D Realms, so we will make 2 new quotes to print. Add these lines right below the definequote 124:
definequote 125 YOU EAT SOME FOOD: +10 HEALTH! definequote 126 YOU AREN'T HUNGRY NOW...
We will use these quotes when we add code to the game.con file. Save your work and close user.con.
First we need to make a state function. Open the game.con file and put the following lines of code at the top of the file:
state eatfood ifp pfacing ifpdistl 1280 ifhitspace { ifphealthl 20 { addphealth 10 globalsound DUKE_NEED quote 125 killit } else { ifphealthl MAXPLAYERHEALTH { addphealth 10 quote 125 globalsound DUKE_GET killit } else { quote 126 break } } } ends
Now we need to find where the actors are located. Scroll down to the line that says:
useractor notenemy FOODOBJECT11 WEAK state breakobject enda
and change it to look like this:
useractor notenemy FOODOBJECT11 WEAK state breakobject state eatfood enda
This now allows our state function to work on FOODOBJECT11. But we want to change 12 through 20 as well. So just make each useractor that we want to change look just like the useractor above. Example:
useractor notenemy FOODOBJECT12 WEAK // We change # 12 now... state breakobject state eatfood enda
Save your work, and when you go into the game, you will find that you can now press space near the food and you will gain 10 health points if you are below 100!
FAQ INFORMATION
About the Authors and General Information
This FAQ was written by Joris Weimar, an avid Duke Nukem 3D FAQ, and a talented con file programmer. Also working on this FAQ is myself, Jonah Bishop. I also run the Map Editing FAQ for Duke Nukem 3D and Shadow Warrior. If you have any questions, tips, corrections or comments about con files or this FAQ, visit the Duke Nukem 3D Editing and Hacking forum at Dukeworld.
Dukeworld --- http://www.dukeworld.com
Credits and Contributors
This FAQ would not be what it is today without the following people (who made suggestions and pointed out various errors):
- James Tan (ctan@xtra.co.nz)
Provided most of the new and updated information for version 4.2.
- TerminX
For providing the updated information on the "endofgame" primitive
- The Reaper (lrdmecha@yahoo.com)
For clearing up all of the version validity problems with the predefined state functions.
- Snowblind (snowblind@brasnet.org)
For letting me know about the missing palette values
- Garry Cobbum (gcobbum@sbinet.com)
For finding several errors and for giving several suggestions
- James Ferry (sweepy@playful.com)
For the tons of information he allowed me to use. Visit his site at http://members.xoom.com/HCAD
- Joe Barta (jbarta@apk.net)
For finding more errors than can be named
- Matthew Hill (gambit@proteus.globalnet.co.uk)
For donating the correct "palfrom" primitive parameters
- Gavin Lambert (uecasm@geocities.com)
For finding an error in the "mikesnd" primitive and for clearing up the usage of the "ifinouterspace" primitive
- Reptile (reptile@worldaccess.nl)
- Linkers (linkers@dds.nl)