thingtype w00t { mass = 1000 }
thingtype w00t
{
mass = 1000;
}
thingtype
w00t
{
mass =
1000 ;;;;;;
}
Obviously, you are encouraged to use a clean and consistent format, even though
it is not required.
# Single line comment
// Another single line comment
/*
This is a multiline comment
*/
spritenames += { SPR1, SPR2, SPR3 }
The items SPR1, SPR2, and SPR3 are unquoted strings. Note how the commas serve to
separate the items in a list, and therefore do not become part of the strings.
thingtype w00t
{
obituary_normal = "w00ts"
obituary_melee = 'says \'w00t\''
}
Line Continuation:
frame S_MYFRAME
{
cmp = "TROO|A|*|6 \
TroopAttack|@next"
}
The "\" character, when followed immediately by a line break, signifies that line
continuation should be triggered. Whitespace before the line continuation will be
included in the string, but any spaces or tabs at the beginning of the next line will
NOT be included (this is the same as line continuation in BEX files). This allows the
following continued parts of the string to be arbitrarily indented for purposes of
beautification. A string can be split across any number of lines in this fashion.
# this is a normal, decimal number (base 10)
spriteframe = 16
...
# this is an octal number (base 8)
spriteframe = 020
...
# this is a hexadecimal number (base 16)
spriteframe = 0x10
Floating-point numbers must have a decimal point in them, as in "20.0". Floating-point
numbers are always base 10.
Files
Why Not in Wads?
Eternity cannot currently load EDF from wad lumps, although actions have been taken to
enable this in the near future.
In the meanwhile, Eternity offers several ways to make loading of EDF from files a gentler
process. These are addressed in the "Specifying the Root EDF File" section below.
Return to Table of Contents
Specifying the Root EDF File
Eternity supports several methods for locating the root EDF file, which is the only EDF file
loaded directly for parsing.
Including Files
Use of include files is critical for several purposes. First, it's unorganized and difficult
to maintain EDF files when everything is put haphazardly into one file. Second, through use
of the stdinclude function, user-provided EDF files can include the standard defaults,
without need to duplicate the data in them. This helps keep EDF files compatible with future
versions of the Eternity Engine, besides making your files much smaller.
To include a file normally, with a path relative to the current file doing the inclusion,
use the include function, like in these examples:
# include examples
include("myfile.edf")
include("../prevdir.edf"); # remember, semicolons are purely optional
This example would include "myfile.edf" from the same directory that the current file is
in, and "prevdir.edf" from the parent directory.
stdinclude("things.edf")
This would include "things.edf" in the Eternity Engine's folder.
spritenames =
{
include("sprnames.txt")
}
Note that for maximum compatibility, you should limit EDF file names to MS-DOS 8.3 format
and use only alphanumeric characters (ie, no spaces). This is not required for Windows or
Linux, but the DOS port of Eternity cannot use long file names.
Including BEX Files
As of Eternity Engine v3.31 public beta 5, EDF now supports including DeHackEd/BEX files.
Any DeHackEd/BEX files included will be queued in the order they are included, after any
other DeHackEd/BEX files to be processed. DeHackEd/BEX processing occurs immediately
after EDF processing is complete. This allows better cohesion between the EDF and BEX
languages, and also allows the user to specify fewer command line parameters or to avoid
the need for a GFS file in some cases.
To include a DeHackEd/BEX file for queueing from EDF, use the bexinclude function,
like in this example:
bexinclude("strings.bex")
The DeHackEd/BEX file will be included relative to the path of the including EDF file.
There is no stdinclude equivalent for DeHackEd/BEX files, since the engine does not
provide any default BEX files.
Default EDF Files
This section explains the contents of each of the standard default EDF modules as of
Eternity Engine v3.31 public beta 4.
Default Fallbacks
As a failsafe to allow old EDF modifications to continue working, EDF is now capable of
loading default modules individually when it determines there are zero definitions of certain
sections. The following modules will be loaded as fallbacks when the given conditions are met:
Verbose EDF Logging
Eternity includes a verbose logging feature in the EDF processor that allows a view of
more detailed information on what is occuring while EDF is being processed. This can help
nail down the location of any errors or omissions. To enable verbose EDF logging, use the
command-line parameter -edfout. This will cause Eternity to write an "edfout.txt" file in
its current working directory.
Return to Table of Contents
Enable Functions
Starting with EDF 1.2, special functions are provided which allow the user to enable
or disable options within the EDF parser. The primary use for these functions is to
instruct the parser to skip definitions for game modes other than the one currently
being played. Although all the thing, frame, sound, and sprite definitions will not
conflict and can be loaded with each other, most of the time this is unnecessary and requires
a significant amount of memory which will never be used. Allowing such definitions
to be discarded during parsing speeds up processing and reduces memory usage. Note that
all of these functions are only valid at the topmost level of an EDF file, and not within
definitions.
Enable Functions
// this thing type is only available if HERETIC is enabled
ifenabled(HERETIC)
thingtype foo { spawnstate = S_FOO1 }
endif()
Note on command-line option "-edfenables":
The -edfenables command-line option allows the user to override the default behavior
explicitly and enable all gamemode's definitions without adding an EDF file. This does
not interfere with explicit usage of enable functions in user EDFs, but it does allow
older DeHackEd patches and WADs which might assume Heretic definitions are available in
DOOM or vice versa to work.
Sprite Names
Sprite names are defined as a list of string values which must be exactly four characters
long, and should contain only capital letters and numbers.
Syntax:
spritenames = { <string>, ... }
If this syntax is used more than once, the definition which occurs last during parsing will
take precedence as the original definition of the sprite name list. Values may either be
added by copying the entire list in a new EDF file and adding the new values anywhere in the
list, or by using the following syntax:
spritenames += { <string>, ... }
This syntax allows the addition of new sprite names to the list without requiring the
original list to be changed or copied.
# defining an original spritenames array (this would replace the default list)
# notice that sprite names never NEED to be quoted, but can be if so desired.
spritenames =
{
FOO1, FOO2, FOO3, TNT1, PLAY
}
# add a few values in later (maybe near a thing or frames that use them)...
spritenames += { "BLAH" }
Return to Table of Contents
Sprite-Related Variables
There are two sprite-related variables which may be specified in user EDF files:
playersprite = <sprite mnemonic> blanksprite = <sprite mnemonic>Full example:
# set the player skin sprite to BLAH playersprite = BLAH # set the blank sprite to FOO1 blanksprite = FOO1Return to Table of Contents
Sprite-Based Pickup Items
Sprite-based pickup item definitions allow one of a set of predefined pickup effects to be
associated with a sprite, so that collectable objects (with the SPECIAL flag set) using it
will have that effect on the collecting player.
It is currently only possible to associate one effect with a given sprite, but effects can
be assigned to as many sprites as is desired. If a sprite is assigned more than one pickup
effect, the one occuring last takes precedence. There are plans to extend this feature in
the future to include customizable pickup items, but for now only the predefined effects are
available.
Syntax:
pickupitem <sprite mnemonic> { effect = <effect name> }
sprite mnemonic must be a valid sprite mnemonic defined in the spritenames list.** Note: all ammo amounts double in "I'm Too Young To Die" and "Nightmare!" ** Note: weapons give 5 clips of ammo when "Weapons Stay" DM flag is on ** Note: dropped weapons give half normal ammo Effect Name Item is... Special effects ---------------------------------------------------------------------------- PFX_NONE No-op collectable None PFX_GREENARMOR Green armor jacket +100% armor PFX_BLUEARMOR Blue armor jacket +200% armor PFX_POTION DOOM health potion +1% health PFX_ARMORBONUS Armor bonus +1% armor PFX_SOULSPHERE Soulsphere +100% health PFX_MEGASPHERE Megasphere 200% health/armor PFX_BLUEKEY DOOM Blue key card PFX_YELLOWKEY DOOM Yellow key card PFX_REDKEY DOOM Red key card PFX_BLUESKULL DOOM Blue skull key PFX_YELLOWSKULL DOOM Yellow skull key PFX_REDSKULL DOOM Red skull key PFX_STIMPACK Stimpack +10% health PFX_MEDIKIT Medikit +25% health PFX_INVULNSPHERE Invulnerability Sphere Temporary god mode PFX_BERZERKBOX Berzerk Box Super strength PFX_INVISISPHERE Invisibility Sphere Temporary partial invis. PFX_RADSUIT Radiation Suit No nukage damage PFX_ALLMAP Computer Map All of automap revealed PFX_LIGHTAMP Light Amp Visor All lights at full level PFX_CLIP Clip +10 Bullets PFX_CLIPBOX Clip box +50 Bullets PFX_ROCKET Rocket +1 Rocket PFX_ROCKETBOX Box of Rockets +10 Rockets PFX_CELL Cells +20 Cells PFX_CELLPACK Cell pack +100 Cells PFX_SHELL Shells +4 Shells PFX_SHELLBOX Box of Shells +20 Shells PFX_BACKPACK Backpack Max ammo *= 2, +1 clip all ammo PFX_BFG BFG BFG weapon, +2 clips cells PFX_CHAINGUN Chaingun Chaingun weapon, +2 clips bull. PFX_CHAINSAW Chainsaw Chainsaw weapon PFX_LAUNCHER Rocket launcher Rocket launcher weapon, +2 rock. PFX_PLASMA Plasma Gun Plasma gun weapon, +2 clips cells PFX_SHOTGUN Shotgun Shotgun weapon, +2 clips shells PFX_SSG Super Shotgun SSG weapon, +2 clips shells PFX_HGREENKEY Heretic Green key ** Gives both DOOM red keys PFX_HBLUEKEY Heretic Blue key ** Gives both DOOM blue keys PFX_HYELLOWKEY Heretic Yellow key ** Gives both DOOM yellow keys PFX_HPOTION Heretic Potion +10% health PFX_SILVERSHIELD Silver Shield +100% Heretic armor (stronger) PFX_ENCHANTEDSHIELD Enchanted Shield +200% Heretic armor (stronger) PFX_BAGOFHOLDING Bag of Holding No effect yet PFX_HMAP Map Scroll All of automap revealed PFX_TOTALINVIS Total InvisiSphere Temporary total invisibility -----------------------------------------------------------------------------Full example:
# define a couple of sprite-based pickups
pickupitem FOO2 { effect = PFX_TOTALINVIS }
pickupitem FOO3 { effect = PFX_LAUNCHER }
# redefine an existing pickup effect (don't forget free-form syntax...)
pickupitem FOO3
{
effect = PFX_ENCHANTEDSHIELD;
}
Return to Table of Contents
Frames
Frames, also known as states, define the animation and logic sequences for thing types and
player weapons.
Each frame must be given a unique mnemonic in its definition's header, and this is the name
used to identify the frame elsewhere. Each field in the frame definition is optional. If a
field is not provided, it takes on the default value indicated below the syntax
information. Fields may also be provided in any order.
If a frame's mnemonic is not unique, the latest definition of a frame with that mnemonic
replaces any earlier ones. As of EDF 1.1 (Eternity Engine v3.31 public beta 4), frame
mnemonics are completely case-insensitive. This means that a frame defined with a mnemonic
that differs from an existing one only by case of letters will overwrite the original frame.
Note that the order of frame definitions in EDF is not important. For purposes of DeHackEd,
the number used to access a frame is now defined in the frame itself. For the original frames,
these happen to be the same as their order.
User frames that need to be accessible from DeHackEd can define a unique DeHackEd
number, which for purposes of forward compatibility, should be greater than or equal to 10000,
and less than 32768. User frames not needing access via DeHackEd can be given a DeHackEd
number of -1. This causes them to be inaccessible to DeHackEd.
Syntax:
# Remember that all fields are optional and can be in any order.
frame <unique mnemonic>
{
sprite = <sprite mnemonic>
spriteframe = <number> OR <character>
fullbright = <boolean>
tics = <number>
action = <bex codeptr name>
nextframe = <frame mnemonic> OR <nextframe specifier>
misc1 = <special field>
misc2 = <special field>
particle_event = <event name>
args = { <special field>, ... }
dehackednum = <unique number>
cmp = <compressed frame definition>
}
Explanation of fields:
# These are equivalent
spriteframe = 0
....
spriteframe = A
Effect name Effect
--------------------------------------
pevt_none No effect
pevt_rexpl Rocket Burst
pevt_bfgexpl BFG Burst
misc1 = frame:S_FOOBAR1
misc1 = thing:BaronOfHell
misc2 = sound:pistol
args = { 1, flags:SOLID|SHOOTABLE|COUNTKILL }
# this needs quotations here, whereas it doesn't in a BEX file, because both
# whitespace and + characters aren't allowed in unquoted strings in EDF
misc2 = "flags2:LOGRAV + BOSS"
args = { bexptr:Chase }
misc1 = 32768
misc2 = -45
args = { 1, 1, 2, 3, 5 }
# define some new frames
frame BLAH1
{
sprite = FOO1
fullbright = true
tics = 12
nextframe = BLAH2
}
frame BLAH2
{
sprite = FOO1
tics = 12
nextframe = BLAH1
}
# Overwrite an existing frame (since BLAH1 is already defined above...)
# Also remember that mnemonics are case-insensitive!
frame blah1
{
sprite = FOO1
fullbright = true
tics = 12
action = HticExplode
args = { 1 }
nextframe = S_NULL
}
Return to Table of Contents
Compressed Frame Definitions
Compressed frame definitions are a new feature in EDF 1.1 that allows a shorthand syntax for
specifying the fields of a frame block.
A compressed frame definition resides inside a normal EDF frame definition, using the
cmp keyword outlined in the syntax of the frame block.
It accepts a single string value with an extended syntax, and the value of all other fields
in the frame block except for the dehackednum can be set via this string. When the cmp
field is present in a frame block, all other fields except dehackednum are ignored.
Note that the cmp field is NOT accepted inside framedelta blocks.
As of Eternity Engine v3.31 Delta, the format of cmp fields has been relaxed
to allow arbitrary whitespace, quoted values, and line continuation. Line continuation was
discussed in the General Syntax section, but the new changes to the cmp
field are discussed below. Note that all existing cmp strings are still accepted as valid; the
new features simply allow for greater flexibility.
Syntax:
frame
{
cmp = <compressed frame definition>
}
The compressed frame definition string has the following syntax:
"sprite|spriteframe|fullbright|tics|action|nextframe|particle_event|misc1|misc2|args1-5"Fields MUST be provided in the order given, but any number of fields can be left off at the end of the definition, and those fields will receive their normal default values. To let an internal field default, you must use the special reserved value "*" for that field.
# this is a compressed frame definition which specifies ALL the values
frame FOOBAR1 { cmp = "AAAA|A|F|6|Look|@next|pevt_none|0|0|0|0|0|0|0" }
# this is an equivalent frame definition, using default specifiers and
# leaving off defaulting fields at the end of the definition. This frame
# and the above mean the EXACT same thing.
frame FOOBAR1 { cmp = "AAAA|*|*|6|Look|@next" }
# here is a complicated example using a parameterized codepointer
# Args start here
# |
# V
frame FOOBAR2 { cmp = "TROO|6|*|6|MissileAttack|@next|*|*|*|thing:DoomImpShot|*|*|20" }
Bad Frame Examples:
# This is wrong, field values may NOT be empty -- use "*" to indicate a default.
frame BAD1 { cmp = "AAAA|||6|Look|@next" }
# This is wrong because BEX flag fields CANNOT use '|' inside compressed frames, unless
# they are surrounded by escaped quotation marks.
frame BAD3 { cmp = "AAAA|B|T|23|SomePointer|*|*|*|flags:SOLID|SHOOTABLE|COUNTKILL" }
# This is wrong because you cannot leave off fields at the beginning.
frame BAD4 { cmp = "Look|@next" }
# This is wrong because fields must be in the correct order.
frame BAD5 { cmp = "6|TROO|*|6|thing:DoomImp|@next|MissileAttack|*|20" }
Examples Using EDF 1.3 Extended Syntax:
# Arbitrary whitespace is now allowed, and is ignored outside of quoted values:
frame NOWGOOD1 { cmp = "AAAA | * | * | 6 | Look | @next" }
# Values may now be quoted using escaped quotation marks so that they can contain
# normally ignored or reserved characters.
# This allows BEX flags strings to contain pipes and/or spaces:
frame NOWGOOD2 { cmp = "AAAA | * | * | 6 | Look | @next | * | \"flags:SHOOTABLE | SOLID | COUNTKILL\"" }
# EDF line continuation may be used inside any quoted string, including cmp field values.
# This frame is completely equivalent to the first example above:
frame NOWGOOD3
{
cmp = "AAAA | * | * | \
6 | Look | @next"
}
Return to Table of Contents
Thing Types
Thing types define monsters, lamps, control points, items, etc -- anything that moves, occupies
space, can display a sprite, or is useful for singling out locations.
Each thing type must be given a unique mnemonic in its definition's header, and this is the name
used to identify the thing type elsewhere. Each field in the thing type definition is optional.
If a field is not provided, it takes on the default value indicated below the syntax
information. Fields may also be provided in any order.
If a thing type's mnemonic is not unique, the latest definition of a thing type with that mnemonic
replaces any earlier ones. See the information below for more on this. As of EDF 1.1
(Eternity Engine v3.31 public beta 4), thing type mnemonics are completely case-insensitive. This
means that a thing type defined with a mnemonic that differs from an existing one only by case of
letters will overwrite the original type.
Note that the order of thing type definitions in EDF is not important. For purposes of DeHackEd,
the number used to access a thing type is now defined in the type itself. For the original
thing types, these happen to be the same as their order.
User thing types that need to be accessible from DeHackEd can define a unique DeHackEd
number, which for purposes of forward compatibility, should be greater than or equal to 10000
and less than 32768. User types not needing access via DeHackEd can be given a DeHackEd
number of -1. This causes them to be inaccessible to DeHackEd and to parameterized codepointers.
Syntax:
# Remember that all fields are optional and can be in any order.
thingtype <unique mnemonic>
{
inherits = <thing type mnemonic>
doomednum = <number>
spawnstate = <frame mnemonic>
spawnhealth = <number>
seestate = <frame mnemonic>
seesound = <sound mnemonic>
reactiontime = <number>
attacksound = <sound mnemonic>
painstate = <frame mnemonic>
painchance = <number>
painsound = <sound mnemonic>
meleestate = <frame mnemonic>
missilestate = <frame mnemonic>
crashstate = <frame mnemonic>
deathstate = <frame mnemonic>
xdeathstate = <frame mnemonic>
deathsound = <sound mnemonic>
speed = <number> OR <floating-point number>
radius = <floating-point number>
height = <floating-point number>
mass = <number>
damage = <number>
activesound = <sound mnemonic>
flags = <flag list>
flags2 = <flag list>
flags3 = <flag list>
cflags = <flag list>
addflags = <flag list>
remflags = <flag list>
raisestate = <frame mnemonic>
translucency = <number> OR <percentage>
bloodcolor = <number>
fastspeed = <number> OR <floating-point number>
nukespecial = <BEX codepointer mnemonic>
particlefx = <particle effect flag list>
droptype = <thing type mnemonic>
mod = <number>
obituary_normal = <string>
obituary_melee = <string>
translation = <number> OR <translation table lump name>
dmgspecial = <dmgspecial name>
skinsprite = <sprite mnemonic>
dehackednum = <unique number>
}
Explanation of fields:
Doomednum Range Usage
---------------------------------------------------------------
0 No-op, no thing will be spawned at all
1 - 4999 Original DOOM things and some extensions
5000 - 5999 BOOM-style control points
6000 - 6999 Reserved for port use
7000 - 7999 Things translated from other games
8000 - 8999 Reserved for port use
9000 - 9999 zdoom-style control points
10000 - 19999 Reserved for port use
20000 - 32767 Reserved for EDF
damage = ((rnd % 8) + 1) * missiledamage
This field is also used as a parameter by some new, parameterized codepointers, including
BetaSkullAttack and Detonate.
Blood color Number
--------------------------
Red (normal) 0
Grey 1
Green 2
Blue 3
Yellow 4
Black 5
Purple 6
White 7
Orange 8
--------------------------
Flag name Hex Value Effect
--------------------------------------------------------
ROCKET 0x00000001 Rocket trail
GRENADE 0x00000002 Grenade trail
FLIES 0x00000004 Swarm of flies
BFG 0x00000008 BFG particle swarm
REDFOUNTAIN 0x00010000 Red fountain
GREENFOUNTAIN 0x00020000 Green fountain
BLUEFOUNTAIN 0x00030000 Blue fountain
YELLOWFOUNTAIN 0x00040000 Yellow fountain
PURPLEFOUNTAIN 0x00050000 Purple fountain
BLACKFOUNTAIN 0x00060000 Black fountain
WHITEFOUNTAIN 0x00070000 White fountain
--------------------------------------------------------
Note that the fountain flag values cannot be combined with each other. Doing so will
simply result in another one of the existing fountain colors.
# a single effect
particlefx = ROCKET
# multiple effects
particlefx = BFG|GREENFOUNTAIN
# if there are spaces or disallowed characters, you must use quotations
particlefx = "BFG + GREENFOUNTAIN"
Unknown 0
Fist 1
Pistol 2
Shotgun 3
Chaingun 4
Rocket 5
R_Splash 6
Plasma 7
BFG 8
BFG_Splash 9
Chainsaw 10
SSG 11
Slime 12
Lava 13
Crush 14
Telefrag 15
Falling 16
Suicide 17
Barrel 18
Splash 19
Hit 20
BFG11K 21
BetaBFG 22
BFGBurst 23
PlayerMisc 24
Grenade 25
Specifying this field is not necessary for most thing types. It IS highly useful for controlling
the obituaries triggered by player projectiles, however. Some of the values above are not
fully supported yet.
Number Color
------------------
1 Indigo
2 Brown
3 Red
4 Tomato
5 Dirt
6 Blue
7 Gold
8 Felt
9 Black
10 Purple
11 "Vomit"
12 Pink
13 Cream
14 Yellow
------------------
# define a new thing type
thingtype ScarletPimpernel
{
doomednum = 15000
spawnstate = S_SCARPIMP1
flags = SPECIAL|NOTDMATCH
dehackednum = 10000
}
# overwrite an existing thing type (assume BaronOfHell is already defined normally...)
# everything is the same as the original except the fields I changed...
thingtype BaronOfHell
{
doomednum = 3003
spawnstate = S_BOSS_STND
seestate = S_BOSS_RUN1
seesound = brssit
painstate = S_BOSS_PAIN
painchance = 10 # changed from 50 to 10
painsound = dmpain
meleestate = S_BOSS_ATK1
missilestate = S_BOSS_ATK1
deathstate = S_BOSS_DIE1
deathsound = brsdth
speed = 12 # changed to from 8 to 12
radius = 24.0000
height = 64.0000
mass = 1000
activesound = dmact
flags = SOLID|SHOOTABLE|COUNTKILL
flags2 = E1M8BOSS|FOOTCLIP
raisestate = S_BOSS_RAISE1
obituary_normal = "was burned by a baron"
obituary_melee = "was ripped open by a baron"
dehackednum = 16
}
Return to Table of Contents
Thing Type Inheritance
New to EDF 1.2, thing type inheritance allows you to derive new thing types from existing
ones, so that there is no need to duplicate all the fields in the original type. To activate
inheritance for a thing type, use the following syntax:
thingtype <unique mnemonic>
{
inherits = <thing type mnemonic>
<any other thingtype fields>
}
When the inherits field is set in a thing type, its parent type will be processed first
if it has not already been processed. Then, all the fields from the parent type, except for
dehackednum and doomednum, will be copied from the parent type to this type. Once
the parent is copied, any other fields in this type will be treated as a thingdelta section,
such that only fields explicitly provided will overwrite values of the parent thing type.
Defaults will not be applied for unlisted fields, again with the exceptions of dehackednum
and doomednum.
/*
As you can see here, thing type inheritance allows inheriting type
definitions to be minimized to only those fields which must differ.
In this example, the dehackednum of the new thing type will be -1,
since it is unspecified. The doomednum will be 20001, since it is
not inherited, but is specified in the child type. Remember that the
dehackednum and doomednum fields are NOT copied between thing types.
*/
thingtype MyNewBaron
{
inherits = BaronOfHell # Inherit from the BaronOfHell
doomednum = 20001 # Set the doomednum to something meaningful
translucency = 50% # Make it 50% translucent
}
Return to Table of Contents
DOOM II Cast Call
The cast call structure allows you to edit and extend the DOOM II cast call used after
beating the game in DOOM II. Editing existing thing types via EDF or DeHackEd can otherwise
cause this part of the game to malfunction, and it has never before been possible to add your
own monsters into the fray. Now this can be done.
Unlike most other EDF sections, castinfo sections will be kept in the order they are
specified, unless the castorder array is defined. The castorder array feature
allows you to explicitly specify a complete ordering for the castinfo sections which
overrides the order of their definitions. See below for more information on castorder.
Beginning with EDF 1.1, all castinfo sections are required to have a unique mnemonic.
Sections with duplicate mnemonics will overwrite, with the last one occuring during parsing
taking precedence as the definition.
Syntax:
castinfo <mnemonic>
{
type = <thing type mnemonic>
name = <string>
stopattack = <boolean>
# see notes about this; there can be from zero to four sound blocks
sound
{
frame = <frame mnemonic>
sfx = <sound mnemonic>
}
}
Explanation of Fields:
# My New Cast Call -- Only The Ultimate FooBar and the Player are worthy!
castinfo foobar
{
type = FooBar
name = "The Ultimate FooBar"
sound { frame = S_FOOBAR_ATK1; sfx = firsht }
sound { frame = S_FOOBAR_ATK3; sfx = firsht }
sound { frame = S_FOOBAR_ATK5; sfx = firsht }
}
# Notice since DoomPlayer is now #2 and not #17, I still need to set his
# name, otherwise it would call him a former sergeant o_O
castinfo player
{
type = DoomPlayer
name = "Our Hero"
stopattack = true
}
Using the castorder Array
castorder = { <mnemonic>, ... }
All mnemonics specified in the castorder list must be valid. If any do not exist,
an error will occur.
# I decided to switch the cast call order around
castorder = { player, foobar }
...
# Later on, perhaps in another file, I add a new castinfo. I can do this:
castinfo weirdo
{
type = WeirdoGuy
name = "The Weirdo Guy"
}
# This will add weirdo to the end of the existing castorder list.
# I could also just redefine the entire list, but there's no point in this case.
castorder += { weirdo }
Return to Table of Contents
DOOM II Boss Brain Types
The Boss Brain thing types list allows editing of the types of monsters which can be spawned
by the DOOM II Boss Brain cube spitter object. This structure is a simple list of thing
type mnemonics, which are kept in the order they are provided. You can redefine the list at will,
just as with the spritenames list.
Starting with EDF 1.1, there is no longer an 11-type limitation on the boss spawner list.
However, if you provide more than 11 thing types in this list, you must also define the new
boss_spawner_probs list, which must be a list of numbers which when added together
equal 256. These numbers serve as the probability values out of 256 for the corresponding
thing types. If exactly 11 types are defined and the boss_spawner_probs list is not
defined, the normal defaults will be used. If boss_spawner_probs is defined, it MUST be the
exact same length as the boss_spawner_types list.
Starting with EDF 1.2, if a thing type in the boss_spawner_types list is invalid, the
"Unknown" thing type will be substituted for it. The previous behavior was to cause an error.
Syntax:
# A list of thing types
boss_spawner_types =
{
<thing type mnemonic>, ...
}
# A list of probabilities for the above thing types. If provided, this list
# must be the same length as the above, and if not provided, the above list
# must contain exactly 11 types. The numbers in this list must add up to 256.
boss_spawner_probs =
{
<number>, ...
}
Full Example:
# Changed DoomImp to FooBar, and Archvile to the ScarletPimpernel
# (so it can give you a powerup, but not very often, since Archvile is the
# rarest type ;)
# In a TC you might want to change ALL the monster types...
# These will use the default probabilities listed below, unless a
# boss_spawner_probs list is also defined somewhere.
boss_spawner_types =
{
FooBar, Demon, Spectre, PainElemental, Cacodemon, ScarletPimpernel,
Revenant, Arachnotron, Mancubus, HellKnight, BaronOfHell
}
Example with More than 11 Thing Types:
boss_spawner_types =
{
DoomImp, Demon, Spectre, PainElemental, Cacodemon, Archvile, Revenant,
Arachnotron, Mancubus, HellKnight, BaronOfHell, FooBar, ScarletPimpernel
}
boss_spawner_probs =
{
40, 40, 30, 10, 30, 2, 10, 20, 30, 22, 10, 10, 2
}
Normal Default Probabilities Used When 11 Types are Defined:
boss_spawner_probs =
{
# prob. / thing type normally in this position in the list
50, # DoomImp
40, # Demon
30, # Spectre
10, # PainElemental
30, # Cacodemon
2, # Archvile
10, # Revenant
20, # Arachnotron
30, # Mancubus
24, # HellKnight
10 # BaronOfHell
}
Return to Table of Contents
Sounds
New to EDF 1.1, sound definitions allow editing of existing sounds, as well as the addition of
new sounds which can be referred to by things and frames. Although Eternity already supports the
implicit addition of new sounds whose lumps start with the DS prefix, those sounds are only
available to MapInfo and scripting. Since EDF allows the assignment of DeHackEd numbers, it
allows much greater flexibility for new sounds.
EDF also provides access to some sound structure fields which are not currently supported
in DeHackEd.
Each sound must be given a unique mnemonic in its definition's header, and this is the name
used to identify the sound elsewhere. Each field in the sound definition is optional. If a
field is not provided, it takes on the default value indicated below the syntax
information. Fields may also be provided in any order.
Syntax:
sound <mnemonic>
{
lump = <string>
prefix = <boolean>
singularity = <singularity class>
priority = <number>
link = <sound mnemonic>
linkvol = <number>
linkpitch = <number>
skinindex = <skin index type>
dehackednum = <number>
}
Explanation of Fields:
sg_none
sg_itemup
sg_wpnup
sg_oof
sg_getpow
sk_none
sk_plpain
sk_pdiehi
sk_oof
sk_slop
sk_punch
sk_radio
sk_pldeth
sk_plfall
sk_plfeet
sk_fallht
# Define some new sounds
# This one is only accessible via scripting because it doesn't have a DeHackEd number.
sound MySound
{
lump = foo # this will play DSFOO, since prefix defaults to true
}
# This entry uses its mnemonic to double as the sound lump name.
sound dsblah
{
prefix = false # Without this, it would try to play DSDSBLAH, which is wrong
dehackednum = 10000
}
# This entry also uses the mnemonic as the sound name, but with prefixing.
# Since prefix defaults to true, the sound lump played will be "DSEXPLOD".
sound explod
{
priority = 128
dehackednum = 10001
}
# This entry links to another sound.
sound BlahLink
{
lump = dummy # this won't even get used in this case
prefix = false # dsblah doesn't need a prefix, so we should echo that here
link = dsblah # we've linked this entry to the dsblah sound
linkvol = 150 # use some suitable values for these (must experiment)
linkpitch = 0
dehackednum = 10002
}
# This entry overrides a previously defined sound.
sound explod
{
priority = 96 # Maybe we like 96 better than 128...
dehackednum = 10001 # We can reuse the same DeHackEd number, since it overwrites
}
Return to Table of Contents
Delta Structures
New to EDF 1.1, delta structures are an easier and more flexible way to edit existing thing
type, frame, and sound definitions.
Each delta structure for a thing type, frame, or sound specifies by mnemonic the section that it
edits inside it. This allows for any number of delta structures to be defined. The structures
are always applied in the order in which they are encountered during parsing, so that, like
style sheets in HTML, delta structures cascade. This means you can load your own set of
delta structures on top of an existing set in a modification.
Delta Structure Syntax:
# A delta structure for a frame has this syntax:
framedelta
{
name = <frame mnemonic>
<list of frame fields>
}
# A delta structure for a thing type has this syntax:
thingdelta
{
name = <thingtype mnemonic>
<list of thingtype fields>
}
# A delta structure for a sound has this syntax:
sounddelta
{
name = <sound mnemonic>
<list of sound fields>
}
The name field is required, and must be set to a valid sound, frame, or thingtype mnemonic in
order to specify the definition that the delta structure edits. Along with the name, the delta
structure can specify any field that is valid in that type of definition (see exceptions below).
# Change the Zombieman attack frame to use the shotgun zombie attack
framedelta
{
name = S_POSS_ATK2
action = SPosAttack
}
Thing Delta Example:
# Change the Zombieman's drop type to MegaSphere, and his spawnhealth to 400
thingdelta
{
name = Zombieman
droptype = MegaSphere
spawnhealth = 400
}
# Later on, maybe in a different file, we change the spawnhealth again
thingdelta
{
name = Zombieman
spawnhealth = 20
}
# At this point, the Zombieman drops MegaSpheres, but his spawnhealth is 20, not 400.
Sound Delta Example:
# This changes the sound explod we defined earlier
sounddelta
{
name = explod
priority = 200
singularity = sg_getpow
}
Return to Table of Contents
Miscellaneous Settings
These optional settings allow customization of various game engine behaviors. When not
provided, they take on the indicated default values. All of these options can only be
specified in the topmost level of an EDF file. The last definition encountered is the
one which will be used.
doom2_title_tics = 525 # make the DOOM II title screen last 15 seconds