The SNDSEQ lump

DOOM had sounds for different events such as moving platforms and crushing ceilings hard-wired into the code. ZDoom uses the more flexible approach of Hexen and allows you to define different sound sequences in a SNDSEQ lump. Like ANIMDEFS and SNDINFO, this is just a regular text lump that you can edit with a text editor. SNDSEQ lumps are also cumulative, so you can have two SNDSEQ lumps in your wad, and they will both be used.

Sound sequences can be assigned to two different classes: doors and platforms. Door sounds are used for doors and moving polyobjects, and platform sounds are used for everything else that involves a moving sector. In addition, you can create sequences that belong to neither class and are only accessible through the ACS soundsequence command.

By default, which sound sequence is played when a sector moves is determined by the special used to activate the sector. You can override this behavior by placing one of the sound sequence things (1400-1411, see section 12, thing types) in the appropriate sector or by using the Sector_ChangeSound special to change the sector's sound sequence after the level has been loaded.

Sound sequences are defined using a simple, yet powerful language. Each sequence begins with a colon followed by the sequence's name and ends with an end command. Between them can be any number of commands to control how sounds are played. The general format of a soundsequence is:

:SequenceName
    Command 1
    Command 2
    Command 3
    ...
end

Unless you plan to only use the sequence with the soundsequence command, you should also have a door or platform command (if not both) to assign it at least one ID. The commands that are understood are summarized below:

play <sound>
Plays the specified sound.
playuntildone <sound>
Plays the specified sound and waits for it to finish before continuing to the next command.
playtime <sound> <tics>
Plays the specified sound and waits for the specified number of tics before continuing to the next command.
playrepeat <sound>
Plays the specified sound continuously until the sound sequence is stopped. Any commands after this one (other than stopsound) are ignored.
playloop <sound> <tics>
Plays the specified sound repeatedly, waiting for a specific number of tics to elapse before restarting the sound. If tics is longer than the amount of time taken to play the sound, this command works just like playrepeat. Like playrepeat, this command only ends when the sound sequence does.
delay <tics>
Waits for the specified number of tics before continuing to the next command. During this time, the current sound will continue to play but will not loop if it ends before the delay period.
delayrand <min> <max>
Waits for a random number of tics before continuing to the next command.
volume <amount>
Sets the volume level this sequence will play any later sounds at. Valid volumes are in the range 0-100, with 100 being the default.
stopsound <sound>
Specifies a sound to be played when the sequence is stopped. This command also halts further execution of the script, so it should be the last command to appear just before the end statement.
nostopcutoff
Use this if you don't want any specific sound to be played when the sequence is stopped, but you also don't want the currently playing sound to be abruptly halted. This is mutually exclusive with stopsound, so you can use only one or the either.
attenuation <type>
Specifies how later sounds played by this sequence are attenuated. The following are possible attenuations (with idle being the default):
normalSound is treated just like a normal sound
idleLike normal, but with lower priority
staticSound diminishes very rapidly with distance
noneSound is heard full volume across the entire level
surroundSound is heard full volume but is played in surround
door <id> ...
Assigns this sound to a door class. <ID> is a number between 0 and 63 inclusive that is used to identify the sound when you define polyobjects or assign a sector a non-default sound. A single sequence can be assigned to multiple IDs by specifying more than one ID on the line.
platform <id> ...
Assigns this sound to a platform class. <ID> is a number between 0 and 63 inclusive that is used to identify the sound when you assign a sector a non-default sound. A single sequence can be assigned to multiple IDs by specifying more than one ID on the line.

Door and platform IDs are considered distinct IDs, so one sequence could be assigned to door ID 0, and another could be assigned to platform ID 0. Which of the two sequences is played depends on which special is used to activate the associated sector or polyobject. Polyobjects always play a door sequence when they move. The various Door_ specials also play door sequences. All the other sequences play platform sequences. If you want a single sequence to be played for a specific ID no matter how it is activated, you should use both a door and platform command and assign it the same ID(s) with both of them.

Here is a sample (and not especially useful) soundsequence:

:ScaryDoorSound
    door            0
    playuntildone   cyber/sight
    playrepeat      cyber/hoof
    stopsound       cyber/death
end

This sound can be attached to a sector with the 1400 things or a Sector_ChangeSound (tag, 0) special, and will be played whenever the sector opens or closes as a door. When the door starts moving, it will play the cyberdemon's sight sound. While the door continues moving, it will play the cyberdemon's hoof sound, and when the door stops, it plays the cyberdemon's death sound. Thus, it's not a very useful door sound, but it does demonstrate how sound sequences are used.