
                   Doomsday Engine Definitions Reference
                        (or "Knee-Deep In The DED")
                   =====================================
        $Id: DEDDoc.txt,v 1.7 2004/01/26 14:52:45 skyjake Exp $

        Contact <skyjake@doomsdayhq.com> if you have any questions.


---------------------------------------------------------------------------
GENERAL SYNTAX
---------------------------------------------------------------------------
Elements of a DED file:

* Comments

  There are two kinds of comments: single-line and multi-line. Single line
  comments begin with a hash character (#) and continue until end of line.
  The parser will skip everything on the line after the # character. Multi-
  line comments begin with #> and continue until <# is found. An example:

      #> The comment begins...
      And continues
      ...and ends here <#

* Header block

  Use of the Header block is optional. For example:

      Header { Version = 6; }

  In DED version 5, there must be a semicolon after each statement,
  including blocks inside definition blocks. In version 6, semicolons are
  optional. If you don't include a version declaration, version 6 is
  assumed.

* Directives

* Definition blocks

* Attributes

  The "Copy" attribute can be replaced with an asterisk (*).

* Keys

* String values

  Strings begin and end in double quotation marks ("). If newline
  characters are found inside a string (the string has been divided into
  multiple lines) the newline and all following whitespace are skipped, and
  the actual string continues from the first non- whitespace character that
  follows.


---------------------------------------------------------------------------
DIRECTIVES
---------------------------------------------------------------------------
...........................................................................

Include "Other.ded";
    # The Include directive causes the parser to read the specified DED
    # file. The contents of the included file are read immediately after
    # the directive has been parsed.

IncludeIf <Not> -option "Other.ded";
    # The specified DED file is included if the option "-option" is (not)
    # found in the command line. Alternatively "-option" can be a game
    # mode string:

IncludeIf <Not> doom1-ultimate "Other.ded";
    # The specified DED file is included if the string matches (or does
    # not match) the current game mode.

SkipIf <Not> -option;
    # The rest of the file is skipped if the option "-option" is (not)
    # found in the command line. Alternatively "-option" can be a game
    # mode string.

SkipIf <Not> doom1-ultimate;
    # The rest of the file is skipped if the string matches (or does not
    # match) the current game mode.

ModelPath "MD2\Game\Item";
    # The ModelPath directive appends a new path to the list of model
    # search paths. NOTE: This directive has no scope: it affects all the
    # definitions that come before and after it. Also, be careful with
    # backslashes. Since they are used as escape characters in strings you
    # can't for example do this: "MD2\Game\Path\". That would mean the last
    # character of the path is " but the string itself doesn't end. You can
    # use forward slashes instead of backslashes.

...........................................................................


---------------------------------------------------------------------------
THING DEFINITIONS
---------------------------------------------------------------------------
...........................................................................

Thing
{
    ID = "";
    DoomEd number = 0;

    Name = "";
        # The real name of this thing, for example "Bag of Holding".
        # Currently not used by the engine.

    Spawn state = "";
    See state = "";
    Pain state = "";
    Melee state = "";
    Missile state = "";
    Crash state = "";
    Death state = "";
    Xdeath state = "";
    Raise state = "";
    See sound = "";
    Attack sound = "";
    Pain sound = "";
    Death sound = "";
    Active sound = "";
    Reaction time = 0;
    Pain chance = 0;
    Spawn health = 0;
    Speed = 0.0;
    Radius = 0.0;
    Height = 0.0;
    Mass = 0;
    Damage = 0;
    Flags = "";
    Flags2 = "";
    Flags3 = "";
    Misc1 = 0;
    Misc2 = 0;
    Misc3 = 0;
    Misc4 = 0;
}

...........................................................................


---------------------------------------------------------------------------
STATE DEFINITIONS
---------------------------------------------------------------------------
...........................................................................

State
{
    ID = "";
        # Identifier of this state.

    Flags = "";
    Sprite = "";

    Frame = 0;
        # Sprite frame. OR with 0x8000 (32768) to make fullbright.

    Tics = 0;

    Action = "";
        # Name of the action function of this state.

    Next state = "";
    Misc1 = 0;
    Misc2 = 0;
    Misc3 = 0;
}

...........................................................................


---------------------------------------------------------------------------
SPRITE DEFINITIONS
---------------------------------------------------------------------------
...........................................................................

Sprite
{
    ID = "";
        # Name of the sprite. Must be four characters long. Sprite
        # frame lump names always begin with a sprite ID.
}

...........................................................................


---------------------------------------------------------------------------
LIGHT DEFINITIONS
---------------------------------------------------------------------------
The engine usually calculates the properties of dynamic lights based on the
sprite frame of the light source. Any zero values in the Light definition
will be replaced by these automatic calculations (zero is the default for
all keys).
...........................................................................

<Copy> Light
{
    # If "Copy" is found all the data of the previous definition is
    # copied to this one as defaults. For the first definition in a
    # file "Copy" has no effect.

    State = "";
        # The State with which the light properties defined here will
        # be used.

    Flags = "";
        # lgf_nohalo: No lens flare (halo) is rendered.

    X Offset = 0.0;
        # In pixels, offset from the center of the source. The offset
        # is parallel with the view plane.

    Y Offset = 0.0;
        # In pixels, offset from the top of the source object.

    Size = 0.0;
        # Size (strength) of the light. Should be between 0 and 1.

    Red = 0.0;
        # Red color component (0-1).

    Green = 0.0;
        # Green color component (0-1).

    Blue = 0.0;
        # Blue color component (0-1).

    Color { 0.0 0.0 0.0 };
        # Sets all three color components at the same time.

    Top map = "";
    Bottom map = "";
    Side map = "";
        # Name of the light map to use. The top map is used for ceiling
        # planes, the bottom map for floors and the side map for walls.
        # If left blank (the default), the standard round dynlight texture
        # is used. Use "-" to disable a map entirely. No light will then be
        # cast in the direction.
}

...........................................................................


---------------------------------------------------------------------------
DECORATION DEFINITIONS
---------------------------------------------------------------------------
You can define multiple Decorations for the same texture/flat, but only the
latest one that passes the conditions will be used. By default (if you
specify no usage flags), a Decoration is only used with resources loaded
from an IWAD.
...........................................................................

<Copy> Decoration
{
    # If "Copy" is found all the data of the previous definition is
    # copied to this one as defaults. For the first definition in a
    # file "Copy" has no effect.

    Texture = "";
        # Name of the texture with which this decoration is used.

    Flat = "";
        # Name of the flat with which this decoration is used. You can
        # only specify either a Texture or a Flat, not both.

    Flags = "";
        # dcf_noiwad: Don't use this decoration if the resource is loaded
        #       from an IWAD.
        #
        # dcf_pwad: This decoration can be used with PWAD resources (for
        #       example custom textures).
        #
        # dcf_ext: This decoration can be used with external resources.

    Light
    {
        # Each decoration can specify up to 8 lights.

        Offset { 0.0 0.0 };
            # Origin of the light in texture coordinates.

        Distance = 1.0;
            # Distance between the origin of the light and the surface.

        Color { 0.0 0.0 0.0 };
            # RGB color (values 0-1) of the light. Color (0,0,0) marks
            # the end of the light definitions. Any lights that follow are
            # not rendered.

        Radius = 1.0;
            # Radius of the dynamic light.

        Halo radius = 0.0;
            # Radius of the halo. Zero means no halo is rendered. Note
            # that halo radius 1.0 produces quite a large flare.

        Flare texture = 0;
            # Texture to use for the primary flare (i.e. the halo itself):
            # 0 = Texture chosen automatically.
            # 1 = Default dynamic light texture.
            # 2 = FLARE.
            # 3 = BRFLARE.
            # 4 = BIGFLARE.

        Top map = "";
        Bottom map = "";
        Side map = "";
            # Name of the light map to use. The top map is used for ceiling
            # planes, the bottom map for floors and the side map for walls.
            # If left blank (the default), the standard round dynlight
            # texture is used. Use "-" to disable a map entirely. No light
            # will then be cast in the direction.

        Levels { 0 0 };
            # Two integers (0-255) that mark the sector light levels where
            # the light is at zero and maximum brightness, respectively.
            # For example, the levels { 100 200 } mean that the light is
            # not visible under light level 100, fades gradually to full
            # brightness when nearing light level 200, and stays full
            # bright over 200. The first level can be higher than the
            # second. The behaviour is then reversed: the light is at full
            # brightness only below the lower light level.

        Pattern skip { 0 0 };
            # Normally the light is repeated on a surface as many times as
            # the texture or flat repeats. The pattern skip values allow
            # sparser repeats for horizontal and vertical patterns,
            # respectively. For example, the skips { 1 2 } will make the
            # light only appear on every second horizontal repeat and
            # every third vertical repeat.

        Pattern offset { 0 0 };
            # Used with pattern skip to offset the origin of the pattern.
            # For example, the offset { 1 0 } will shift the origin of the
            # pattern one full horizontal repeat.
    };
}

...........................................................................


---------------------------------------------------------------------------
DETAIL TEXTURE DEFINITIONS
---------------------------------------------------------------------------
General detail texture strength, scaling and maximum distance can modified
with the "detail" console command. One Detail definition can be used to
assign a detail texture to one wall texture and/or one flat picture.
...........................................................................

<Copy> Detail
{
    # If "Copy" is found all the data of the previous definition is
    # copied to this one as defaults. For the first definition in a
    # file "Copy" has no effect.

    Wall = "";
        # Name of the wall texture which this detail texture should be
        # associated with.

    Flat = "";
        # Name of the flat which this detail texture should be
        # associated with.

    Lump = "";
        # Lump name of the detail texture (e.g. "DTLROUGH"). This must
        # be a 64x64, 128x128 or 256x256 raw image with one color
        # component (a black and white image). This means the size of
        # the lump can be either 4096, 16384 or 65536 bytes.

    Scale = 1.0;
        # Relative scaling for the detail texture. Actual scaling is
        # calculated with (Scale)*(common-scaling-factor). The default
        # value for the common scaling factor is 4 (which means one
        # world unit corresponds four detail texture pixels).

    Strength = 1.0;
        # Relative intensity factor. Actual strength is calculated
        # with (Strength)*(common-strength-factor). The default value
        # for the common strength factor is 0.5.

    Distance = 0.0;
        # Maximum distance at which the detail texture is visible. If
        # left at zero, the common maximum distance is used (default:
        # 256). Smaller maximum distances may cause problems with
        # floors and ceilings, where big polygons cause inaccuracies
        # in the calculation of eye -> vertex distance.
}

...........................................................................


---------------------------------------------------------------------------
GENERATOR DEFINITIONS
---------------------------------------------------------------------------
A particle generator must always be triggered somehow to be spawned. There
are four types of triggers available: State, Type, Flat and Map. The
trigger also determines the generator's source, from which the generator's
particles seem to originate. A generator must have a source to be able to
create new particles. If the source of a generator is destroyed before the
generator dies, the only result will be that no new particles are created.
Any existing particles created prior to the removal of the source will live
on.

State triggering means that the generator is spawned when any mobj enters
the state the generator has been associated with. The mobj in question will
become the source of the generator. State triggering is especially useful
with "one time" effects such as explosions. State triggering should be
avoided with mobjs that have a loop of states (if the gnf_spawn flag is not
used). This can lead to generators being spawned more frequently than
necessary.

All Type triggered generators are spawned at the beginning of a level. Each
Type triggered Generator definition gets its own particle generator entity.
Type triggering makes the generator multi-sourced: all mobjs in the level
with one of the types associated with the generator will act as particle
sources. The effect is similar to having a separate generator for each
mobj. Note, however, that you need to allocate a fairly large number of
particles in the definition since all the mobjs use the same generator.

Flat triggering works a bit differently. The level is periodically checked
for any planes with the specified flat as texture (floors and ceilings). A
generator is spawned for all planes that match the associated flat. The
sector to which the plane belongs will become the source of the generator.
The origin of the particles can be the ceiling or floor plane, or the space
in between. The default behaviour can be modified using the gnf_floor,
gnf_ceiling and gnf_space flags. Each plane can have only one generator,
i.e. each sector can have up to two generators.

Map triggered generators are all spawned in the beginning of a level, but
only if the level has a map ID that matches the generator's. Map triggered
generators use the Center key to define their origin because they haven't
got an object as a source. The Center is interpreted as world coordinates
(X,Y,Z). When using map triggered generators it's probably best to set the
Max age and Spawn age keys to -1, to allow the generator to operate
indefinitely.

There is a limit to the number of active particle generator entities in the
level (currently 96). If the maximum number is reached, existing non-static
generators will be destroyed to make room for any new generators.
...........................................................................

<Copy> Generator
{
    State = "";
        # Particle generators can be either State, Flat or Type
        # triggered. Whenever a mobj is set to this state, a new
        # particle generator is spawned. If the gnf_spawn flag is set,
        # the generator is only spawned when the source mobj itself is
        # being spawned; handy if the mobj has a loop of states and
        # the generator should only be spawned when the state is first
        # set.

    Flat = "";
        # Makes this a Flat triggered generator. Each plane with the
        # given flat receives its own generator. The gnf_* flags can
        # be used to control where the particles are actually spawned.

    Mobj = "";
        # Makes this a Type triggered generator. The value must be a
        # defined thing ID (e.g. "PLAYER"). All Type triggered generators
        # are spawned in the beginning of a level, and they create
        # particles using all mobjs of the given type as sources. Use the
        # gnf_static flag to prevent the generator from being removed by
        # later generators (could happen when the maximum number of
        # generators is reached).

    Alt mobj = "";
        # Alternate mobj type for Type triggered generators.

    Damage mobj = "";
        # Makes this a Damage triggered generator. They are spawned when a
        # mobj of the specified type receives damage. The initial movement
        # direction is calculated from the positions of the mobjs involved
        # in the operation, so that positive speed values will make the
        # particles move away from the inflictor (in the direction of the
        # damage).
        #
        # NOTE: Damage triggered particle generators currently do not work
        #       on the clientside (netgames and demos).

    Map = "";
        # Makes this a Map triggered generator. The generator is spawned
        # only in the specified map (e.g. "E2M3"). The Center key defines
        # the spawn origin.

    Flags = "";
        # gnf_static: Generator will not be removed until it times
        #       out. Otherwise it might get replaced by newer
        #       generators if there are too many active generators.
        #
        # gnf_extra: (State triggered) This generator is to be spawned
        #       simultaneously with the previously defined generator. This
        #       allows having multiple generators assigned to the same 
        #       state. If this flag is not used, all the previously 
        #       defined generators associated with the state are ignored.
        #
        # gnf_srcvel: (State/Type triggered) Particles inherit their
        #       source's velocity (in addition to spawn velocity).
        #
        # gnf_srcdir: (State/Type triggered) Particle movement vector
        #       is rotated using source's direction angle.
        #
        # gnf_spawn: Generator is only spawned if the source mobj is
        #       being spawned.
        #
        # gnf_blendadd: Particles of the generator are rendered using
        #       additive blending ('gnf_blend' is an alias for this).
        #
        # gnf_blendrsub: Particles of the generator are rendered using
        #       reverse subtractive blending (framebuffer - particle).
        #
        # gnf_blendsub: Particles of the generator are rendered using
        #       subtractive blending (particle - framebuffer).
        #
        # gnf_blendmul: Particles of the generator are rendered using
        #       multiplicative blending (particle * framebuffer).
        #
        # gnf_blendimul: Particles of the generator are rendered using
        #       inverse multiplicative blending ((1-ptc) * framebuffer).
        #
        # gnf_modelonly: The particle generator will only be active
        #       if the source is represented by a 3D model.
        #
        # gnf_floor: (Flat triggered) Particles of the generator will
        #       be created on the floor of the source sector.
        #
        # gnf_ceiling: (Flat triggered) Particles of the generator
        #       will be created in the ceiling of the source sector.
        #
        # gnf_space: (Flat triggered) Particles of the generator will
        #       be spawned at a random height in the sector.
        #
        # gnf_density: (Flat triggered) The "Particles" key specifies
        #       the maximum density of particles per block (128x128)
        #       rather than the maximum number of particles for the
        #       generator.

    Speed = 0.0;
        # Initial speed for new particles.

    Speed Rnd = 0.0;
        # Randomness of initial particle speed (between 0 and 1):
        # 0 = Not random at all.
        # 1 = Randomly scaled between zero and the value of "Speed".

    Vector { 0.0 0.0 0.0 };
        # Initial movement direction for new particles.

    Vector Rnd = 0.0;
        # Randomness of initial particle direction. Random components
        # of the given value are added to "Vector". For example, if
        # "Vector Rnd" is 2, a random vector with components ranging
        # from -2 to 2 is added to "Vector".
        
    Init Vector Rnd = 0.0;
        # One-time random component applied to "Vector" when the generator
        # is spawned. Works as Vector Rnd, but only applied once.

    Center { 0.0 0.0 0.0 };
        # (State/Type triggered) An offset to the source coordinates.
        # X = Distance on the XY plane (world units), rotated using
        #     source angle.
        # Y = Source angle offset (degrees).
        # Z = Z distance (positive is upwards, world units).
        #
        # (Map triggered) Coordinates of the origin (X, Y, Z).

    Submodel = -1;
        # (State/Type triggered) If the source is represented by a 3D
        # model, this submodel's center will be used as the origin of the
        # generator. If less than zero, the source's actual coordinates
        # are used and the model has no effect on the origin's position.

    Spawn radius = 0.0;
        # Particles will be spawned at a random distance from the center of
        # the source, at a distance of at most this many units. A flat
        # distribution inside a cube is used if the Min spawn radius is
        # zero.

    Min spawn radius = 0.0;
        # Particles will be spawned at least this many units away from the
        # center of the source. Setting this to a nonzero value will enable
        # the more advanced algorithm for choosing particle spawn
        # coordinates: a random point is chosen inside a sphere with the
        # radius of Spawn radius, but not closer than Min spawn radius.

    Distance = 0.0;
        # Maximum distance at which the particles of the generator are
        # visible. If zero, there is no distance limitation.

    Spawn age = 0;
        # Number of tics that the generator will create new particles
        # after having been spawned. If -1, the generator will
        # continue creating new particles until destroyed.

    Max age = 0;
        # Maximum generator lifetime, in tics. If -1, the generator
        # will not be destroyed until either replaced by a newer
        # generator or the level ends.

    Particles = 0;
        # Maximum number of particles that the generator can have, or
        # the maximum density of particles per 128x128 block (with
        # Flat triggered generators using the gnf_density flag).

    Spawn rate = 0.0;
        # Number of new particles spawned per game tic. Fractional
        # values are allowed (< 1.0).

    Spawn Rnd = 0.0;
        # Randomness of spawn rate (between 0 and 1):
        # 0 = Not random.
        # 1 = Spawn rate is randomly scaled between zero and the value
        #     of "Spawn rate".

    Presim = 0;
        # Number of tics to "think ahead" when the generator is
        # spawned. Useful for Flat triggered generators that are
        # visible right after starting a level.

    Alt start = 0;
        # Index number of the alternative particle start stage. By
        # default all particles start from stage zero.

    Alt Rnd = 0.0;
        # Randomness of initial particle stage (between 0 and 1):
        # 0   = Default stage (zero) is always used.
        # 0.5 = 50% chance of starting with Alt start.
        # 1   = Always start from Alt start.

    Force = 0.0;
        # Strength of the sphere force that pulls or pushes particles
        # towards the surface of the sphere. In most cases the value should
        # be less than one.

    Force radius = 0.0;
        # Radius of the sphere for sphere force. The force will push or
        # pull particles to the surface of this sphere, centered around the
        # center of the generator (with the offset specified with Force
        # origin applied).

    Force origin { 0.0 0.0 0.0 };
        # Defines the coordinates for the force sphere in relation to the
        # center of the source.

    Force axis { 0.0 0.0 0.0 };
        # The sphere force can also rotate particles around an axis. The
        # length of the axis defines how strong the rotation is.

    Stage
    {
        # Each generator can have up to 32 particle stages. Each
        # particle will go through the defined stages starting from
        # zero or the alternative start stage.

        Type = "";
            # pt_point: Render particle as a point.
            #
            # pt_line: Render particle as a line. The length of the
            #       line depends on the speed of the particle.
            #
            # pt_texNN: Use Data\<Game>\Textures\ParticleNN.
            #
            # pt_modelNN: Use Model definition with ID "ParticleNN".

        Tics = 0;
            # Number of tics that the particle will spend in this
            # stage.

        Rnd = 0.0;
            # Randomness of stage tics (between 0 and 1).

        Color { 0.0 0.0 0.0 0.0 };
            # RGBA color of the stage (components between 0 and 1).
            # The fourth component of the color vector is the alpha
            # component: 1 = opaque, 0 = fully transparent.

        Radius = 0.0;
            # Radius of the particle at this stage, in world units.
            # The visible radius is interpolated between the radii of
            # the current stage and the next one.
            
        Radius Rnd = 0.0;
            # Randomness of particle radius. The radius of a particle will
            # be randomly chosen from the range:
            # (1 - RadiusRnd)*Radius ... Radius

        Flags = "";
            # ptf_stagetouch: When touching a wall or a plane, the
            #       particle will immediately skip to the next stage.
            #
            # ptf_stagevtouch: Only applies to walls.
            #
            # ptf_stagehtouch: Only applies to planes.
            #
            # ptf_dietouch: Particle will die when it touches a wall
            #       or a plane.
            #
            # ptf_bright: Particle's color is not affected by the
            #       light level of the sector it's in.
            #
            # ptf_flat: When touching a wall or a plane, the particle
            #       is rendered flat against the surface.
            #
            # ptf_vflat: Only applies to walls.
            #
            # ptf_hflat: Only applies to planes.
            #
            # ptf_force: Particle is affected by the sphere force.
            #
            # ptf_zeroyaw: Set particle yaw to zero.
            #
            # ptf_zeropitch: Set particle pitch to zero.
            #
            # ptf_rndyaw: Set particle yaw to a random value.
            #
            # ptf_rndpitch: Set particle pitch to a random value.

        Bounce = 0.0;
            # Determines how 'bouncy' the particle is (0..1):
            # (particles will only collide with walls and planes)
            # 0 = Particle loses all its momentum when it hits
            #     something (in the direction of the collision).
            # 1 = Particle retains all its momentum and continues
            #     moving in the opposite direction after a collision.
            # >1 = Particle gains extra speed in collisions.

        Gravity = 0.0;
            # Determines how strong an effect gravity has on the
            # particle. Normal mobjs have a Gravity factor of 1.0.

        Force { 0.0 0.0 0.0 };
            # A linear force that affects the particle during this stage.
            # Gravity = 1 would correspond Force { 0 0 -1 }. This force is
            # applied independently of sphere force.

        Resistance = 0.0;
            # Air resistance for the particle (between 0 and 1):
            # 0   = Particle moves without friction.
            # 0.5 = Particle loses half of its momentum each tic.
            # 1   = All movement of the particle will stop in one tic.
            
        Frame = "";
            # First model frame in the animation sequence of a model 
            # particle. The animation will interpolate through all the 
            # frames between Frame and End frame.
        
        End frame = "";
            # Last model frame in the animation sequence of a model 
            # particle.
            
        Spin { 0.0 0.0 };
            # Model particle spinning velocity (yaw and pitch, 
            # respectively) in degrees per second. Each particle will
            # randomly change the sign of the spinning velocity when the
            # particle is first spawned.
            
        Sound = "";
            # ID of the sound to play when a particle enters this stage.
            # Sound will use the particle's coordinates as its origin. Use
            # carefully: starting a lot of sounds is a heavy operation.
            
        Volume = 1.0;
            # Volume of "Sound" (0...1).
            
        Hit sound = "";
            # ID of the sound to play when a particle hits a surface while
            # in this stage. Sound will use the particle's coordinates as
            # its origin. Use carefully: starting a lot of sounds is a 
            # heavy operation.
      
        Hit volume = 1.0;
            # Volume of "Hit sound" (0...1).
    };
}

...........................................................................


---------------------------------------------------------------------------
SOUND DEFINITIONS
---------------------------------------------------------------------------
...........................................................................

Sound
{
    ID = "";
    Lump = "";
    Name = "";
    Link = "";
    Link pitch = 0;
    Link volume = 0;
    Priority = 0;
    Max channels = 0;
    Flags = "";

    Ext = "";
    File = "";              # Same as "Ext"
    File name = "";         # Same as "Ext"
        # External sound file. Must be a mono WAV file with no
        # compression. If specified, this sound file will be played
        # instead of the sound data in Lump (if a Lump is defined).
        # Relative paths are interpreted in relation to the base path, so
        # "Sound/Kaboom.wav" becomes "<BasePath>/Sound/Kaboom.wav".
}

...........................................................................


---------------------------------------------------------------------------
MUSIC DEFINITIONS
---------------------------------------------------------------------------
...........................................................................

Music
{
    ID = "";
        # The ID of the song.

    Lump = "";
        # Name of a lump containing a MUS song.

    Ext = "";
    File = "";              # Same as "Ext"
    File name = "";         # Same as "Ext"
        # External music file. Played using FMod. This can either be a
        # file name (e.g. "c:\music\song.mp3") or a CD track (e.g.
        # "cd:8"). Supports many kinds of music files, see
        # http://www.fmod.org/ for details. Relative paths are
        # interpreted in relation to the base path, so "Music/Rock.mp3"
        # becomes "<BasePath>/Music/Rock.mp3".

    CD track = 0;
        # Overrides "cd:" in the Ext key.
}

...........................................................................


---------------------------------------------------------------------------
TEXTURE ENVIRONMENT DEFINITIONS
---------------------------------------------------------------------------
The Texture Environment definitions are used to calculate the 3D sound
characteristics of the sectors in a map.
...........................................................................

Texture Environment
{
    ID = "";
        # Identifier of this environment. Must be either "Metal",
        # "Rock", Wood" or "Cloth".

    Texture
    {
        # There can be any number of Texture blocks inside a Texture
        # Environment definition.

        ID = "";
            # Name of a wall texture (e.g. "STARTAN3").
    }
}

...........................................................................


---------------------------------------------------------------------------
MAP INFO DEFINITIONS
---------------------------------------------------------------------------
...........................................................................

<Copy> Map Info
{
    # If the "Copy" attribute is used, all the data of the previous
    # definition is copied to this one. For the first definition in a file
    # "Copy" has no effect.

    ID = "";
        # Map identifier. Could be "ExMy" or "MAPxy" depending on the
        # game. Example: if this map info is meant for the first map
        # of the second episode, the ID is "E2M1". If the ID is "*"
        # (asterisk), this definition will be used for all maps that
        # don't have a definition of their own.

    Name = "";
        # Name of the map. Displayed e.g. in the automap and in the
        # console when the map is loaded.

    Author = "";
        # Author of the map. Displayed e.g. in the console when the
        # map is loaded.

    Flags = "";
        # mif_fog: Enable fog in the map.
        #
        # mif_sphere: Draw the sky sphere even when sky models have been
        #       set up.

    Music = "";
        # Identifier of the song to play during this map. Notice that
        # this is the identifier of the Music definition, not the
        # actual MUS lump found in a WAD file.

    Par time = 0.0;
        # Par time of the map, in seconds.

    Fog color R = 0.0;
        # Red color component (0-1) of the fog used in the map.

    Fog color G = 0.0;
        # Green color component (0-1) of the fog used in the map.

    Fog color B = 0.0;
        # Blue color component (0-1) of the fog used in the map.

    Fog start = 0.0;
        # (Linear fog) Fog start distance, in world units.

    Fog end = 0.0;
        # (Linear fog) Fog end distance, in world units.

    Fog density = 0.0;
        # Used in exponential(2) fog mode.

    Ambient light = 0.0;
        # Minimum light level (0-1) of all sectors in the map.

    Gravity = 1.0;
        # Gravity in the map.

    Sky height = 0.666667;
        # Height of the sky sphere (0-1). The real height is an angle
        # determined using Pi/2 * (sky height), which means if the sky
        # height is 1, the sphere covers the whole sky.

    Horizon offset = 0.0;
        # Angle offset to sky vertices, in radians. Negative angles
        # move the horizon downwards.

    Sky Layer 1
    {
        Flags = "";
            # slf_enable: Enable layer. By default the layer is
            #       disabled and will not be rendered.
            #
            # slf_mask: Layer texture's color zero should be masked.

        Texture = "";
            # Name of the texture to use for this layer.

        Offset = 0.0;
            # A horizontal offset applied to the texture coordinates
            # of the layer.

        Color limit = 0.0;
            # Specifies how small an intensity (0-1) the sky fadeout
            # color (top line of the texture) can have before the
            # fadeout color is reduced to black.
    };
    Sky Layer 2
    {
        Flags = "";
        Texture = "";
        Offset = 0.0;
        Color limit = 0.0;
    };

    Sky Model
    {
        # There can be up to 32 Sky Model blocks in a Map Info definition.
        # Each block defines one a sky model.

        ID = "";
            # Identifier of the Model definition that describes the 3D
            # model. If left empty, this sky model will be disabled.
            
        Layer = 0;
            # The sky layer this model is associated with. Valid values 
            # are 1 and 2. If zero, model does not depend on the sky 
            # layers. If set to nonzero, the sky model is hidden when the
            # associated layer is hidden (i.e. not enabled).

        Frame interval = 1.0;
            # The number of seconds between frame changes. Sky model
            # animation is interpolated. The model is animated by going
            # through all its frames one by one.

        Color { 1.0 1.0 1.0 1.0 };
            # RGBA color for the model.

        Offset factor { 0.0 0.0 0.0 };
            # The position of the sky model may depend on the coordinates
            # of the camera. The Offset factor key sets a factor for each
            # axis (X, Y, Z) separately. Small factors (< 1.0) can be used
            # to create the illusion that the sky model is larger than it
            # really is. If the factors are zero, the sky model's origin 
            # will be positioned at the camera's viewpoint.
            
        Rotate { 0.0 0.0 };
            # Additional rotation around the X and Z axes, respectively (in 
            # degrees). These are applied after normal rotation.
            
        Yaw = 0.0;
            # Initial rotation around the Y axis (in degrees).
            
        Yaw speed = 0.0;
            # Angular velocity around the Y axis (in degrees per second).
    };
}

...........................................................................


---------------------------------------------------------------------------
FINALE DEFINITIONS
---------------------------------------------------------------------------
The Finale definition is used to define intros, interludes and finale
animations. All of these are called "finales" in this reference. The
finales of the original DOOM, Heretic and Hexen typically have a tiled flat
as the background and text that is slowly typed onto the screen.
...........................................................................

Finale
{
    Before = "";
        # Identifier of the map before which this finale should be
        # played. The precise form of the identifier depends on the
        # Game, but the two commonly used ones are "ExMy" and "MAPxy",
        # where "x" and "y" denote episode and map numbers; "E2M3".

    After = "";
        # Identifier of the map after which this finale should be
        # played. Normally it's useful to only use either one of the
        # Before and After keys, though both can be set at the same
        # time.

    Game = 0;
        # Game selector. Currently only used by jDoom to separate
        # Plutonia (Game=1) and TNT (Game=2) from Doom II (Game=0).
        # IncludeIf/SkipIf and game mode strings could also be used for
        # this purpose.

    Script { };
        # An InFine script that defines what the finale does. The same
        # parsing rules are used when reading the script and the DED
        # file itself, so for instance strings can be split onto
        # multiple lines (see Text definitions). See the InFine
        # Scripts reference for more information.
}

...........................................................................


---------------------------------------------------------------------------
TEXT DEFINITIONS
---------------------------------------------------------------------------
Do not change the order of existing Text definitions; always add new
definitions to the end of the list. This is because Games access strings
using the index numbers of the strings, and the indices are assigned based
on the order of the Text definitions.
...........................................................................

Text
{
    ID = "";
        # Identifier of the text string.

    Text = "";
        # The string itself. Backslash (\) is used as an escape
        # character: \n = newline. Quotes (") must be escaped or the
        # parser will think the string ends ("Say \"Hello!\""). The
        # string can be divided onto multiple lines, in which case the
        # parser will skip to the first non-space character of the
        # next line when it encounters an end of line. For example
        # the following two strings are identical:
        #
        # "This is a long
        #    string?"
        #
        # "This is a longstring?"
        #
        # The escape sequence \_ translates to a normal space
        # character, so these two strings are also identical:
        #
        # "This is another long
        #   \_string."
        #
        # "This is another long string."
        #
}

...........................................................................


---------------------------------------------------------------------------
VALUE DEFINITIONS
---------------------------------------------------------------------------
The engine itself doesn't use the values for anything. You can think of the
Values definition as a registry of nested string pairs (a bit like Windows'
registry). Internally the hierarchy levels are separated with the |
(vertical line) character, so you can't use it in the key names.
...........................................................................

Values
{
    Key1 = "Example";
    My block {
        Nested key = "This is a string";
        Other key = "Hello";
    };

    # The definitions above would create the following entries:
    #
    # Key1                          Example
    # My block|Nested key           This is a string
    # My block|Other key            Hello
}

...........................................................................


---------------------------------------------------------------------------
MODEL DEFINITIONS
---------------------------------------------------------------------------
A 'Model' can be thought of as a collection of one to eight MD2 models.
Each MD2 file assigned to a Model is called a submodel. Thus a Model can
have up to eight submodels. In the Model definition the submodels are
defined sequentially starting from zero. The engine handles the submodels
separately, which makes it possible to interpolate the animation of each
submodel independently of the other submodels.

An example of the structure of a Model definition is given below:

Model {
    Md2 { };    # 1st submodel (submodel 0).
    Md2 { };    # 2nd submodel (submodel 1).
    Md2 { };    # 3rd submodel (submodel 2).
    Md2 { };    # 4th submodel (submodel 3).
}

One Md2 block is required, the rest should be omitted if the Model has only
one MD2 file. You can set flags in both the main Model definition and the
submodel Md2 definitions.

* Flags defined in the main definition affect all the submodels, for
  example:

  Model {
    Flags = "df_shadow1";
  }

  This means the flag will affect all the submodels of the model.

* If the Flags key is placed in a Model:Md2 definition, for example:

  Model {
    Md2 { Flags = "df_shadow1"; };
  }

  it only affects the single submodel. NOTE: a XOR operation is done so
  that using Model:Md2:Flags will reverse any flags set in Model\Flags.
  This way Model:Md2:Flags can be used to either turn off or on single
  flags that affect the whole model (depending on whether the flag is set
  in Model:Flags or not). For instance:

  Model {
    Flags = "df_shadow1";
    Md2 { Flags = "df_shadow1"; };      # Not shadowed at all.
    Md2 { Flags = "df_fullbright"; };   # Shadowed and fullbright.
    Md2 { };                            # Just shadowed.
  }

Inter and Interpolate can be used together. You can for example assign two
model frames to span across three states:

:    (Frame 1)    :    (Frame 2)    :
:                 :                 :
+-----------+-----------+-----------+ Time-->
| (State 1) | (State 2) | (State 3) |
|0         1|0   0.5   1|0         1| Inter (0..1)
D1----------D2----D3----D4----------+
:           :     :     :
:           :     :     4th defn: S3, Inter=0, Interpolate {0.333 1}
:           :     :
:           :     3rd defn: S2, Inter=0.5, Interpolate {-0.333 0.333}
:           :
:           2nd defn: S2, Inter=0, Interpolate {0.666 1.333}
:
1st definition: S1, Inter=0, Interpolate {0 0.666}

Note the 2nd definition's Interpolate end marker (1.333) and 3rd
definition's Interpolate start marker (-0.333). This is needed because the
2nd definition only extends from Inter=0 to Inter=0.5, but we want that at
Inter=0.5 the interpolation visually reaches its end (frame 1 ends and
frame 2 begins): point 0.5 in the range {0.666 1.333} is one. The 3rd
definition's case is similar, but this time the definition begins really
from Inter=0.5 and visually from the beginning (i.e. zero). When 0.5 is
scaled to the range {-0.333 0.333} we get the zero we wanted.
...........................................................................

<Copy> Model
{
    # If "Copy" is found, all the data of the previous definition is
    # copied to this one as defaults. For the first definition in a
    # file "Copy" has no effect.

    ID = "";
        # The identifier of this definition. You can only set either the ID 
        # key or the State key, not both. Models with an ID can't be 
        # assigned to Thing States.

    State = "";
        # The State this model will be used with. You can only set either 
        # the ID key or the State key, not both.

    Off = 0;
        # Offset to state index. Use carefully! If State indices
        # change you'll be in a lot of trouble.

    Group = "";
        # One or more group IDs (mg_*). Optional.

    Selector = 0;
        # A custom value which can be used by the Game for various
        # purposes, like alternative models for some objects.

    Inter = 0.0;
        # Possible values: 0-1. Determines the point during the
        # interpolation between states when this definition becomes
        # valid. Can be used to assign several different model frames
        # to a single State.

        # NOTE: When defining models that use Inter, the definitions
        #       must be given in an ascending order; the definition
        #       with the lowest Inter comes first.

    Interpolate { 0.0 1.0 };
        # Range of interpolation. Specifies the range of the visual
        # interpolation of the model during the State. Can be used to
        # extend the interpolation of one model frame onto multiple
        # States (by defining a sub-0..1 range). Always define full
        # ranges that begin from zero and end to one.
        #
        # When the "df_worldtime" flag is used, this key has a different
        # meaning:
        #
        #   Interpolate { <range-length> <interpos-offset> }
        #
        # <range-length> is the number of seconds it takes for one 
        # animation cycle to run from start to finish (Inter 0...1).
        # <interpos-offset> is added to the Inter calculated from world
        # time and <range-length> (offset should be 0...1). If the offset
        # is -1, a random offset is used for each object.

    Flags = "";
        # Flags for the whole model, including all the submodels.
        #
        # df_fullbright: The model is rendered with the maximum light
        #       level (corresponds sector light level 255) regardless
        #       of the sector it's currently in.
        #
        # df_shadow1: The model is rendered with 33% (?) translucency.
        #       When using this flag the value of the "Transparent"
        #       key is ignored.
        #
        # df_shadow2: The model is rendered with 66% (?) translucency.
        #       When using this flag the value of the "Transparent"
        #       key is ignored.
        #
        # df_brightshadow
        # df_brightshadow2
        # df_darkshadow
        # df_movpitch
        # df_movyaw
        # df_spin
        # df_skintrans
        # df_autoscale
        #
        # df_nointerpol: Disable model vertex interpolation.
        #
        # df_alignyaw
        # df_alignpitch
        # df_idskin
        #
        # df_noz: The model is rendered with Z-buffer writes disabled.
        #
        # df_nomaxz: Model is used at all distances regardless of the
        #        model visibility settings.
        #
        # df_selskin
        #
        # df_ptoffsub1: The center of submodel #1 is the spawn origin
        #        for particle generators.
        #
        # df_noptc
        # df_specular
        # df_litshiny
        #
        # df_idframe: An offset derived from the ID number of the object
        #        is added to the current frame index of the object. Frame
        #        range must also be set.
        #
        # df_idangle: The model gets a unique yaw angle offset calculated
        #        from the ID number of the object.
        #
        # df_notexcomp: Disable texture compression of all the skins of 
        #        the model associated with this definition.
        #
        # df_worldtime: Model's animation becomes a function of world 
        #        time. Changes the meaning of the Interpolate key. This is
        #        supposed to make it easier to animate objects with just
        #        one State.

    Skin tics = 0;
        # Skin cycle: this many tics for each skin.

    Scale = 1.0;
        # Scaling factor for the whole model (all submodels affected).
        # Uniformly sets *all* components of "Scale XYZ" to the specified
        # scaling factor.

    Scale XYZ { 1.0 1.0 1.0 };
        # Scaling factors for the whole model (all submodels affected).

    Resize = 0;
        # Automatic resizing to the given height. The whole model will
        # be scaled (only along the Y axis).

    Offset = 0.0;
        # Offset to model Y coordinate, applied when rendering.
        # Affects all submodels. Modifies the Y component of "Offset
        # XYZ".

    Offset XYZ { 0.0 0.0 0.0 };
        # Offset to model X, Y and Z coordinates, applied when
        # rendering. Affects all submodels.

    Sprite = "";
    Sprite frame = 0;
        # For autoscaling: specifies the sprite and frame to scale
        # things by. If not given, autoscaling is done based on the
        # sprite and frame associated with the State of this model.

    Shadow radius = 0;
        # With the default value of zero the shadow radius is
        # automatically calculated.

    Sub # Or Md2
    {
        # There can be eight Sub blocks in a Model definition.
        # Each block defines a submodel. You can use the keyword "Md2"
        # instead of Sub to begin the block.

        File = "";
            # MD2 file, e.g. "Monst\Trooper.md2". The given file name
            # is searched from all the directories specified in the
            # model search path. The skin of the model should reside
            # in the same directory with the model (not required,
            # though: it's enough that the skin is on the model path
            # as well).

        Frame = "";
            # Name of the MD2 frame to use.

        Frame range = 0;
            # Used with the df_idframe flag. Defines how many consecutive
            # frames make up the range for the frame index offset, which
            # is calculated from the object's ID.

        Flags = "";
            # Flags (df_*) that affect this submodel only. A XOR
            # operation is done with the flags that affect the whole
            # model.

        Skin = 0;
            # The index number of the skin to use.
            
        Skin range = 0;
            # Size of the skin cycling range. The first skin in the
            # range is the one specified by Skin, and the last one is
            # (Skin) + (Skin range) - 1.

        Skin file = "";
            # Optional: File name of the skin. This can be any image file
            # on the model path. If a skin file is specified, the skin 
            # number is ignored.

        Offset XYZ { 0.0 0.0 0.0 };
            # Offset to submodel X, Y and Z coordinates, within the
            # model.

        Transparent = 0.0;
            # Translucency of the submodel: 0=opaque, 1=transparent.
            # The level of translucency defined here is not used with
            # df_shadow1/2 or dr_brightshadow.

        Shiny skin = "";

        Shiny = 0.0;

        Shiny color { 1.0 1.0 1.0 };

        Selskin mask = 0;
            # df_selskin chooses the skin to use by looking at the
            # high byte of the selector integer. The selskin mask
            # specifies which bits of the selector special byte should
            # be considered for df_selskin.

        Selskin shift = 0;
            # After doing an AND operation with the selskin mask, the
            # resulting value is shifted to the right this many bits.
            # Negative values shift to the left.

        Selskins { 0 0 0 0 0 0 0 0 };
            # At most 8 skin numbers for df_selskin. After the special
            # byte is AND'd with the selskin mask and shifted, the
            # result is an index to this list. If the df_selskin flag
            # is set for the model, the skins in this list are used.

        Parm = 0.0;
            # Custom parameter.
    };
}

...........................................................................

Shortcuts:

* Use "Copy Model" (or "*Model") whenever possible.

* Use hyphens (-) to indicate that the previous value of the same Key
  should be used (if "Copy" was not used).

* Use ModelPath to add new model search paths. This makes it unnecessary to
  include the path in Model:Md2:File (or skin file names).


---------------------------------------------------------------------------
Doomsday Engine Definitions Reference
