INDEX/TABLE OF CONTENTS: A. What are .CON files? B. Can I alter .CON files? C. How do I alter .CON files? * What is all this strange C-programming
language-like junk? ***** DEFS.CON: define ***** USER.CON: definequote, definelevelname,
music, definesound ***** GAME.CON: comments, include, primitives - Listing of primitives +
their uses (if known) D. Examples * Trampoline trash cans * Hollow-point
pistol bullets (Unfinished) * Kamikaze enemies (Unfinished) E. So now what?
A. What are Duke Nukem 3D .CON files?
.CON files are text files that "CON"trol certain aspects of the DOOM- like game
Duke Nukem 3D (DN3D). There are three of them that come with the Shareware version of
DN3D: DEFS.CON, USER.CON, and GAME.CON. (The full version of DN3D is has not been released
as of the writing of this document, and so I can't say anything about it.) When DN3D
starts up, it loads GAME.CON, checks it for errors, and if there are none keeps the
instructions contained in it for use later on in the game. (GAME.CON is in charge of
loading up any supplemental files, like DEFS.CON and USER.CON, that it may want to use)
The instructions currently known to be usable in GAME.CON control things as mundane as how
much damage each kind of weapon does to things as exotic as how enemies behave.
B. Can I alter .CON files?
Yes, you most certanly can. This is one of the nicer features of the Build engine, or at
least Duke3D's implementation of the Build Engine. But, before you start playing with
them, you should definitly MAKE A BACKUP OF ALL YOUR .CON FILES!!!!! This is not only to
prevent you from having to re-install DN3D if you mess up your existing .CON files, but
also so that you can have the original .CON files as reference material when you start
altering them. Once you've got backups made, altering the .CON files couldn't be easier:
just open them up with your favorite text editor and edit away.
C. How do I alter .CON files?
* What does all this weird, C-like junk in my .CON files mean?? A lot of things,
depending on which .CON file you edited. Let's take the .CON files from least complex to
most complex: ***** DEFS.CON: Most of the lines in DEFS.CON look something like:
define SOMETHING SOMENUMBER What they do is basically simple substitution: If you have a
line somewhere in your DEFS.CON that said: define THEANSWER 42 Then any time after that,
if the word "THEANSWER" appears, "42" is substituted in it's place. By
themselves, these lines aren't very interesting. They become helpful later on, when you're
writing actor code and don't want to remember that an enemy who is TOUGH happens to have a
strength of 137. You can just: define TOUGH 137 And thereafter don't have to remember that
TOUGH = 137, you just know that an enemy is TOUGH. Defines are ubiquitous; almost
everything in the .CON files is really a number, but is DEFINEd to be a name so it makes
more sense. At some point you can just stop caring whether things are DEFINEd labels or
numbers, but be aware that most of the things you deal with are really numbers. *****
USER.CON: USER.CON is somewhat like DEFS.CON in that it mostly just defines things.
However, USER.CON usually defines things that might be interesting to the game player,
whereas DEFS.CON usually defines things that a DN3D player could care less about. USER.CON
also contains nice technical notes written by the 3D Realms .CON programmer, Tod Replogle,
that tell you all about how to modify it. Almost all of the info below is basically a
rehash of the notes you can find in USER.CON There are 5 major kinds of lines in USER.CON:
defines, definequotes, definelevelnames, musics and definesounds. "define" lines
are no different than they were in DEFS.CON; they define stuff. Most of the stuff you can
define here is emminantly useful, tho. Examples abound: You can define Duke's starting and
maximum health and armor values here. You can define how much ammo Duke gets per clip
picked up, how much ammo is allowed for each weapon, how much damage each weapon does per
hit, etc, etc... "definequote" lines define the different things that will pop
up on the screen in response to certain game events. You can define what words appear on
the screen when you get an some ammo or an inventory item, what words appear on the screen
when you use the various cheat codes, what words will appear when you adjust game options,
etc, etc... "definequote" lines have two arguments: a number and a quote. The
number is what you use to refer to the quote by later on. For example, the line:
definequote 101 NIGHT VISION GOGGLES! Defines quote number 101 is "NIGHT VISION
GOGGLES!" (This is pretty obvious, isn't it?) One other thing to keep in mind while
making quotes; Todd Replogle, the Duke3D .CON file programmer, cautions: >// Maximum
quote size is 64 characters. "definelevelname" lines are used to define the
episode and level number, floor-plan file, par and record times, and level names for each
level. The format of a definelevelname line is: definelevelname #LEVEL #EPSIODE MAPFILE
PARTIME RECORDTIME LEVELNAME For example, Episode 1, Level 5 is "The Abyss." The
floor-plan of this level is in the file E1L5.map. (which is actually contained in
DUKE3D.GRP) The par time is 9 minutes, 10 seconds, and the record time is 5 minutes flat.
It's definelevelname entry looks like this: definelevelname 0 4 E1L5.map 09:10 05:00 THE
ABYSS As you can see, you must subtract one from the actual episode and level numbers
before you put them on the definelevelname line. We're in Episode 1, but the #EPISODE is
0. We're in level 5, but the #LEVEL is 4. Notice also that you should (I don't think it's
actually required) pad the par and record times with a leading 0 if necessary. There are
also some comments from Todd Replogle, taken from USER.CON: > - Level file names cannot
excede 13 characters. > - Level par cannot excede 5 characters (min:sec) > - Level
titles cannot excede 32 characters. "music" lines (as far as I can tell) define
which .MID files to play for each level. Beyond that I'm not entirely sure how
"music" lines specify exactally which file to play for which level; if someone
can enlighten me I'd be appreciative. "definesound" lines define various names
that correspond to ways to play a VOC file. The format of a definesound line is:
definesound SOUNDNAME VOCFILENAME.voc #1 #2 #3 #4 #5 Once again, Todd Replogle has
provided .CON file hackers with a helpful technical note in USER.CON: >
----------------------------------------------------------------- > ABOUT CHANGING
SOUND FX > The sound fx section follows this explanation. > > 1. The program
expects to find a .VOC file > 2. You can either change the VOC name listed below to
match your new > sound, or you can rename your file to match the name here. > 3. New
sound files should be added to the game directory. Though > all sound files shipped
with the game are included inside the > .GRP file, the program will know if there are
sound files outside > the .GRP file, and will use them instead. > 4. The numbers
that are to the right of the sound file name are > technical parameters which will not
be explained here, except as > follows... > - The first 2 numbers define a random
pitch variation range. > They can be positive or negative numbers. > - The 3rd
number is a priority flag. > - The 4th number is a bit parsed set of technical
variables > that identify the type of sound it is in the game. > - The 5th number is
a volume adjustment flag. >
----------------------------------------------------------------- The explanation seems
pretty self-evident, so I won't go into a detailed explanation of each field of the
definesound line. ***** GAME.CON: The BIGGIE! Lots of stuff in this one, and most
of it rather difficult to explain... let's start out with the first couple of lines, which
are: /* ------------------------------------------------------------------- Duke Nukem 3D
Script Code. Todd Replogle.
------------------------------------------------------------------- */ If you're a C
programmer, this stuff is immediatly obvious: everything between /* and */ is considered a
"comment" and Duke3D will almost always ignore it when reading in GAME.CON. (I
say "almost always" because it appears that Duke still counts the curly braces,
{ and }, inside comments. This can lead to some interesting effects; comment out some bad
code that has non- matching curly braces and the game might refuse to load up, even though
the bad code is inside a comment, and supposedly never even seen.) There are two kinds of
comments: the double-slash or "//" comment and the "/* */" comment. A
"//" comment starts at the double-slash and extends to the end of the line. A
"//" comment ends at the end of the line. The "/* */" comment can span
several lines, but "//" comments only "null out" one line, at most.
Many // and /* */ comments can be found all over DEFS.CON, USER.CON, and GAME.CON.
Forewarned: you must put a space after "//" before typing the text of the
comment. The comment: "//This is a comment" will cause Duke3D to error out.
Changing the comment to "// This is a comment" will fix the problem. I assume
the same holds for "/* */" comments. Things like: "/*C*/" are a no-no.
Things like "/* C */" are OK. The next few lines in GAME.CON are
"include" lines which basically cause Duke3D to process the specified file. The
line: include defs.con Makes DN3D go process DEFS.CON before it moves along to the next
line. And now, the really big, confusing ones: states, actions, and actors. Apogee hasn't
said anything about states, actions, or actors yet, so the things I'm about to tell you
are pure conjecture based on observation and experimentation: *****STATEs As far as I can
tell, "states" can be thought of as something like subroutines. You go into a
state, do something, and then come back to wherever you were. The first state in GAME.CON
is the "rats" state, which randomly makes some rats whenever it's called. The
format of a state is: state #STATENAME ... ends STATENAME is a unique number that is
usually DEFINEd to be the name of the state. No two states should have the same number.
"ends," of course, is short for "End State." Be sure that your states
are defined before you try and use them. If you try and use a state (in an actor, perhaps)
that hasn't been defined earlier in the file, DN3D will error. *****ACTIONs As far as I
can tell, an "action" specifies a sequence of sprites (pictures) to draw onto
the screen. The format of an action is still not quite entirely known, but it seems to be
something like this: action #SPRITEGROUP #FIRSTFRAME #LASTFRAME #?? #?? #DELAY Each action
has a set of pictures, or "frames" associated with it. The number first number,
#SPRITEGROUP, defines this bunch of picures, or a "sprite group." #SPRITEGROUP
is usually a DEFINEd number, so you can type "action BURNING_FRAMES" instead of
having to remember that the fire animation frames are number 327, and typing "action
327." The second and third numbers of an action specify which sequence of frames from
the specified sprite group group to step through when you're animating this sprite.
(Animation starts from the whatever-th frame in the sprite group, number #FIRST, and goes
until the whatever-th frame in the group, number #LAST. Then it usually loops back to the
first frame or else quits, depending on the actor code controlling it.) The #DELAY number
determines the delay between frame changes. That is, how rapidly the frames are animated
on-screen. 1 = small delay and fast animation, bigger numbers = bigger delays and slower
animation. (I think?) The two remaining numbers are a mystery. If anybody knows what they
mean and how they're used, please mail me at cantrick@rintintin.colorado.edu so I can add
them to the guide. *****ACTORs As far as I can tell, an "actor" is any
(freestanding?) object in the game that does something. Obviously, Duke and the enemies
are actors. However, the rubber-maid trash cans in the movie-theater lobby are also
actors, because they dent and then bounce back when you shoot them. The items and weapons
and clips are also actors, because they also do something when you run over them: they
give you an item, a weapon, or more ammo. Walls are not actors, because they don't 'do'
anything except sit there. (Bullet-holes being an exception, I guess. Perhaps the bullets
themseves are some kind of actor that effect the surface they hit.) Doors and lifts are
borderline; I suppose the game might treat them as actors internally, but I don't know if
you can/how you would alter their behavior in the .CON file. The format of an actor is
something like: actor #ACTORNUMBER #ACTORSTRENGTH #ACTION #SPEED #AI_FUNCTION ... enda
#ACTORNUMBER is (I think?) a unique number that identifies this actor. No two actors
should have the same number. Usually #ACTORNUMBER is DEFINEd to be something easier to
remember than a number. #ACTORSTRENGTH is a number that determines how much damage this
actor can take before it breaks, dies, etc... (I think?) Putting a value of 0 for this
field makes the object invincible. Usually, #ACTORSTRENGTH is DEFINEd to be something easy
to remember. (See 'define TOUGH' above.) #ACTION is (I think?) the number of an action
(that is, the identifying number of a series of frames) to cycle through for this actor,
if this actor is animated. Patches of fire actors use this to maintian an image- loop so
they look like they're constantly burning. The HoloDuke recharge also uses an action to
make the shimmer propagate across it's surface. #SPEED is (I think?) how fast this actor
moves, if it moves. I don't know if "move" is always interpreted in the
traditional sense; it appears from the gun-turret actor code that turrets that spin in
place are considered to be "moving." #AI_FUNCTION is (I think?) a number, as
defined in DEFS.CON, that specifies what this actor's initial AI is if it has an initial
AI. The AI routines are: face_player (1), geth (2), getv (4), random_angle (8),
face_player_smart (64), fleeenemy (128), seekplayer (512), fleeplayer (1024), looking
(2048) and dodgebullet (4096). As to what these mean or how they work, I haven't any idea.
The last three parameters of actor seem to be optional. Things that aren't animated, don't
"move" and have no AI don't seem to include those parameters. You can make a
perfectly sensible actor without them; as a matter of fact the majority of non-enemy
actors in Duke3D (ammo and items) do not use them at all. * You keep putting
"..." inside states and actors as if we already know what's supposed to go
inside there; but we don't! Well, this is kind of sticky; there are quite a few things
inside there, most of them vaguely reminiscent of the C programming language with a
virtual environment twist. The things that go inside actors and actually make up the actor
"code" are what I'll call "primitives." Primitives are simple
operations that the Build Engine will perform for you. For instance, one primitive is
"ifrnd" which will tell you if a random number between 0 and 256 was less than
the number you gave it. For instance, if you wanted there to be a 1 in 2 chance of
something happening, you could put: ifrnd 128 { ... // 50% chance that this stuff gets
done. } Since 128 is half of 256, the random number between 0 and 256 will be less than
128 about half the time. Thusly, the "..." inside that "ifrnd" block
will only be executed about half the times the ifrnd is run. To take another example: if
you wanted a 1/4 chance, you'd ifrnd 64 { ... }. Since a random number between 1 and 256
will be less than 64 about 25% of the time. There are a bunch of other primitives, too.
I'll list them each here, along with their arguments and what they do. After that, I'll
give some (hopefully) illustrative examples on how to use them. Note: Primitives marked
with a "?" instead of a "-" are still mysteries to me. As usual, mail
me (cantrick@rintintin.colorado.edu) if you know how they work or if I've forgotten any
primitives. Note: Most "add" primitives are subject to some kind of limit. These
limits are usually explained in the explanation of the primitive. Note: All (?) 'ifXXXXX'
primitives can have an (optional) else clause that gets executed if the condition being
tested is false. For instance: ifphealthl 45 { quote OK // Print "You're OK." }
else { quote BUMMER // Print "Find some health!" } *****PRIMITIVES: addammo
#WEAPON #AMT - Adds #AMT ammo to #WEAPON weapon, Subject to max ammo constraint for that
weapon. Does not give player #WEAPON, only gives them ammo. Ex: "addammo
PISTOL_WEAPON PISTOLAMMOAMOUNT" addinventory #ITEM #AMT - Adds #AMT of #ITEM to
player's inventory, subject to #ITEM's max amount limit. addkills #NUM - Adds #NUM to
number of kills player has made. addphealth #NUM - Adds #NUM points to player's health.
(#NUM may be negative.) addweapon #WEAPON #INITIALAMT - Gives player weapon #WEAPON that
has #INITIALAMT of ammo in it. Ex: "addweapon SHOTGUN_WEAPON 10" ai AINAME
#ACTION #SPEED #AITYPE ? Defines an AI routine for enemies to use. AINAME is any string,
#ACTION is the series of frames to cycle through when the enemy is using this AI, #SPEED
is how fast the enemy moves when using this AI and #AITYPE is what the enemy does when
it's using this AI. (For a list of AITYPEs, see #AI_FUNCTION under ACTORs.) break - Stops
whatever you're doing and immediatly exits the currently running actor or state. cactor
#ACTORNUM ? As far as I can tell, this primitive "c"alls another
"actor" to do something for you. cstat #NUM ? Allows setting of the attribute
bit(s) of the current actor. #NUM is the sum of the attributes you want this object to
have. The values of the attributes are as follows: 1 - ? 2 - Translucent (With black as
the transparent color?) 4 - Moving? 8 - Upside-Down 16 - Background (If looked at from
above, this object will appear blended in with the background. Viewed any other way, it
will look normal.) 32 - Floor Texture (Draws object as a flat square on the ground) 64 - ?
128 - Half submerged (Maybe for floating things?) 256 - Solid. (You can shoot it, you can
stand on it, etc...) 32768 - Invisible. Ex. "cstat 10 // Turn upside-down and
translucent. (10 = 8 + 2)" debris #??? #AMT - Causes some debris to fly. (Whose
action or spritegroup is defined by #??? ?). Larger values of #AMT make more junk fly.
Acceptable values of #??? seem to be "SCRAP1" and "SCRAP2." Ex.
"debris SCRAP2 5 // Lots!" define - Defines various things. See other
definesound sections of document. definelevelname fall - Causes the current actor to
"fall" until it hits a surface it can come to rest on. Good to do right after
you "spawn" something small from inside something larger. globalsound #SOUND ?
Plays the sound associated with #SOUND at (which?) Duke's location. guts #??? #AMT - Like
debris, but causes different kinds of body parts to fly instead of debris. Acceptable
values for #??? seem to be JIBS1 to JIBS5 (Misc body parts) as well as HEADJIB1, LEGJIB1,
ARMJIB1 (Trooper parts), LIZMANARM1 and LIZMANLEG1 (Captain). Also DUKETORSO, DUKELEG and
DUKEGUN. Ex. "guts JIBS1 1 // A spine." hitradius #RADIUS #1 #2 #3 #4 ? Defines
the effective distance and strenghts of area-effectors like explosions and fires. #RADIUS
determines the circle of maximum effect, (I think?) within which damage done to objects is
given by #4.(?) Objects farther away (how much farther?) from the center of effect suffer
damages of #3, objects farther than that sustain damage #2, objects farther yet take
damage equal to #1, and objects sufficiently far away from the area-effector suffer no
damage at all. Ex: "hitradius 1024 WEAKEST WEAK MEDIUMSTRENGTH TOUGH" ifactor
#NUM ? Tells you if the currently executing code was called by the given actor?
ifactornotstayput ? ifaction #ACTION { ... } - Tests if the current actor is executing the
given action, and executes the appropriate code. ifactioncount #NUM { ... } - Tests if the
current actor is displaying the given frame of an action, and exectes the appropriate
code. ifbulletnear ? Checks to see if a bullet has passed near the current actor? ifcansee
- Returns true if Duke can see the current actor. ifcanseetarget ? Enemy AI routine?
ifcanshoottarget ? Enemy AI routine? ifceilingdistg #NUM - Returns true if the distance to
ifceilingdistl #NUM the ceiling is greater/less than the given number. ifcount ? Like
ifactioncount, but counts the number of frames total that have been used since the last
call to ifcount? ifdead - True if the current actor has taken as much damage as they can
given their strength and should be pushing up daisies. iffloordistg #NUM - True if the
distance from the iffloordistl #NUM current actor to the floor is greater/less than #NUM.
ifgapzl #NUM ? True if the distance between the floor and the ceiling at the actor's
location is less than #NUM. ifhitweapon ? True if the current actor was hit with a weapon
recently. (How recently? Since the last call to ifhitweapon?) ifinwater - True if the
current actor is ifonwater in/on water. ifmove #NUM ? True if the value of variable #NUM
is not false? ifnotmoving ? True if the current actor is not moving? ifp #COND ? True if a
player (the last one that affected this actor?) satisfies #COND, when #COND can be one of
the defined (in DEFS.CON) numbers: pstanding, pwalking, prunning, pducking, pfalling,
pjumping, phigher, pwalkingback, prunningback, pkicking, pshrunk, pjetpack, ponsteroids,
ponground, palive, pdead, pfacing. ifpdistg #NUM ? True if a(?) player's distance ifpdistl
#NUM from the current actor is greater/ less than #NUM. ifphealthg #NUM ? True if (which?)
player's health ifphealthl #NUM is greater/less than #NUM. ifpinventory #ITEM #AMT ? True
if less than #AMT of #ITEM is in (which?) player's inventory. ifrespawn - True if monsters
should respawn. ifrnd #NUM - True if #NUM is less than a randomly selected number between
0 and 256. Ex. "ifrnd 128 {...} // 50% chance." ifhitspace ? True if a(?) player
hit space. ifplayersg #NUM ? True if (which?) player has ifplayersl #NUM greater/less than
#NUM Dukes left. ifspawnedby #ACTOR - True if the current actor was SPAWNed by the given
type of actor. ifspritepal #NUM ? True if the current actor's sprite palette is #NUM. (See
spritepal for a listing of palette numbers and their meanings.) ifsquished ? True if the
current actor was hit by the shrink ray and then stepped on. Ex. "ifsquished sound
SPLURT // Yummy!" ifwasweapon #WEAPON ? True if the current actor was recently(how
recently?) hit by a shot from weapon corresponding to #WEAPON. killit - Removes the
current actor from the map. Seems to need to be the last instruction executed in an actor.
In particular, don't try to SPAWN after this. money #NUM - Spawns #NUM dollar bills. move
#??? [#1 #2 #3 ... ] ? Sets the value of #??? to #1, and #2, and #3,(?) or if they are not
specified, to 0? operate ? Causes the current actor to push the 'operate' button thus
triggering a door, elevator or the like(?) palfrom #1 #2 #3 ? Rotates the palette from #1
to #2 (and then back?), where #1 and 2 may be bitflags (aka 1, 2, 4, 8, etc...) where 16
specifies red and 0 or 32 specifies green(?). #3 is a "delay" parameter that
controls how quickly the pallete change happens; larger values = slower changes.(?) Ex.
palfrom 16 16 // Screenflash red. pstomp ? Causes the player (which player?) to look down,
and stomp the current actor(?) Ex. "ifshrunk ifpdistl RETRIEVEDIST { pstomp killit
}" quote #NUM - Prints quote #NUM out on the screen in the usual fashion.
resetactioncount ? Resets the counter that counts the number of frames that have been
displayed by the action that the current actor is executing? resetcount ? Resets the
global count of number of frames displayed by this actor since the last call to resetcount
of ifcount(?) shadeto #NUM ? ??? shoot #WEAPON ? Makes an enemy fire it's weapon. (Seems
to be used to trigger blood- splattering, too) sizeto #1 #2 ? Scales the sprites
associated with the current actor to 1/#1 (?) in the X direction and 1/#2 in the Y
direction. sound #SOUND - Plays the sound associated with #SOUND by definesound at the
current actor's location. soundonce #SOUND ? ??? spawn #ACTOR - Spawns a copy of #ACTOR.
spritepal #NUM ? Changes the color of the current actor. Each value of #NUM corresponds to
a different color scheme, some(?) of which are: 1 - bright blue 4 - dark 6 - Night vision
green 7 - "messed up yellow" 8 - green 10 - somewhat red 19 - very reddish 22 -
Almost normal. wackplayer - Boot... TO THE HEAD!
D. Examples *
Trampoline Trash Cans I love those grey and red rubber-maid trash cans in the movie
theater lobby in level 1. They're simple and static, so they're fun to play with. Let's
make it so that when a player shoots one, it dents, and if they're stand too
"close" when the trash can bounces back, the trash can will hit them and jar
their viewpoint for a second. First of all, we have to understand the trash can actor
code: action RUBCANDENT 1 1 1 1 1 action RUBCAN actor RUBBERCAN WEAK ifaction RUBCANDENT {
ifactioncount 16 { strength 0 action RUBCAN break } } else ifhitweapon { ... } enda Well,
first of all, we don't care about what will happen to the trash can if it's hit with a
weapon, so forget about the 'else ifhitweapon' part except to keep in mind that it takes
care of denting the trash can for us. (Which is really just a call to 'action RUBCANDENT')
Now then, before we start modifying things, try and think of what's happening from the
trash can's perspective. This is Zen and the art of Duke3D: you must "become
one" with your actor code. ;] Thinking this way, the important stuff in this actor
could be paraphrased in english as: "if I'm dented, and if I've been dented for a
while, pop back." We'd like to modify that to: "if I'm dented, and if I've been
dented for a while, pop back. And if the player's "close," then bump them."
So how do we tell if the player's close? We can use the "ifpdistl" primitive to
tell if the player is less than a certain distance away. Now, how close is
"close?" Apogee (in DEFS.CON) defined a certain distance to be close enough to
retrieve an item. This is a good estimate of "close." Apogee called this
distance RETRIEVEDISTANCE. How do we "bump" the player? Why, we
"wackplayer," of course. ;] Okay, the code is shaping up. We have to modify the
actor right in the part where the trash can bounces back. That's the stuff inside the
'ifactioncount 16 { ... }' Okay, so we go in there. What do we want? Well, IF player_close
{ bump_player }, right? So: actor RUBBERCAN WEAK ifaction RUBCANDENT { ifactioncount 16 {
strength 0 action RUBCAN /* We added these three lines below: */ ifpdistl RETRIEVEDISTANCE
{ // If player's close... wackplayer // Boot... TO THE HEAD! } break } } ... enda *
Hollow-point bullets. * Kamikaze enemies.
E. So now what? Now go
start playing with the .CON files. The worst that can happen is that DN3D will refuse to
run because you made a mistake. (Forgot a brace, or something) If so, you'll have to
correct the mistake or restore from your backup .CON file(s). (You DID make a backup,
didn't you? Of course you did.) Please do not email the author with questions; he probably
doesn't know. Even if he does, he won't help you. If he starts answering requests, where
will it all stop? ("How do I make the sound that Duke makes when he's ducking in the
ooze sound like a fart and have bubbles float around and etc, etc...?") Also please
don't e-mail Apogee or 3D Realms with questions; they have specifically disavowed all
responsibility if you mess with the .CON files. Instead, do what comes naturally: play
around until you figure out the answer.
|