header general

Tutorials

Things you might want to know

Welcome to the Realm667 tutorial section. Here, you'll find a variety of guides catering to all skill levels. Whether you're a pro or a newbie in Doom editing, there's something here for you. If you're looking for a tutorial on a specific topic, just let us know, and we'll find or create one for you.

  • Alternate Fire/Reload/Zoom/...States on Weapons
    Thanks to WildWeasel for teaching me a non-ACS way of doing this. I've been meaning to write this for ages, but never got around to it.

    One of the more obscure tricks with weapons is the ability to add a new firing state (a state that can be activated aside from primary and alternate fire). This is usually used to have a key that specifically zooms or reloads. However, this is actually quite a simple trick.

    For reference, here are three wiki pages:


    I'll put it in basic terms, then explain each part further. Essentially, you have a dummy inventory item as a flag for the weapon to check for in the Ready state, and this item is given and taken away by a pair of CustomInventory items which are bound to a key.

    I'll use a third Fire state as an example. To explain further, we start with our fake inventory item; an item that literally has
    no use besides A_JumpIfInventory to check for:


    Actor IsFiring : Inventory
    {
      Inventory.Amount 1 //This doesn't technically need to be here but it's better to make sure
      Inventory.MaxAmount 1
      -INVBAR //Keeps it from displaying in the inventory bar, but you don't have to worry
      States
      {
      Spawn:
        TNT1 A 1
        Fail //Keeps it from really doing anything in the world
      }

    All this will do is sit in your inventory. Now we have an alternate pistol checking for this:

    Actor Pistol2 : DoomWeapon 5010 //Named differently so it won't conflict with Doom's
      {
      Game Doom
      Weapon.SelectionOrder 1900
      Weapon.AmmoUse 1
      Weapon.AmmoGive 20
      Weapon.AmmoType "Clip"
      AttackSound "weapons/pistol"
      Obituary "$OB_MPPISTOL"
      +WEAPON.WIMPY_WEAPON
      Inventory.Pickupmessage "$PICKUP_PISTOL_DROPPED"
      Decal BulletChip
      States
      {
      Ready:
        PISG A 0 A_JumpIfInventory("IsFiring", 1, "AltAltFire") //We're checking for the fake inventory item
        PISG A 1 A_WeaponReady
        Loop
      Deselect:
        PISG A 1 A_Lower
        Loop
      Select:
        PISG A 1 A_Raise
        Loop
      Fire:
        PISG A 4
        PISG B 6 A_FirePistol
        PISG C 4
        PISG B 5 A_ReFire
        Goto Ready
      AltFire: //Because why not, we're already using altfire!
        PISG A 4
        PISG B 6 A_FirePistol
        PISG C 4
        PISG B 5 A_ReFire
        Goto Ready
      AltAltFire:
        PISG A 4
        PISG BBB 0 A_FirePistol
        PISG B 6 A_FirePistol //Fires four times so we know it's working
        PISG C 4
        PISG B 5 A_ReFire
        Goto Ready
      Flash:
        PISF A 7 Bright A_Light1
        Goto LightDone
        PISF A 7 Bright A_Light0
        Goto LightDone
      Spawn:
        PIST A -1
        Stop
      }
    }

    There! Our pistol is checking for that item, and has a new firing state. Now we just need those two CustomInventory items:

    Actor Action_Fire : CustomInventory
    {
      Inventory.Amount 1
      Inventory.MaxAmount 1
      -INVBAR
      States
      {
      Use:
        TNT1 A 0 A_GiveInventory("IsFiring", 1)
        Fail // It's important that these items end in "Fail" instead of "Stop" or else they are removed from inventory as soon as they are used. Fail will keep them in your inventory.
      }
    }

    Actor Action_FireCancel : CustomInventory
    {
      Inventory.Amount 1
      Inventory.MaxAmount 1
      -INVBAR
      States
      {
      Use:
        TNT1 A 0 A_TakeInventory("IsFiring", 1)
        Fail
      }
    }


    When Action_Fire is used, it will give the fake item, but when Action_FireCancel is used, it will take it away again. Thus, using one will make the pistol fire, and the other will make it stop. It is important that both of these are given to the player at the start with Player.StartItem, or this will not work.

    Now to bind these two items to a key:

    AddKeySection "Your Section Name" YourSectionsName
    AddMenuKey "Alternate AltFire" +altaltfire
    Alias +altaltfire "Use Action_Fire" // + events occur when the key is pressed.
    Alias -altaltfire "Use Action_FireCancel" // - events occur when the key is released.
    DefaultBind x +altaltfire // only the + event needs to be bound.


    Check the wiki link above about adding keysections for explanations of what these do. Now, when the key is pressed it will give the item (activating AltAltFire), and when the key is released, it will take the item away (making it stop firing).

    And it's that simple! If you want to test it out, here's a full Decorate and KeyConf:

    Actor Pistol2 : DoomWeapon 5010 //Named differently so it won't conflict with Doom's
      {
      Game Doom
      Weapon.SelectionOrder 1900
      Weapon.AmmoUse 1
      Weapon.AmmoGive 20
      Weapon.AmmoType "Clip"
      AttackSound "weapons/pistol"
      Obituary "$OB_MPPISTOL"
      +WEAPON.WIMPY_WEAPON
      Inventory.Pickupmessage "$PICKUP_PISTOL_DROPPED"
      Decal BulletChip
      States
      {
      Ready:
        PISG A 0 A_JumpIfInventory("IsFiring", 1, "AltAltFire") //We're checking for the fake inventory item
        PISG A 1 A_WeaponReady
        Loop
      Deselect:
        PISG A 1 A_Lower
        Loop
      Select:
        PISG A 1 A_Raise
        Loop
      Fire:
        PISG A 4
        PISG B 6 A_FirePistol
        PISG C 4
        PISG B 5 A_ReFire
        Goto Ready
      AltFire: //Because why not, we're already using altfire!
        PISG A 4
        PISG B 6 A_FirePistol
        PISG C 4
        PISG B 5 A_ReFire
        Goto Ready
      AltAltFire:
        PISG A 4
        PISG BBB 0 A_FirePistol
        PISG B 6 A_FirePistol //Fires four times so we know it's working
        PISG C 4
        PISG B 5 A_ReFire
        Goto Ready
      Flash:
        PISF A 7 Bright A_Light1
        Goto LightDone
        PISF A 7 Bright A_Light0
        Goto LightDone
      Spawn:
        PIST A -1
        Stop
      }
    }

    Actor IsFiring : Inventory
    {
      Inventory.Amount 1 //This doesn't technically need to be here but it's better to make sure
      Inventory.MaxAmount 1
      -INVBAR //Keeps it from displaying in the inventory bar, but you don't have to worry
      States
      {
      Spawn:
        TNT1 A 1
        Fail //Keeps it from really doing anything in the world
      }
    }

    Actor Action_Fire : CustomInventory
    {
      Inventory.Amount 1
      Inventory.MaxAmount 1
      -INVBAR
      States
      {
      Use:
        TNT1 A 0 A_GiveInventory("IsFiring", 1)
        Fail // It's important that these items end in "Fail" instead of "Stop" or else they are removed from inventory as soon as they are used. Fail will keep them in your inventory.
      }
    }

    Actor Action_FireCancel : CustomInventory
    {
      Inventory.Amount 1
      Inventory.MaxAmount 1
      -INVBAR
      States
      {
      Use:
        TNT1 A 0 A_TakeInventory("IsFiring", 1)
        Fail
      }
    }

    Actor DoomPlayer2 : DoomPlayer
    {
      Player.StartItem "Pistol2", 1
      Player.StartItem "Clip", 50
      Player.StartItem "Fist"
      Player.StartItem "Action_Fire", 1
      Player.StartItem "Action_FireCancel", 1
    }


    KeyConf:

    ClearPlayerClasses
    AddPlayerClass DoomPlayer2

    AddKeySection "Your Section Name" YourSectionsName
    AddMenuKey "Alternate AltFire" +altaltfire
    Alias +altaltfire "Use Action_Fire" // + events occur when the key is pressed.
    Alias -altaltfire "Use Action_FireCancel" // - events occur when the key is released.
    DefaultBind x +altaltfire // only the + event needs to be bound.


    Keep in mind, by the way, Fire and AltFire have some special behavior that alerts monsters, and A_Refire only works for Fire/Hold and AltFire/AltHold. Here's another AltAltFire that emulates that behavior:

    AltAltFire:
        PISG A 4 A_AlertMonsters //Because it alerts monsters as soon as the state is entered.
        PISG BBB 0 A_FirePistol
        PISG B 6 A_FirePistol //Fires four times so we know it's working
        PISG C 4
        PISG B 5 A_JumpIfInventory("IsFiring", 1, "AltAltFire") //Fire again if the button is still pressed, like A_Refire.
        Goto Ready

    Read Tutorial

  • Anatomy of a Cutscene

    The screen is dark and all you hear is the crackling static of a radio receiver in its last throes. Slowly the screen brightens in a classic fade-in to reveal a scene of carnage and destruction. Suddenly, a shadow darts across the screen and the camera moves to follow it. Ominous music pipes in, softly at first, but growing to a crescendo as the camera reaches a breach in the wall. A city street stretches out below, buildings along it lying in ruins and utter devastation. The camera slowly drops to street level and pans around. You hear the sound of heavy, belabored breathing, and the camera swings in the direction of the sound. Suddenly a scream rings out, and the camera lens is splattered with drops of crimson as you hear the sound of a body hitting the pavement. The music peaks just in time to show you a vast, indistinct shape shambling away into an adjacent alley. Words and a logo zoom out onto the screen, but you are cringing at the horror of it all, and for a moment you can't make sense of the words. "ATTACK OF THE KILLER FIENDS", they announce. The scene fades to black but the title remains on the screen. You breathe a sigh of relief as you press the 'ESC' button to bring up the menu. All is safe with the world. It's only a game after all.

    Anybody who's played a modern computer or console game has seen one - the ubiquitous cutscene. Used for everything, from providing a story's introduction to filling in pieces of the action that cannot be left to the player to control, cutscenes serve a myriad of purposes. As outlined by the fictitious scenario in the paragraph above, it is used as a means to set up the "back story" and to create the appropriate mood. It can be used for mission briefings, where the player can benefit from basic information about the game and its objectives. It can be used to show the player the effect of his/her actions in a distant, remote part of the game. It can be used to advance the plot, provide clues, and promote character development. Finally, it can be used to provide a dramatic conclusion when the player has successfully completed all objectives. Cutscenes are an important tool in a game-developer's kit, and when used skillfully they can create a dynamic environment in the player's sand-box.

    There are two key elements in the creation of a cutscene - aesthetics and mechanics. Aesthetics are, largely, subjective and a matter of taste. Therefore, I'll only provide some basic guidelines on what this constitutes. Or, more accurately, I'll provide some guidelines on what I think it constitutes. Mechanics, on the other hand, are more easily established, and I'll provide step-by-step instructions on how to achieve some common cutscene effects.

    A. Aesthetics of a Cutscene

    The aesthetics aspect of a cutscene revolves around the mood you wish to create, and your desire to hold the player's interest. Here are some pointers, all of which pertain more to cinematography than map-building:

      1. You'll want to make the cut-scene visually appealing, so make sure that the scene is one that is suitably lit. By that I don't necessarily mean "brightly-lit"; lighting should be adequate to illuminate the scene so that the player can obtain whatever visual cues you wish to convey, while creating the proper atmosphere. Use dynamic lighting if your game engine permits (e.g., GZDooM).
      2. Select an area of your game that shows off some interesting architecture or other map feature. While the "action" may be occurring in the foreground, the player's eyes are likely to wander, and there's plenty to gain by showing off maximum eye-candy, especially during an introductory cutscene.
      3. You'll want the cut-scene to be dynamic, so make full use of moving cameras (traveling along all three axes as appropriate) and switching cameras. [More on moving cameras in the section on Mechanics.]
      4. Use close-ups of characters or objects, zooming in or out as appropriate.
      5. Use character or object motion as appropriate, allowing your camera to pan with the motion. GZDooM allows "moving" models, and both GZDooM and ZDooM allow characters (also known as "actors") to walk along a specified path, and pause at specified points; you can even create fight sequences by scripting battles between actors. These all serve to create a visually-arresting scene that is more likely to hold the player's attention.
      6. Use fade-in and fade-out to transition from one camera to the next, as appropriate.
      7. Avoid keeping the camera fixed at one spot for more than a few seconds. My rule of thumb for real-life videography is to record no single shot for more than 10 seconds - I can easily use a video editing program to stitch together various scenes for a longer sequence if necessary, and shorter "shots" tend to be more exciting.
      8. Use sound effects and music to enhance the atmosphere.

    B. Mechanics of a Cutscene

    There are seven common tools you can use in a cutscene, and each of these is already built into ZDooM. As such, you won't need to insert your own resources into your game if you so choose. These tools are:

    The first three items all pertain to "cinematography" - types of cameras, switching cameras, and causing cameras to "travel". The fourth item is required if you want actor movement where the actor needs to be animated. The fifth allows you to move an actor (such as an enemy or model) along a path. [Enemies become dormant when propelled by an Actor Mover.] The sixth is useful for mission briefings and other instances when messages need to be conveyed to the player. Action Code Script, or ACS, is the language that ZDooM (and each of its derivatives) uses to create various effects. Please read the articles to which those items have been linked, and become familiar with them.

    There are four steps to developing your cutscene [which I have cheesily named the "4P Method"]: Planning, Placement, Programming, Playing. Let me first outline what these steps are and their importance in creating the right effect. After that I'll illustrate with some examples.

      1. Planning:The more complex you want your cutscene to be, the more important it is to plan the sequence of events you'll be recording. Even simple cutscenes require basic decisions. Where should the camera face? Should the camera be stationary or moving? Will it be necessary or desirable to use more than one camera? At what height should the camera be placed for optimal viewing of the scene? Will the actors be stationary of moving? What sound effects should you use? When should message text be displayed, and for low long should it be displayed? The answers to these questions will depend on what the purpose of the cutscene is, and how dynamic you want it to be. Mission briefings will typically involve keeping one or more cameras on a single actor, and will involve fewer "maneuvers". A battle scene will be considerably more complex, involving several actors that will need to perform specific actions. An introductory camera "fly-by" could be equally involved, with a lot of "background action". Therefore, it will probably benefit you to plan each "shot".

      2. Placement: Once you've planned out your scene you'll need to begin putting your "pieces on the board". The four main types of pieces are actors, cameras, interpolation points, and patrol points. Use your plan to place your various pieces into the appropriate positions. Keep in mind that you have three dimensions to work with, so make sure you take advantage of height variations, especially for your cameras. For example, during a mission briefing you can start your camera near the ceiling as it faces the principal actor. As the briefing begins the camera could slide down to a few feet above the ground before moving forward to zoom in on the actor. If there are actors that need to be moving (e.g., an enemy or a model) you'll need to position your Patrol Points and Actor Movers.

      3. Programming (scripting & specials): If your "pieces" are the automobile, your scripting is the driver of the automobile. It tells the pieces when to start, when and where to move, when to turn, and when to stop. The specific lines of code you use will depend on the nature of the cutscene. In most instances you'll need to "freeze" the player so that s/he is unable to move independently and interfere with the action. Accordingly, you'll need the SetPlayerProperty function. You can "unfreeze" the player later, as appropriate. But until then you will need to begin the process of letting the dominoes fall. The first step in that process is "changing" your camera and activating it using the Thing Activate function. [Optionally, you can fade into the scene using the FadeTo function before you activate the camera.] Finally, you fade back into the scene.

      So far, all you've done is changed the scene to a remote camera and activated it. Now you need to trigger the events of your cutscene. If you've set up your first camera to be a moving camera, you'll have also set up your sequence of interpolation points. This, then, becomes a "fire-and-forget" device that proceeds automatically, and does not require further manipulation. Keep in mind that setting up your interpolation points is not a trivial task; distance between points, height of points, angle the point faces, and speed between points [travel time] will all determine how smooth and dynamic your camera movement will be. If you're doing a mission briefing you'll begin displaying the heads up display (HUD) text or begin a sound recording, or both. [You can use ThingSound to start the audio portion of the briefing.] If all you're doing is a "static" mission briefing, where the briefer is stationary, beyond this point you'll simply need to change cameras as appropriate, fade out when the briefing is complete, change cameras back to the player, and unfreeze her/him.

      If you are doing a more complex cutscene, such as a battle scene or a fly-by, you'll need to activate your actors in addition to your cameras. Much of the actor behavior will already have been determined in the Planning, and Placement stages of setting up your scene. To move and animate actors, you'll need to use patrol points to designate the path your actors will take. This method is ideal for enemies, non-combatant actors (e.g., scientists), and other things that have animated frames and behavior. If you just want to move an actor without animating it (e.g., a model of a tram that runs on an electrified rails and without wheels) use an actor mover. You can use this method for any type of actor, but if it's not a model the actor will be moved without any of the inherent animation that is part of its normal behavior; use the patrol point method if you need the sprite animations. If it's a model, the actor mover will move it along the path and all the associated animations will work. For example, if your actor is a model of a helicopter, and the model definition includes turning rotor blades, the helicopter will appear to move forward (or backward/upward/downward as you define) while its blades rotate. Finally, if you want events to happen after the cutscene begins, you can script them using ACS. If you want these events to be triggered when the camera reaches a specific point, use Interpolation Specials. For example, you may want music to begin when the camera has reached a specific point. Set up an interpolation special at that point, then use it to trigger a script that starts the music.

      4. Playing (testing): Once you've implemented the first three of the 4P steps, you'll need to test your work. In reality, however, you'll probably test the various pieces of your cutscene more-or-less continuously during the development phase. The key things you'll want to make sure of are the following:

        1. Cameras are activated at the right moment.
        2. Cameras are facing the correct direction.
        3. Moving cameras are traveling along the proper path.
        4. If both audio and HUD text are used for mission briefings, the two are properly synchronized.
        5. Actors begin moving when they are supposed to, and not before or after.
        6. Actors properly follow their paths or the actor movers.
        7. Other effects (e.g., sounds, music, lighting) are appropriately activated.

    C. Making a Cutscene Optional

    Whenever possible, especially whenever the viewing of the the cut-scene is not necessary for the player's advancement within the game, provide the player a means to skip the cut-scene. Watching a cut-scene may be enjoyable the first time, but if a player goes back and plays the map again s/he may not be interested in sitting through it again. There are several ways by which you can allow a player to skip a cutscene. [However, keep in mind that some cutscenes may be required in order to move the action or story along, and it may not be desirable (or even possible) to make these portions skippable.] The method you use to allow players to skip cutscenes will, to some extent, depend on the type of cutscene:

      1. Introductions: You've seen the clever cinematics at the beginning of games where the camera swoops down from the sky and circles around a gothic-looking castle, skimming the surface of a moat under a curved bridge, before soaring heavenward again as the music thunders to its conclusion. This type of scene is an effective way to advertise your game, essentially by showing cool stuff right off the bat. In (G)ZDooM you can achieve this effect by creating a TITLEMAP. A TITLEMAP has the advantage of being skippable at any point - the MENU is pulled up as soon as the player presses any key - but also allows the cutscene to be as long or as short as the game author wishes it to be.

      2. Mission Briefings: Mission briefings pose a problem of being (generally) required the first time a game is played, but not necessary after that. One way to give the player the option of accepting the briefing or skipping it, is to create two "paths" before that point. The first path will go to the briefing, while the second path will by-pass it. If the briefing is at the beginning of the game, you can simply present the player with two switches - one for the briefing, one to skip it. If you wanted to make the choice more "realistic", you could have a corridor at the game start that leads to the briefing room (and a sign that says "Briefing Room" could be posted outside). The corridor could branch off at the door, continuing to the rest of the game, thereby not requiring the player to enter the briefing room.

      Alternatively, if you wanted the mission briefing to begin automatically, you can silently teleport the player to a remote 64x64 sector after the camera has been activated. The wall that the player faces has an ACS trigger that, when "used", ends the briefing, teleports the player back to her/his original location, and changes the camera back to the players point of view (POV). In this way, the player can exit the briefing at will. [This same effect can be achieved by having the ACS trigger at the player's original location, but the risk is that the player may not activate the trigger during the briefing, but may inadvertently do so afterwards, resulting in unintended consequences. It is possible to nullify the trigger using ACS, and if you are comfortable enough with the use of variables, this method will work just as well for you.]

      3. Other Cutscenes: The same method that works for skipping mission briefings after they have started will also work for other types of cutscenes. Simply provide the player with an ACS trigger that will terminate the cutscene and return the player to the game. (G)ZDooM allows even a totally frozen player to "use" switches, etc.

    D. An Example of a Mission Briefing

    Mission briefings are generally the simplest types of cutscenes to develop. Let's look at the key blocks of code in an example. [Incidentally, this example is from Paranoid, a Half-Life mod for GZDooM.] The first picture below is the scene where the mission briefing occurs. You see the model of the briefer, the desk and other office accoutrements, and the two cameras. The second picture is from the map editor, and it shows the layout of the scene; the notes indicate what each thing is.

    cutscene1 cutscene2

    Now let's look at the scripting that went into creating the mission briefing:

    //****
    // Script 11: Mission Briefing & begin game
    //****

    script 11 (void)
    {

      SetPlayerProperty(1, 1, PROP_TOTALLYFROZEN);
      FadeTo (0, 0, 0, 1.0, 3.0);
      delay(const:35*4);
      ChangeCamera (255, 0, 0);
      Thing_Activate(255);
      fadeto (0, 0, 0, 0.0, 3.0);
      [Remainder of script, see below]

    This triggers the following sequence: the player freezes, the screen fades to black in 3 seconds, the players point of view changes from the normal in-game mode to the particular camera for the cutscene (tag ID = 255), the camera is activated, and the scene being captured by the camera fades into view in 3 seconds.

    Meanwhile, camera with thing identification (TID) of 255 has been set up as a moving camera at zheight = 152, is bilinear (camera will adjust its angle to match those of the points it passes), and will move to interpolation point with TID = 254. Interpolation point (IP) with TID = 254 has the same x, y, and z coordinates as the camera, is pointing to IP with TID = 253, and has a travel time of 64 tics to that IP, which is at zheight = 128 and slightly forward of the camera start point. This means that, upon being activated, the camera will slowly float down towards the floor before moving forward to the next IP.

      [Continued from script, see above]
      delay(const:35*8);
      ambientsound ("radiostatic", 127);
      delay(const:35*2);
      ThingSound (19, "BRIEF01", 127);

      SetHUDSize (640, 480, 1);
      SetFont ("confont");
      HUDMessage (s:"Dr. Bellmer, this mission briefing will serve to instruct you\non your primary and secondary objectives.";
      HUDMSG_TYPEON | HUDMSG_LOG, 2, CR_GOLD, 30.1, 200.1, 0.5, 0.07, 1.0);
      delay(const:35*8);
      [Remainder of script, see below]

    This section begins with a sound being triggered, signalling that the briefing is about to begin. This is a useful device that adds a touch of realism, but is entirely optional. Following that, the audio portion of the briefing starts. You'll need to include a sound file in your game and set up the sound definitions, but that's the subject of a different discussion. In this example, the mission briefing also includes a HUDMessage that simply transcribes the audio portion. You can choose to use only the audio, or only the HUDMessage, or both.

    Meanwhile, the camera has moved to its "destination" IP. In this example, the IP is positioned at an actual camera model that the player can see as the POV approaches it. Again, this is simply a device to provide some realism, and is not required.

      [Continued from script (some lines omitted), see above]
      ChangeCamera (249, 0, 0);
      delay(const:35*1);
      ThingSound (19, "BRIEF02", 127);
      HUDMessage (s:"Your primary objective is to damage their information systems so that data\nrecovery is difficult and time-consuming.";
      HUDMSG_TYPEON | HUDMSG_LOG, 2, CR_GOLD, 30.1, 200.1, 0.8, 0.08, 1.0);
      delay(const:35*10);
      [Remainder of script, see below]

    After the briefing has gone on for a little while, you should consider changing cameras to lend a touch of dynamism to the proceedings. In this example, the camera changes to a fixed cameraoff to the side, and which is pointing at the briefer. The second audio section of the briefing then begins, and the transcribed test is displayed. The reason to split the audio file into two or more files is that it allows better control of the synchronization of audio, HUDMessages, and camera movement.

      [Continued from script (some lines omitted), see above]
      ChangeCamera (255, 0, 0);
      delay(const:35*1);
      ThingSound (19, "BRIEF04", 127);
      delay(const:35*1);
      HUDMessage (s:"Periodically, during your mission, you will receive transmissions from me.";
      HUDMSG_TYPEON | HUDMSG_LOG, 2, CR_GOLD, 30.1, 200.1, 0.4, 0.05, 1.0);
      delay(const:35*6);
      [Some lines omitted]
      ambientsound ("radiostatic", 127);
      fadeto (0, 0, 0, 1.0, 3.0);
      delay(const:35*4);
      ChangeCamera (0, 0, 0);
      SetPlayerProperty (1, 0, PROP_TOTALLYFROZEN);
      fadeto (0, 0, 0, 0.0, 3.0);
      }

    As before, after some more of the briefing, you should change the camera again. In this instance, the camera has been changed back to the original moving camera while the last audio and HUDMessage portion of the briefing is delivered. Finally, the radiostatic sound is played to signify the end of the briefing, and the scene fades to black. The camera is changed back to the player's POV, the player is unfrozen, and the scene fades back in.

    Admittedly, this is a rather involved mission briefing, and you can achieve the same result without the manipulations described here. However, this example illustrates the richness and diversity of effects that you can employ to create an attractive cutscene. The principles used in this example are virtually the same as those for other, more complex cutscenes. Even though you may use more actors, have more frequent camera changes, or implement more sound & light effects, the toolbox defined in the discussion above will allow you to execute a slick and professional-looking cutscene.

    Read Tutorial

  • Balancing Monsters
    Here's a subject apparently few users grasp sufficiently: Balance.

    Balance mostly deals with different factions in strategy games like Starcraft or Age of Empires, where each faction has its own strengths and weaknesses, but they have to remain balanced on the stereotypical scale. If one faction is too powerful, then that scale tips and the game is unbalanced. Balance issues are not always clear; it takes testing in real game conditions to make sure, but it is worth the work to make sure a game or mod is the best it can be. Blizzard Entertainment tweaked Starcraft 1 for years to make sure it was balanced, and it appears they're doing the same with Starcraft 2.

    In first-person shooters, things aren't any easier to see if they're balanced. How do you decide a weapon does too much damage? Or if a monster has too much health? What are you balancing it against? In a multiplayer game like Quake 3, you balance it with the other weapons; because each item is readily available, they should be equally useful in general. In a single-player game like Doom, you balance it according to a progressing staircase. Some monsters are more powerful than others, according to this staircase. Let's look at the basic Former Human, Imp, Hell Knight, Baron of Hell and Cyberdemon. At the bottom of this staircase is the Former Human; it's very weak, almost incapable of killing the player, and usually placed in groups. Imps are a bit more powerful but dodgeable, and still common because it's not very strong. The Hell Knight, however, is much more damaging. Just as dodgeable, but it also has more health to deal with. These are rarer than imps. Barons are the same as Hell Knights, but double the health, so it stands to reason these would be rarer. Cyberdemons have a whopping four times the health of a Baron and is capable of one-shotting the player. It's obviously a boss.

    There are two ways to see if something truly fits into this staircase; the first is seeing if it fits the difficulty the monster was intended for. Was the imp meant to be a common weakling? Was the Cyberdemon meant to be a boss? If the answer to these questions is yes, then very good. The second thing to make sure of is to see if this balance is actually FUN. Play Nuts.wad without any cheats, gameplay mods or anything like that. Is that fun?

    There are several factors that go into the difficulty of a monster. Health and damage being the most obvious. Then there are numbers of attacks, type of attacks, speed of attacks, movement speed, gimmicks, rarity and situation. I will say first that you DO NOT EVER balance one extreme with another. If a monster has an insta-kill hitscan attack, and one health, that's not fun! It's either a pushover, or too damn frustrating! Glass cannons are stupid to fight. Yes, I'm guilty of making one (The Repeater Zombie), but recently I have rebalanced it quite a bit. If an attack does 500 damage, but moves so slowly that an ant will outrun it, that's not fun, that's not balanced, that's just stupid.

    Health and damage are the two most common ways of balancing a monster. The original Doom used these because primarily because Id didn't have a lot of other gimmicks to add. Think of the Imp and Baron of Hell. Functionally, they're exactly the same. The only difference is health and damage. Another common one is the type of attack; projectile versus hitscan. Projectiles are dogable, so they should do more damage, whereas you can't dodge hitscan, you have to rely on luck to avoid damage. Random spreads are sometimes used for balancing hitscans, but remember that with projectiles launched with a random angle, it's possible to dodge into the attack.

    Speed is another balancing factor, but not just the movement speed of the monster. There's also attack speed (how quick between attacks, how short the delay before it attacks) and projectile speed. Revenants are quick, and that makes them tricky to hit sometimes, which balances their low health. Arachnotrons also have a short delay between attacks, but there's a delay before they fire that you can take advantage of, either to duck behind cover or to interrupt them. Don't make something too fast that it's silly, though; speed is one of those things that can look downright hilarious if something is too fast or too slow.

    Gimmicks are the hardest things to get right, because it's all unique. By gimmick, I mean some unique feature in the monster that doesn't fit into any other category. It could be the Archvile's resurrection ability, or the Revenant's homing rockets. The only way these can really be balanced is with proper testing.

    Keep in mind graphics go into balance as well. If a monster doesn't look powerful, it's not going to be well-received when it takes away 75 health with one attack. Often, it's best to decide where it goes in the progression of difficulty simply by how it looks and plan around that. The Banshee in the Beastiary right now (as of 12/07/11, it may get updated) doesn't look or sound like the horrible powerhouse it is. It doesn't make sense for the weakest monster in a mod to have more special effects than the final boss, as well. Also, taking existing, weak monsters and suddenly making them more powerful isn't a great idea, either, since you're messing with the player's expectations, which is really frustrating to the player. An imp with 800 health that throws rockets is rather silly.

    The total number of attacks a monster has, while it doesn't necessarily make a monster unbalance, goes into the overall quality of the monster as well. Weaker monsters don't need a lot of attacks, especially since they'll be dead before the player sees all of them. Bosses benefit from having several unique attacks, but it doesn't make a boss. Make sure the attacks the monster has are used to best effect, and that they aren't thrown in just because.

    For the purposes of the R667 Beastiary, you don't have to worry about rarity and situation, but you have to keep it in mind for testing your monster. The best way I've thought of to test situation is to replace a monster in an equivalent place in that staircase of difficulty and test out some real maps. When you test a monster by summoning it, you're setting the conditions. You're deciding what weapons you have when you fight it, how much health and armor you have, how large the area is, how much cover you have. In general, these conditions really suck for testing monsters because you aren't seeing how they work in real gameplay. I admit, I like to hit Give All and test monsters out by going to the middle of Doom 2 Map13 (Or Heretic E3M3, depending on what game it's intended for) and summoning the monster in question, but I've been doing this a while and I can keep in mind how different the situation could be. Also, if you gear a monster for a specific situation and are concerned a modder might place it in a map in a situation where it's too tough or too weak, say what it's intended for in the Info lump. That way, it's the modder's fault and not yours!

    Also, keep in the mind the skill of people playing. People don't play in the same exact way you do, and if you made the monster, you already have an advantage over those other players because you know what to expect, just like if you made a map you know where all the monsters and secrets are. Will the average player find this fun? It's okay to gear something towards more experienced players, but just bear in mind the community in general. This is good advice for anything you do in modding, whether it's making a monster, a weapon, or a map pack.

    Hopefully, this tutorial helps people. At the very least, it'll give me something to point monster makers to when they submit a really fast monster with 40 health that does 140 damage with fast, homing attacks. This is geared towards monsters, but some of the principles (balancing one extreme with another, for example) carry over into weapons.

    Read Tutorial

  • Basics of Design and Gameplay

    DooM editing is an incredible outlet for creative energy, limited only by your imagination. Here are a few things I've learned along the way; perhaps they'll be of some use to you.

    1. Start small, but stay ambitious. Think of your first few levels as a training ground, where you learn the basics and become familiar with the tools. Beginners sometimes get carried away and bite off more than they can chew -- going for a 32-level megawad TC with new graphics, sounds, music, etc. is best left for a team, or for someone that's been around the editing block a few times.

    2. Write down your ideas and draw out sections (or all) of your map. This will give you a sense of your scale. Avoid large areas or rooms, as they often give rise to visplane overflow (VPO) errors, which cause DooM to crash. Also, large areas that are plain tend to look ordinary and boring. Detailing large areas takes a lot of work, and can often lead to visplane errors when a source port is not used.

    3. Add angles, recesses, and beams to your rooms so that they'll be visually interesting. Playing in square or rectangular rooms is all right, but adding these variations makes for a nicer looking map.

    4. Incorporate height variations. Have a section of a map that is one or two levels up from the main level, and a section that is one or two levels down. Elevators and stairways make for interesting gameplay while providing a nice look and feel to a map.

    5. Incorporate lighting variations. For outdoor areas in daylight and reasonably well-lit indoor areas use a light value of 160 and up, for indoor areas not under direct light use 128 to 144, for unlit corridors, etc. use light value of 96 to 128. Avoid excessive use of very dark areas, as it gets old after a while.

    6. Use a balanced approach to gameplay. Always provide the player with a fair chance at finishing the level or an area. Sometimes you may want to make a particular area very tough, forcing a player to find an alternative way in or to get better weapons, etc. But make sure that the player has a way of beating the area, one way or another.

    7. Pay attention to the general look of the level. Define a theme and generally stick to it. Try to use texture variations to provide visual relief to your areas. For example, use STARGR1 as the main texture in a room, but occasionally insert a STARGR2. If you have a plain wall that's more than 256 units long, add a wall-bracket or "support" that uses a different and contrasting texture -- e.g., STARGR1 as wall texture, METAL1 as support or pillar texture.

    8. If it's consistent with your theme and level design, incorporate outdoor areas into your map. A good mix of indoor and outdoor areas lends appeal to a level.

    Good luck.

    Read Tutorial

  • Beginning Doom Editing
    Here are some suggestions for getting started:

    1. waddesignershandbook2Spend some time reading the tutorials. You will learn the fundamentals, and, most importantly, the terminology. The two tutorials that helped me the most when I was getting started was The Unofficial Wad Designer's Handbook by Ron Allen and Bill McClendon.

    2. Open up an editor and begin exploring. After you've tried out a few editors and settled on the one with which you are most comfortable, open up maps that you've played. The original DooM and DooM2 maps are great for starters, as they contain examples of most things you can do with the original DooM engine.

    3. Start making your own maps. Experiment with rooms, doors, windows, wall recesses, overhangs, platforms, stairs, and lifts. These type of constructs typically form the bulk of most maps.

    4. Experiment with wall textures and floor/ceiling flats. You'll find that if you use constructs and textures within a general theme (e.g., military base, medieval, hellish) your maps will look more natural.

    5. Experiment with the various effects -- teleportation, flickering lights, hazardous areas, crushing ceilings, etc.

    6. Nobody's a pro from the first day!Experiment with enemies, traps, and gameplay. Use enemies selectively, as each has strengths and weaknesses. Not every enemy works in every situation. Make sure that you give your enemies enough room to move and maneuver. Putting a "wide" enemy in a narrow corridor causes them to be stuck to the walls, defenseless and unable to move or attack.

    7. Experiment with weapons, ammo, health, armor, and other powerups. Strive for a balance, so that the player is challenged but not frustrated. Give the player just enough to be able to overcome the obstacles you put in his or her way.

    8. Work on the details of your maps. Pay attention to texture alignment, add architectural accents, add decoration and scenery.

    Good Luck,
    Rex Claussen (Rex's Nexus)

    Read Tutorial

  • Creating Custom Items in ZDoom

    Using DECORATE to Create Custom Items

    ZDooM (and its derivatives GZDooM & SkullTag) allows the creation of items that look and behave completely differently from those in "vanilla" DooM. These new items, known as "actors", need to be defined; this is accomplished via a text-based "lump" (name for any entry in a DooM wad) known as DECORATE. The purpose of this article is not to provide an introduction to defining custom items; rather, it highlights some lessons that I recently learned while creating my own custom items. For information on creating DECORATE definitions, refer to these sources:

    DECORATE-related Tutorials

    New User's Guide to Editing with DECORATE

    Creating Non-interactive Decorations

    DooM World Forum Discussion on DECORATE

    A. Power-Ups, Inventories, and Hubs

    It turns out that many power-ups can't be carried from one map to another in a hub. For example if you want the player to pick up a radiation suit in one map and carry it for use in another map in the hub, the "standard" DooM radiation suit will not work. The item is activated as soon as you pick it up; but more importantly, as soon as you teleport into a new map you lose the power-up, even if there's plenty of time left on the item. In my opinion the biggest oversight in ZDooM's definitions in this regard, is the lack of portability of a computer map. You can pick up a computer map on one map in a hub and find that you've "lost" it when you travel to another map. [To be fair, however, when you return to the map in which you picked up the unit it is usable again.] So, in this section I will outline the steps to make a radiation suit that can be carried to, and used in, any map within a hub.

    First, here's an example of a radiation suit that can be picked up in a map and put into an inventory for use in that or any other map in a hub.

    ////////////////////////////////////////
    // Custom Radiation Suit //
    ////////////////////////////////////////
    ACTOR SlimeSuit : PowerupGiver 20006
    {
      Game Doom
      SpawnID 206
      Height 46
      +COUNTITEM
      +INVENTORY.HUBPOWER
      +INVENTORY.ALWAYSPICKUP
      +INVENTORY.INVBAR
      Inventory.Icon SUITA0
      Inventory.MaxAmount 1
      Inventory.PickupMessage "$GOTSUIT" // "Radiation Shielding Suit"
      Powerup.Type "IronFeet"
      States
      {
      Spawn:
        SUIT A -1 Bright
        Stop
      }
    }

    So let's examine the definition above, which is virtually the same as the one for DooM's radiation suit:

      1. You have to give the actor a unique name, especially one that has not been given to one of the DooM actors. In this case, SlimeSuit is a name that has not been taken; it also has the benefit of describing the actor you are creating.
      2. DooM's RadSuit inherits its properties from a PowerupGiver, which is used to give one of the existing powerups to the player using or picking up this item. It is only used as a base class for many predefined inventory items or as a base to define new powerup pickups. This is what you're doing here for SlimeSuit - letting the game know that your actor will be inheriting (in this case) an existing powerup that is already defined.
      3. If you want to be able to spawn the SlimeSuit in-game (e.g., via a script), you'll need to give it a unique SpawnID, in this case = 206.
      4. Now here's the key to making your actor usable in other maps in a hub - you'll add the flag +INVENTORY.HUBPOWER.
      5. You probably want to be able to show the player that the SlimeSuit is in her/his inventory. You'll use the flag +INVENTORY.INVBAR.
      6. Define the maximum number of SlimeSuits that the player can carry at any given time (in this case = 1) using Inventory.MaxAmount.
      7. Now here's the key step - you need to define what the PowerupGiver actually does. In this case, because you want the SlimeSuit to behave exactly like the RadSuit, you'll simply use the flag = Powerup.Type "IronFeet". IronFeet is an internal class that already contains all the instructions necessary for defining your SlimeSuit, so all you need to do is call it up in your definition.

    B. Creating A Custom Berserk

    Most DooM items are automatically activated as soon as you pick them up. This, of course, defeats the purpose of having an inventory in which you can store items for later use. In addition, some items change the player's state upon being picked up; the Berserk is an example of such an item. When you pick it up your health automatically maxes out at 100 HP, your weapon is lowered and your fist is readied, and your punches are given greater strength. You don't want these state changes to occur, but you want to be able to call them up when you're ready to use this item. So here's an example:

     
    ///////////////////////////////
    // Custom Berserk //
    ///////////////////////////////
    ACTOR Pugilist : CustomInventory 20011
    {
      Game Doom
      SpawnID 211
      +COUNTITEM
      +INVENTORY.HUBPOWER
      +INVENTORY.ALWAYSPICKUP
      +INVENTORY.INVBAR
      Inventory.Icon PSTRA0
      Inventory.MaxAmount 1
      Inventory.PickupMessage "$GOTBERSERK" // "Berserk!"
      Inventory.PickupSound "misc/p_pkup"
      States
      {
      Spawn:
        PSTR A -1
        Stop
      Use:
        TNT1 A 0 A_GiveInventory("PowerStrength")
        TNT1 A 0 HealThing(100, 0)
        TNT1 A 0 A_SelectWeapon("Fist")
        Stop
      }
    }
      1. Before you examine the definition above, please open up the definition for the Berserk.
      2. You'll notice that the Berserk has a "Pickup" state. This provides a definition of what changes to make to the player's state upon the item being picked up. Of course, you want the item to be save to your inventory, not used up when it is picked up. Therefore, you need to delete the "Pickup" state and replace it with a "Use" state.
      3. However, as the state changes you wish to give the player when the item is used are the same as those when the Berserk is picked up, all you need to do is rename "Pickup" to "Use".
      4. All other changes to make the item storable in an inventory are described above for the SlimeSuit.

    C. Creating A Custom SoulSphere

     Now let's look at a slightly more complicated example of an item that gives the player a powerup but does not have a "Use" state at all. The SoulSphere gives the player 100 HP but allows the maximum health to exceed 100 HP to a maximum of 200 HP. You want to be able to retain this property, but make it usable at will. So here's an example:

    ////////////////////////////////////
    // Custom SoulSphere //
    ////////////////////////////////////
    ACTOR BlueSphereHealth : Health
    {

      Inventory.Amount 100

      Inventory.MaxAmount 200
      +INVENTORY.ALWAYSPICKUP
    }

    ACTOR BlueSphere : CustomInventory 20014
    {
      Game Doom
      SpawnID 214
      +COUNTITEM
      +INVENTORY.HUBPOWER
      +INVENTORY.INVBAR
      +INVENTORY.ALWAYSPICKUP
      +INVENTORY.FANCYPICKUPSOUND
      inventory.maxamount 1
      inventory.icon SOULA0
      Inventory.PickupMessage "$GOTSUPER" // "Supercharge!"
      Inventory.PickupSound "misc/p_pkup"States
      {
      Spawn:
        SOUL ABCDCB 6 Bright
        LoopUse: TNT1 A 0 A_GiveInventory("BlueSphereHealth")
        Stop
      }
    }
      1. Before you examine the definition above, please open up the definition for the SoulSphere.
      2. You'll notice that the SoulSphere only has a "Spawn" state and has no "Pickup" or "Use" states. This is because the SoulSphere is defined to inherit from the Class: Health, which is automatically activated upon being picked up. [Note that health items are always effective when picked up; they cannot be placed in the inventory.] Given that the health class does not lend itself to usage in an inventory, and the fact that the SoulSphere has no "Use" state, you have no choice but to create a CustomInventory item.
      3. CustomInventory items are special items that allow some very primitive scripted functionality using its states. In other words, if you want to include a "Pickup", "Use", or "Drop" state in the definition of your item, you must define it as a CustomInventory.
      4. Also, because there are no pre-defined CustomInventory items that behave like a SoulSphere, you need to create a completely new actor. In this case, I have named it BlueSphereHealth. This actor can inherit from Class: Health, as this is the behavior you desire for it.
      5. Your in-game actor will inherit all the health attributes from the BlueSphereHealth actor (via the "Use" state), but you'll need to define it as a CustomInventory. [Defining it as Class: Health will completely negate any inheritance from the other actor, as your "Use" states will become redundant. You'll note that I've taken the Inventory.Amount and Inventory.MaxAmount flags from the SoulSphere definition, and put them into the definition of my BlueSphereHealth.
      6. Your "Use" state must include a flag that instructs the game to use the pre-defined actor "BlueSphereHealth".
      7. All other changes to make the item storable in an inventory are described above for the SlimeSuit.
    D. Creating An Inventory Item That Is Usable Only After One or More Conditions Are Met

    In an adventure scenario, and particularly within a hub, it may be necessary to prevent a player from using an inventory item prematurely. For example, let's say the player needs a radiation suit in Map05 of a hub in order to make progress through a nukage area, but the suit is available only in Map02. If the player picks the suit up in Map02 and accidentally uses it before getting to Map05, s/he is essentialy stuck in the game, as the nukage area cannot be traversed without the suit. So here's an example of how to set up the actor in such a manner that the suit (called a "special" SlimeSuit in this tutorial) cannot be used before reaching the nukage area:

    //////////////////////////////////////////////////////
    // Custom Radiation Suit (Special) //
    //////////////////////////////////////////////////////
    ACTOR SlimeSuitProtection : RadSuit
    {
      +INVENTORY.ALWAYSPICKUP
    }

    ACTOR SlimeSuit : CustomInventory 20006
    {
      Game Doom
      SpawnID 206
      Height 46
      +COUNTITEM
      +INVENTORY.HUBPOWER
      +INVENTORY.INVBAR
      inventory.maxamount 1
      inventory.icon SUITX0
      Inventory.PickupMessage "$GOTSUIT" // "Radiation Shielding Suit"
      Inventory.PickupSound "misc/p_pkup"States
      {
      Spawn:
        SUIT Z -1 Bright
        Stop
      Use:
        TNT1 A 0 A_JumpIf((ACS_ExecuteWithResult(666,0,0,0)) < 1, "FailState")
        TNT1 A 0 A_GiveInventory("SlimeSuitProtection", 1)
        Stop
      FailState:
        TNT1 A 0 A_Print("SlimeSuit Use Disabled in this Sector.")
        Fail
      }
    }
      1. You'll notice that, at its core, the definition is very similar to that of the Custom Radiation Suit at the top of this tutorial.
      2. The key difference between the "Special" SlimeSuit and the "Regular" SlimeSuit in this tutorial is that the former is defined as a CustomInventory item, while the latter inherits from DooM's Radiation Suit via the PowerupGiver class, which is used to give one of the existing powerups to the player. It is necessary to define the special slimesuit as a CustomInventory item because a "regular" inventory item does not support the type of feature that is needed to control the item's use (see 5, below).
      3. As with the custom SoulSphere above, because there are no pre-defined CustomInventory items that behave like a RadSuit, you need to create a completely new actor. In this case, I have named it SlimeSuitProtection. This actor directly inherits from Class: RadSuit, as this is the behavior you desire for it.
      4. You'll notice that the sprite graphic used for this special SlimeSuit is not the same as the regular SlimeSuit (which in turn was using the sprite graphic of DooM, which is SUITA0). The special suit uses a sprite graphic named SUITZ0, which happens to be different in appearance from SUITA0 to mark it as a special item. This is done so that the regular radiation suit (or regular SlimeSuit) can be used in the same game without causing confusion about the inventory item's capabilities. If you have no need to distinguish between the special SlimeSuit or regular SlimeSuit/RadiationSuit you can simply use the DooM's sprite graphic and name.
      5. Your in-game actor will inherit all the radiation protection attributes from the SlimeSuitProtection actor (via the "Use" state). However, note that there's a "condition" placed in the "Use" state, which only allows the inventory item to be used if a specific condition has been met. This is implemented via a JumpIf expression. Let's see how this expression and state work:
        a. The first part of the expression, A_JumpIf, jumps the specified amount of states (not frames) forward if the expression evaluates to true.
        b. The second part of the expression, (ACS_ExecuteWithResult(666,0,0,0)) < 1, sets up the condition that JumpIf is testing. In this case, it is testing script number 666 to see if the "return value" is less than 1. (More on "return value" later in this tutorial).
        c. The final part of this expression, "FailState", specifies the name of the state to which to jump if the test proves to be true (i.e., return value is less than 1). In this case, the "Use" state is considered to have failed, and the item is "disabled" for use by the player.
        d. If the JumpIf determines that the result of the test is untrue, the definition jumps to the next frame, namely: TNT1 A 0 A_GiveInventory("SlimeSuitProtection", 1), which then activates the SlimeSuit.
      In summary, if the script passes a value less than 1, the "Use" state is deemed to have failed, and the item cannot be used. If the script passes a value of 1 or more, the item is activated.
      6. The FailState provides a message that provides a clue to the player; it is entirely optional. The key aspect of this state is the "Fail" statement, which prevents the item from being used.
      7. All other changes to make the item storable in an inventory are described above for the SlimeSuit.
    So now let's take a look at the "switch" that determines when the SlimeSuit can be activated - Script 666. Essentially, we're setting up the condition like a reverse switch, with the condition indicating that the player is notat the area where the SlimeSuit is required. So long as the condition is true the return value will be 0, and the expression will jump to the fail state. As soon as the player arrives at the appropriate area, the return value changes to 1, the JumpIf condition becomes false, and the definition jumps to the A_GiveInventory frame, which activates the SlimeSuit.

    Because it serves as a switch, Script 666 will look different in maps where SlimeSuit use is "denied" and in maps where it is "allowed". [As an aside, the script number is arbitrary. You can pick any number, so long as it's not already in use in all of the maps. A suitably high number (e.g., 999) would work just as well, as it's unlikely that a map has that many scripts - assuming they are consecutive.] First, a look at a map where SlimeSuit use is denied:

    //////////////////////////////////////////////////////////////////////////////////

    // Script 666: Prevents radiation suit from being used //

    //////////////////////////////////////////////////////////////////////////////////

      script 666 (void)

      {
        SetResultValue (0);
      }

    An ACS_ExecuteWithResult script must always be accompanied by a script with SetResultValue. The Special SlimeSuit definition is running the ACS_ExecuteWithResult script, which in turn is looking for the result from a script that returns a value via a SetResultValue. This value can either be a numeric value or a True/False value. In our example it's a numeric value, namely 0. Remember, you want the A_JumpIf expression to failin this instance, which means the value needs to be less than 1. Any time you try to "use" the SlimeSuit in your inventory, ACS_ExecuteWithResult runs Scrpit 666, gets a returned value less than 1, jumps to the FailState state, and prevents the item from being used. Now lets look at the map where SlimeSuit use is allowed:

    //////////////////////////////////////////////////////////////////////////////////

    // Script 666: Prevents radiation suit from being used //

    //////////////////////////////////////////////////////////////////////////////////

       script 666 (void)
      {
        SetResultValue (1);

      }

    Pretty self-explanatory - by setting the return value to 1, you are now allowing the definition to jump to the instruction that activates the SlimeSuit. This will allow you to use the SlimeSuit as soon as you enter the map. But what if you didn't want the player to use the SlimeSuit right away upon entering the map? You'd have to create a switch within a switch that would remain turned off until the player reached the proper point in the map. You'd set this up in two steps, as follows:

    /////////////////////////////////////////////////////////////////////////////////
    // Script 9: Message about radiation suit on Map02 //
    /////////////////////////////////////////////////////////////////////////////////
      int Map05;
      script 9 (void)
      {
        Map05 = 1;
        print(s:"Activate Radiation Suit from your inventory before entering nukage.");
      }

    ////////////////////////////////////////////////////////////////////////
    // Script 666: Allows radiation suit to be used //
    ////////////////////////////////////////////////////////////////////////
      script 666 (void)
      {
        if(!Map05)
          {
          print(s:"You are not yet ready to use the SlimeSuit.");
          SetResultValue (0);
          }
        else
          SetResultValue (1);

      }


    Script 9 is set up to throw the first switch, allowing Script 666 to throw the second switch. [Script 9 also has a message, but that's entirely optional.] Script 9 can either be activated by pressing an actual switch, or by crossing a linedef, or by entering a sector, or by any other means by which a script may be triggered. Until Script 9 is triggered, the variable 'Map05' will not be switched on, and Script 666 will return a value of 0. As soon as the player reaches the designated point on the map and triggers Script 9, Script 666 will return a value of 1. This will allow the DECORATE definition to properly complete the "Use" state and activate the SlimeSuit.

    Read Tutorial

  • Creating Graphics with TEXTURES
    TEXTURES (also known under the deprecated name of HIRESTEX) is ZDoom's text-based answer to the classic Doom engine PNAMES and TEXTUREx lumps. With TEXTURES, you can create not only new textures and flats, but also menu graphics and sprites. Here's the relevant Wiki page for it, and a couple of other pages which will be referenced.
    Adding a TEXTURES lump is easy. Simply create a new entry named TEXTURES, or if you're using the PK3 format for your mod, create a text file named TEXTURES. This language is plain-text and can be edited with any text editor, or in a resource manager such as XWE or SLADE. SLADE is recommended as it features a visual TEXTURES editor, though you can still of course edit the code directly.

    First of all, here are some relevant keywords. This first batch will help you learn the namespaces involved with TEXTURES.
    • Texture - This creates an "overriding" texture (see note on priority below). Most of the time, this is what you will want to use.
    • WallTexture - Used to define a wall graphic. This is usually not necessary in ZDoom.
    • Flat - Used to define a floor or ceiling graphic. This is usually not necessary in ZDoom.
    • Sprite - Used to define a sprite, an image displayed for weapons, enemies, projectiles, decorations and other physical objects. Sprites have special properties in TEXTURES which I will cover later.
    • Graphic - Used to define a graphic like M_DOOM or menu images. Needed only for PK3 archives, and not WADs.
    A note on texture priority: There are three texture namespaces, Texture, WallTexture and Flat. When applying a texture on a sidedef, ZDoom will look first in Texture, then in WallTexture, and finally in Flat. When applying a texture on a sector, ZDoom will look first in Texture, then in Flat, and finally in WallTexture. This second batch can be applied to the images you create with TEXTURES.
    • XScale - The width scaling of the image. This uses inverted scaling, covered later.
    • YScale - The same as XScale, but for height.
    • Offset - Used only for sprites to determine where it is displayed when it is rendered.
    • WorldPanning - This is mostly used when replacing a lower-res texture with a higher-res one. As such, it's not terribly useful.
    • NoDecals - This image will never have decals on it in a map.
    • NullTexture - Most likely for compatibility purposes to emulate textures like AASHITTY and AASTINKY. This texture will never be drawn.

    I'll show you how to assemble a basic single-patch texture, followed by a detailed analysis of it. This is a texture from Doom 2's TEXTURE1 lump. In a PK3 archive, you can also specify a full path if you want to.

    walltexture ASHWALL2, 64, 128 //namespace, name, width, height
    {
       Patch RW22_1, 0, 0 //patch name, offset X, offset Y
    }

    As you can see, you begin a new entry by defining a namespace as explained earlier. For a simple texture, like in Doom 2, I am using the walltexture namespace. Following this is the name of the texture. We're using the name of the first texture in Doom 2's TEXTURE1 lump after AASHITTY, which is ASHWALL2, for example purposes. Next, the width (X) of the image in pixels, and then the height (Y) in pixels.

    Next, we place a patch. You begin with the keyword Patch, followed by the patch you wish to use. This can be any graphic in the WAD you're using. After the patch are it's offsets on the final texture. These are X and Y, respectively. 0, 0 would be the upper-leftmost pixel.

    Finally, a second curly brace to close the block, and we have a functional texture! It's not much, but it's a working texture. Why don't we spruce it up a bit, though? Let's re-use our texture, but this time, we're making a sub-block underneath the patch. Here we can apply a number of neat effects, but to start I'll show you color blends.

    walltexture ASHWALL2, 64, 128
    {
       Patch RW22_1, 0, 0
       {
          Blend Red, 0.5 //color, intensity
       }
    }

    As you can see, I've blended some red into the patch at half intensity. At 0.1, the graphic is an almost entirely solid color, while at 0.9, it's a very light tint, opposite what you may expect.


    Now I'll show you how to use translations. We're going to take FLAT14, which is a blue carpet-looking flat from Doom 2, and make it red. So, first we define our image, but you know how to do that by now. If you've written translations in DECORATE or ACS, this is easy as can be, and it uses the same syntax.

    flat FLAT14_R, 64, 64
    {
       Patch FLAT14, 0, 0
       {
          Translation "192:207=176:191", "240:247=40:47"
       }
    }

    As you can see, I've added the Translation keyword, followed by my crappy translation that turns the soft blues of the image into reds. You can also use GZDoom's special translation function to use colors outside the palette. Here's a fabulous purple carpet which shows off this feature's use in TEXTURES.

    flat FLAT14_P, 64, 64
    {
       Patch FLAT14, 0, 0
       {
          Translation "204:207=[130,80,170]:[80,30,120]", "241:247=[75,25,110]:[55,5,90]"
       }
    }
    Bear in mind that Translation and Blend cannot be used on the same patch!

    Next comes rotations. These are also easy to do, and applied in much the same way as flips. For an example, I will show you how to make a practical texture out of an existing one; we're making a horizontal version of the DOORTRAK texture.

    texture DOORTRKH, 128, 8
    {
       Patch DOORTRAK, 0, 0
       {
          Rotate 90
       }
    }

    First of all, note the dimensions of the texture; when using rotations, bear in mind what the dimensions of the texture would need to be to accommodate the patch once it has been rotated. Now look at the patch block. As you can see, you begin with the rotate keyword, followed by an angle. As of writing this, ZDoom only supports rotations in angles of 90, limiting your options to 90, 180, and 270. Either way, you now have a horizontal door track!


    Now I'll show you how to use different rendering methods. First, here are the rendering styles you may use. All of these use the Alpha parameter to control the intensity of the effect chosen.
    • Copy - The patch is completely solid. No translucency or other effects are applied. This is the default and you don't need to apply it.
    • CopyAlpha - Copy for PNGs with their own translucency.
    • Translucent - Basic translucency.
    • Add - Additive translucency, which makes the patch appear bright as if it's producing its own light.
    • Subtract - Removes the patch from the patches beneath it while inverting the patch.
    • ReverseSubtract - The same as subtract, but without inversion.
    • Modulate - Darkens the patch considerably.
    IMPORTANT! A common misconception is that translucency affects the final texture. Keep in mind when using translucency that you cannot make the resulting texture translucent, only the patches in relation to one another. As such, using translucency on a single-patch texture will result in a darkened mess. Consider the texture itself to be a black canvas. When you place a patch on it and make it translucent, in game on a wall or HUDMessage, you will see the "canvas" behind the patch.
    Let's create another texture with two distinct patches; a wooden crate with a label on it.

    texture WOOD10, 128, 128
    {
       Patch RW13_1, 0, 0 //first, the base texture
       Patch PS18A0, 34, 43 //our label, a radiation sign from Doom 2. Its offset places it roughly in the center
       {
          Style Translucent
          Alpha 0.6
       }
    }

    Now if you load your TEXTURES lump with Doom 2, wherever you see a big wooden crate, it will have a translucent radiation sign on it. The other rendering modes are just as easy to use. With the exception of Blend and Translation together, you can freely combine any styles and alterations you wish.


    Next, I'll show you how to make a scaled texture. Let's say you've got an image that's 256x256, and want it to be only 128x128 in-game. That's easy to do.

    texture SCALED, 256, 256
    {
       XScale 2
       YScale 2

       Patch SCALE_ME, 0, 0
    }

    As you can see, it's as simple as scaling it down by two. If you wanted it to fit to a 64x64 texture for use as a flat, you would scale by four and so on.
    IMPORTANT! When defining a scaled texture, make sure you set the image's dimensions as the size of the texture, and not the size you want to scale down to!TEXTURES' scaling is quite robust. Let's take an image with far more oddball dimensions and scale it down. For instance, I have a texture that is 419x531, and I want to scale it down to 80x128. Open a calculator program and enter in the width of your texture. Divide this by the desired width, and the output number is your scaling factor.

    texture SCALED, 419, 532
    {
       XScale 5.2375
       YScale 4.15625

       Patch SCALE_ME, 0, 0
    }

    As you can see, the scaling factor can be decimalized, allowing for greater flexibility. You can also scale images up. Here's a texture that's 64x64, scaled up to 128x128.

    texture SCALED, 64, 64
    {
       XScale 0.5
       YScale 0.5

       Patch SCALE_ME, 0, 0
    }

    The process to get an inverted scaling factor is more or less the same. Take the dimensions you want, and divide them into the dimensions of the image.


    Finally, TEXTURES can be used to create sprites. The process is much the same as creating a new texture, with an extra set of parameters. Let's create a simple flipped decoration.

    sprite FCAND0, 37, 53
    {
       Offset 19, 49

       Patch FCANA0, 0, 0
       {
          FlipX
       }
    }

    This code will give us a flaming can that's been flipped on its X axis. You could go on to redefine the other two frames of it in this manner to create a mirrored flaming can decoration. Note the offset keyword before the patch block. This tells the engine where to draw the sprite in relation to its physical location. Here, I'm using the offsets of the FCANA0 sprite.

    You can also make new weapon sprites in a similar way. For example, here's the player's fist on the left side of the screen, again using a simple FlipX command.

    sprite PUNGE0, 113, 42
    {
       Offset -151, -126

       Patch PUNGA0, 0, 0
       {
          FlipX
       }
    }

    Note that when using the Scale functions for sprites, offsets can become difficult to calculate. While scaling can be directly applied to any actor from within DECORATE or through ACS, high-resolution weapon sprites require scaling via TEXTURES. Unfortunately, I have no easy method for calculating these offsets except by trial and error.
    A note on sprite naming: When using the sprite frames [, \, and ], you must enclose the name in quotations or the parser will not recognize it! For example, "POSS\1".Now that you understand TEXTURES, you may wonder why you should use it. If you don't require anything more advanced than a list of textures you can use, TEXTURES is really not necessary. However, with it you can accomplish a number of things and save a considerable amount of space. A number of texture packs offer recolored versions of many classic Doom textures, but you can do these with translation code now to save space. You can use flipped and rotated versions of classic textures without having to add anything new, complete textures that require mirroring (for instance, from games like Doom 64, Duke Nukem 3D and Blood), and any number of other graphic-related needs.

    Read Tutorial

  • Creating Hub Structures in ZDoom

    This is a brief discussion on how to create maps in a hub structure within a ZDooM environment. A "hub" structure is a loose definition of the original "hub & spoke" structure. A hub & spoke design is one where there is a central map (the hub), and peripheral maps connected to the hub via spokes. [Very similar to a cart wheel, with the central hub being the point through which the entire structure connects.] A good example is the first Hexen mission. Subsequently, any collection of maps that allow players to return to maps already traversed (or allowed back-and-forth travel between maps) became known as hub-based wads.

    There are two parts to creating a set of maps within a hub structure. The first part involves setting up your MAPINFO definitions, and the second part involves setting up your maps. (This discussion assumes you are familiar with the use of a MAPINFO lump.) To set up your MAPINFO, you'd need to assign your maps to a "cluster". [From the ZDooM wiki:] A cluster definition begins with the keyword “cluster”. For purposes of ZDoom, clusters are used to displays messages when moving between maps and to optionally group different levels into a hub.... When leaving a hub, the game will remember the contents of the level when the player left it and restore the level to that state when the player returns to it. The following is an example of a MAPINFO definition for maps in a hub:

      map map10 "Command Center"
      sky1 sky1 0.0
      music D_DOOM2
      cluster 1

      map map11 "Power Plant"
      sky1 sky1 0.0
      music D_TENSE
      cluster 1

      map map12 "Krakatoa"
      sky1 sky2 0.0
      music D_ADRIAN
      cluster 1

      map map13 "Valhalla"
      sky1 sky2 0.0
      music D_ROMERO
      cluster 1

      map map14 "Temple of the Ancients"
      sky1 sky2 0.0
      music D_SHAWN
      cluster 1

      clusterdef 1
      hub

    You'll notice that each map has to be defined within its cluster (in this case, "cluster 1"). Also note that cluster 1 is defined as a hub via the lines "clusterdef 1" & "hub". [The definitions for map names, skies, and music are all optional in the context of defining clusters and hubs.]

    This next section covers how to set up your maps. Assuming, for a moment, that you have a true hub-spoke wad in which the player starts in the hub map and can travel to 3 other maps, you'd do the following:

      1. In the "hub" map, your Player 1 start would have a default argument value of 0. [Let's say the map is Map01.]

      2. In Map01, you'd have exits to each of your other maps. For simplicity's sake, assume the player returns to Map01 at the same point that s/he leaves it. At each exit you would have a player start. For the exit/return point for Map02, you can assign an argument value of 1 to the player start (although you can just as easily assign an argument value of 2 or 3 if you wish). For the exit/return point for Maps03 and 04, you can assign an argument value of 2 and 3 to the respective player starts.

      3. In Map01, your exit command would use Teleport_NewMap (map, position). So, to exit to Map02, you'd have Teleport_NewMap (2, position). For the sake of simplicity, assume the position (which is the player start argument value for the destination map) is 0. So your exit would be Teleport_NewMap (2, 0).

      4. In Maps02 to 04, assign an argument value of 0 to the respective player starts. (You can assign a different value, depending on the argument you use in the exit command from Map01. See 3, above.)

      5. In Maps02 to 04, create your exit points to return to Map01.

      6. For Map02, your exit command would be Teleport_NewMap (1, 1); for Map03, it would be Teleport_NewMap (1, 2); and for Map04, it would be Teleport_NewMap (1, 3). The position values here correspond to the player start arguments you assigned in 2, above.

    If you wanted to create direct connections between the peripheral maps (i.e., Maps02 to 04) that would not require going through the hub (Map01), you'd create similar exit/entry points, taking care to use different player start arguments (unless the entry points happen to coincide with those from Map01, in which case you wouldn't need new arguments).

    Read Tutorial

  • CustomInventory Items as New Functions
    Before we start, this is just a really tiny tutorial for a little trick you can take advantage of. Only really two links you need to know about, and they're things you want to know anyway:
    Sometimes, you want monsters, players, or other actors to do a lot of things at once, while it's doing other things. For example, if you wanted to make a standard imp do something interesting in its See state if it's fully submerged underwater, you might do something like this:

      See:
        TROO A 0 A_JumpIf(waterlevel == 3, 2)
        TROO A 0 A_ChangeFlag("NoPain", 0)
        Goto See+3
        TROO A 0 A_ChangeFlag("NoPain", 1)
        TROO A 3 A_Chase
        TROO A 0 A_JumpIf(waterlevel == 3, 2)
        TROO A 0 A_ChangeFlag("NoPain", 0)
        Goto See+7
        TROO A 0 A_ChangeFlag("NoPain", 1)
        TROO A 3 A_Chase
        TROO B 0 A_JumpIf(waterlevel == 3, 2)
        TROO B 0 A_ChangeFlag("NoPain", 0)
        Goto See+11
        TROO B 0 A_ChangeFlag("NoPain", 1)
        TROO B 3 A_Chase
        TROO B 0 A_JumpIf(waterlevel == 3, 2)
        TROO B 0 A_ChangeFlag("NoPain", 0)
        Goto See+15
        TROO B 0 A_ChangeFlag("NoPain", 1)
        TROO B 3 A_Chase
        TROO C 0 A_JumpIf(waterlevel == 3, 2)
        TROO C 0 A_ChangeFlag("NoPain", 0)
        Goto See+19
        TROO C 0 A_ChangeFlag("NoPain", 1)
        TROO C 3 A_Chase
        TROO C 0 A_JumpIf(waterlevel == 3, 2)
        TROO C 0 A_ChangeFlag("NoPain", 0)
        Goto See+23
        TROO C 0 A_ChangeFlag("NoPain", 1)
        TROO C 3 A_Chase
        TROO D 0 A_JumpIf(waterlevel == 3, 2)
        TROO D 0 A_ChangeFlag("NoPain", 0)
        Goto See+27
        TROO D 0 A_ChangeFlag("NoPain", 1)
        TROO D 3 A_Chase
        TROO D 0 A_JumpIf(waterlevel == 3, 2)
        TROO D 0 A_ChangeFlag("NoPain", 0)
        Goto See+31
        TROO D 0 A_ChangeFlag("NoPain", 1)
        TROO D 3 A_Chase
        Loop
    //Don't quote me on this, I haven't tested it. Just an example of what it might look like

    Pretty obviously, this is hilariously ugly, can bug out easily if not done right, and you have to keep close track of your jumps, gotos and etc. THERE IS A BETTER WAY TO DO THIS!

    In "real" programming, if you have one function that does the same thing repeatedly in a sequence with other stuff, we outsource that repeated thing to another function and call that, so it looks cleaner and is easier to troubleshoot. This is why, for example, A_MissileAttack has A_FaceTarget built in, instead of calling it with a 0-delay just beforehand. Unfortunately in Decorate, we can't define new functions (the A_ things)... But we have CustomInventory!

    CustomInventory, by definition, is an item that allows you to define a Pickup state (or Use, but we want Pickup for this) with existing functions to make a powerup or other item that does anything you want it to do, with a few limitations. These functions in the Pickup and Use states are executed BY THE ACTOR WHO PICKED UP THE ITEM, not the item itself. Thus, we can slap some of those functions we have in a CustomInventory item, and A_GiveInventory it so we can execute those checks and flag changes to one call!

    Yes! As the wiki page says, monsters can have items! They have no code for picking up items (for good or ill), so they either have to give it to themselves or it has to be done in ACS.

      See:
        TROO AABBCCDD 3 A_GiveInventory("ImpWaterCheck", 1) //Execute our new function!
        Loop

    Actor ImpWaterCheck : CustomInventory
    {
      Inventory.PickupMessage ""
      Inventory.PickupSound ""
      -CountItem
      states
      {
      Spawn:
        TNT1 A 1
        Fail //We don't want this ever spawning.
      Pickup:
        TNT1 A 0 A_Chase
        TNT1 A 0 A_JumpIf(waterlevel == 3, "Underwater")
        TNT1 A 0 A_ChangeFlag("NoPain", 0)
        Stop
      Underwater: //Because new states are just awesome
        TNT1 A 0 A_ChangeFlag("NoPain", 1)
        Stop
      }
    }

    It requires a new CustomInventory item, but we've just made our See state much easier to follow. Now, keep in mind, CustomInventory items CANNOT have delays! Nor would we want them to in this case because it we want all of this to happen immediately when it's given. Still, CustomInventory items can't have delays, and no matter what number you put in, it'll still execute all of it with 0 delays. Now, I really don't recommend this for just collapsing a few 0-delay things together, but it's ideal for when you have checks, jumps and things like that in a looping state, because that gets difficult to manage how the state flows.

    Another thing I like to use this for is when I have a monster that is heavily built in to some ACS scripts. If you want to use an ACS script change a flag on a monster, for example, but don't want to use SetActorState (and risk interrupting an animation), you can give a CustomInventory item that does it.

    Read Tutorial

  • Editors & Tools to start with
    Considering the age of Doom now, it's some kind of a miracle to me that there are still new people arriving at the modding communites and starting to work on their own projects. Not that it is a bad thing, it's quite the opposite as those people get some new ideas into this fucking old egoshooter. Though, starting off from zero is a hard thing considering all the different applications and programs you can work with. This article is supposed to be a collection of tools that are a useful base if you want to work effectively on a new ZDoom/GZDoom project without having too much trouble or spending too much time on looking for them. I will also try to keep this up-to-date as soon as new programs are availabe, so just to let you know that this isn't outdated in the next few weeks Zwinkernd So, let us not waste even more time and read on!

    The Map Editor
    "Easy and fast - it's DoomBuilder 2"
    start_db2.pngSince almost ten years, I am an active mapper in the community and therefore I had the chance (or out of necessity) to use a large variety of different editors, like WinDeu, Deth, Zeth, WadAuthor and Zeth but none of them has been as advanced, as fast and as easy to learn as DoomBuilder and the all new DoomBuilder 2. The reason for this is definitely CodeImp, the creator of DoomBuilder. He is still actively working on improvements for his masterpiece mapeditor and what's even more important: He is working together with this on members from the community in terms of beta tests, bug tracking and feature suggestions. So, in a certain way, the new Doom Builder is a coproduction that aims exactly at the needs of us mappers. Additionally it's always up to date in terms of ZDoom/GZDoom compatibility (e.g. reading resources PK3s), and with it's countless possibilites and features, it's the primary choice for every Doom mapper out there. Nothing is better, nothing is faster, nothing is easier than Doombuilder. That's no hint, it's an assignment Lachend By the way, if you are more into next-generation-editing with all those nice dynamic lights and 3d models that GZDoom supports, you might also be interested in GZDoombuilder, a new fork that makes mapping even easer (thanks to UDMF btw).
    Download
    DoomBuilder 1 | DoomBuilder 2 | GZDoomBuilder

    The Lump Editor / Organizer
    "The choice is easy, it's SLADE 3"
    start_xwe.pngThere have been several tools created over the years to work with Doom's data formats. DeuTex, WinTex, NWT, XWE, etc. The only one that is still maintained and that is updated to handle the new features of modern source ports is SLADE 3. Furthermore, it also features online documentation with a dedicated wiki. SLADE features a simple and intuitive interface, can open PK3 files, edit PNG offsets, and handle many data formats including those exclusive to some source ports or used by other games. SLADE 3 also supercedes SLumpEd entirely, having all the features of its predecessors but a lot less bugs.

    Download
    SLADE 3 | SLumpEd

    The DECORATer
    "DecX - It doesn't only extract"
    start_decx.pngAs of now, there is one single tool that can help you with all kinds of DECORATE needs that you could come up with. It's called DecX, standing for Decorate Extractor but in this case, that's only an understatement. DecX is a great decorate editor with all kinds of nifty features like syntax highlighting for actor and weapon codepointers, general decorate code and it is also capable of directly testing actors in a testing environment (weapons & monsters). For newbies, this is the perfect program to work and learn with. Unfortunately, it has some limitations. Nya didn't work on this for a long time now, so the syntax highlighting and possible codeointers isn't up to date and that's somehow a problem. The only way to avoid this, is Cutman Mike's latest application (yes, the man can do more than Ghouls Lächelnd) DECORATE Assistant. The application simply pastes code for action functions and actor flags with the parameters ready to be changed, you only need to click on the system tray icon and choose the function you need and it appears in your editor or your clipboard if you prefer that. These two programs in combination and all your wishes are fulfilled.
    Download
    DecX 2 | DECORATE Assistant

    And that's all you need I guess Zwinkernd Sure, that's my personal preference and it's possible that other Doomers recommend other tools or even some more programs, but for me the ones that I've mentioned have been enough to create the Ultimate Torment & Torture, City of the Damned : Apocalypse and my ZPack submissions. Zwinkernd So I think if you have these on your hd, most of the aspects you will encounter in mapping and modding for Doom will be covered.
    -Tormentor667 (May 26th 2011)

    Read Tutorial

  • Getting Started: Tools of the Trade
    The following overview is written for people who are complete newcomers to DooM editing. It is not meant to be an exhaustive discussion on every aspect of editing, nor is it meant to identify all the tools available. Rather, these are the tools with which I am familiar. Links to much wider lists of utilities and tutorials are provided at the bottom of this page.

    Map Editing

    Purpose - To create a map in a manner that it is readily playable without requiring the player to do much additional work. (In other words, unzip, extract, and play.) Creating a map involves the drawing of lines (known as linedefs) and areas (known as sectors); designating floor & ceiling heights and light levels of your sectors; assigning textures on wall surfaces (known as sidedefs), floors, and ceilings; inserting enemies, weapons, health, ammo, decorations, etc. (known as things); and building the nodes that will make your map playable.

    Skill Level Required - Some computer knowledge is required, particularly as it relates to using a multi-function software program. Knowing the basics of geometric space is extremely helpful. Experience with computer drawing tools such as CAD is a plus, but not essential.

    Available Tools

    • Doom Builder features a 3D editing modeDoom Builder by Pascal vd Heiden, aka Code Imp, is probably the foremost map editor in use by mappers today. It is currently in its second version, features a 3D editing mode, and incorporates support for all the major source ports as well as mapping in UDMF format. If you plan to work on maps for GZDoom or ZDoom, make sure to get the version called GZDoom Builder, developed and maintained by MaxED, as it features support for slopes, 3D floors, models, voxels, translucent lines, and all other GZDoom and UDMF features in 3D mode.
    • SLADE 3 by sirjuddington is a very good all-round utility, with map-making as well as resource editing functions (see below). It's 100% free, and has documentation on dedicated wiki. Good support on its GitHub page, and the Doomworld and ZDoom forums. Cross-platform. Can be used to edit maps for source ports, supports several ZDoom and UDMF features, though not as many as GZDoom Builder.
    • WadAuthor by John Williston, is an excellent map editor that I use as my primary map-making utility. The program is easy to set up, the interface is intuitive, and the Help file is very useful. It is shareware, and must be registered after 14 days. Not currently supported by its author. It's for Windows, and has a built-in nodes builder. Can be used to edit maps for source ports.
    • DeepSea by Jack Vermeulen, is a powerful and versatile utility that does more than make maps. (See under Resource Editing, below.) The map-making portion of DeepSea is shareware, but is not time-limited. Rather, there are limits on the size and complexity of your maps. Well-supported by the author, with periodic upgrades. For Windows, and has a built-in nodes builder. Can be used to edit maps for source ports.
    • WinDEU by the DEU Team is a Windows port of the DOS version, and was updated in early 2001 with a beta version. (This link points to the non-beta release, back in 1996.) I used it very early in my editing "career", but moved to WadAuthor.

    Resource Editing

    Purpose - To modify elements of your map besides the geometry. You may have played DooM maps where the graphic textures, enemies, sounds, music, weapons, etc. looked or sounded nothing like those in DooM. With a bit of practice, manipulating such elements can become quite routine.

    Skill Level Required - Some computer knowledge is required, particularly as it relates to using a multi-function software program. Requires some understanding of the structure of a wad file (that's the file that contains all relevant information about your map or maps).

    Available Tools

    • Wintex - Old but Gold?DeepSea is a one-stop-shop for all your resource editing needs. (It is also a good map editor -- see under Map Editing, above.) While the map-making portion of DeepSea is shareware, the resource editing portions are not. Well-worth the download, although it has a fairly steep learning curve. The documentation and user support greatly help. For Windows.
    • SLADE 3 is an easy-to-use resource editing utility. It's 100% free, and has documentation on dedicated wiki. Good support on its GitHub page, and the Doomworld and ZDoom forums. Cross-platform. Can be used to edit maps for source ports. Supports many newer editing features and a wide range of data formats, including those used in other old games.
    • WinTex is a popular resource editing utility for Windows. (It also has map editing functions, but it is better known for its ability to manipulate graphics, music, and sound.) Takes a bit of learning to master this aspect.

    Hacking the Executable File

    Purpose- To modify fundamental elements of the game that are written into DooM.exe or DooM2.exe. For example, the speed with which an enemy moves or the damage inflicted by its attack are pre-defined in the executable. To modify such parameters you will need to hack into the executable file. (Now hold on there -- this kind of "hacking" is neither illegal nor is it very difficult to do. Read on.)

    Skill Level Required - Because of the relative simplicity of the tools available, not a great deal of computer savviness is needed. You will need to familiarize yourself with some new terminology, for which there is no substitute for reading the manual.

    Available Tools - The most widely used tool for modifying in-game parameters is DeHacked, by Greg Lewis. It's been around for a while, and will run on DOS, Win95, Win98, and Win2K. (I haven't yet tried it on WinXP.)

    Other Resources - Visit Nigel Rowand's Little Place of DooM for well-written and informative tutorials on DeHacked.

    Want to Learn More About DooM Editing?

    More Utilities Than You Can Shake a Stick At - Visit DooM World's Editors and Utilities Page for a long list of available tools.

    DooM Editing Tutorials

    • ZDoom Tutorials by Rick ClarkThe Unofficial Wad Designer's Handbook by Ron Allen & Bill McClendon, is a well-written and easy to understand document. While it is not illustrated, the authors have provided links to examples that demonstrate what they're saying. This is another tutorial I used when I started DooM editing. It's classic, but it covers a lot of things that are still up to date and very interesting for newbie mappers - recommendation!
    • Rick Clark's Editing Tutorials, while they deal primarily with ZDooM editing, also have some very nice discussions on the basics (scroll to the bottom of the page and look for the "Tools" section). Rick's tutorials are great because he uses illustrations to good effect throughout. This is another resource I used extensively, particularly when I started editing for ZDooM.
    • DooM World's Editing Tutorials page has many more links to tutorials on basic as well as advanced DooM editing.

    Read Tutorial

  • Layout & Structure in Doom

    Doors

    Standard doors (or those which do not feature remarkable linedefs and/or which are assigned a typical door texture) are for the most part used scarcely in Doom. Doors which require keys, lead to secret areas or are activated by shootable switches or walkover lines are to be considered exceptions to this generalization as they typically do little to disrupt the fluidity of gameplay. Doors serve more toward area segregation and combat control than as aesthetic dividers, and are used to grant the player easier navigation and time to either prepare or contemplate before entering the next room. As is often the case, this somewhat liberal use of doors allows the mapper to create a contrast in design between rooms separated by doorways, lending to some interesting shifts both visually and in terms of gameplay.

    Here’s a selection of maps from each episode that we may use to illustrate door use, as well as a general overview on how doors are used between episodes:

    Knee-deep in the Dead:
    Of the three episodes, Knee-deep in the Dead uses regular doors the least. Most areas are separated by shifts in height or direction, which differs greatly from the slightly more uniform layout of maps in The Shores of Hell, and to a lesser extent Inferno. However, there is still a great deal that may be learned from the study of door use in E1. E1M3, 4 and 7, for example, all place the player in a room isolated from the rest of the level by a standard door.

    E1M1
    The first and only standard door (if we choose to exclude the exit for its being canon) allows the player to prepare before encountering the first monster in the game. It is expected that the player is still getting to grips with the controls of the game at this stage, and having a door here gives the player time to set his priorities and make the game move at his pace. Since M1 is a small and linear map, the function of the door could be seen as similar to those used in E3M1 for example, which is equally a one-way street. Doors cannot really obstruct the flow here as they are passed through only once (see M7 below for further examples).
    E2M1, if we are to take the final M1 counterpart, is an also linear map which introduces teleporting to the player, and so the role of the door as a means of compartmentalizing and segregating areas is somewhat usurped, or at the very least expanded upon.

    layoutandstruct1E1M7
    At the opposite end of the episode is E1M7, which interestingly features only 3 standard doors of 17 in being perhaps the second most sophisticated level in the episode after M6.

    The use of all three keys and a considerable amount of backtracking makes the use of doors particularly interesting. The lowermost door indicated [O] leads off to an optional area of the map which is not reachable via any other means, while the centremost door indicated [F] similarly leads off to a segregated area, but one to which a visit is deemed necessary for the player to complete the level. With the first example we might accept that the player will be unlikely to return to the southwest part of the map, and so the use of a door helps familiarise the player with the area beyond it through compartmentalization. Similarly with the second example, the centremost regular door (which stays open), the player is unlikely to visit the northwest portion any more than once, the red key having been obtained. Between these two doors however and elsewhere in the level the player is quite likely to revisit areas more than just once for both access and explorative purposes. The rising pillar, for example, gives the player access to the flanking slime pits in which multiple secrets reside, while the overlook closer to door F surveys these accessible areas.

    The topmost door indicated [.B], just as with M3 and 4, allows the player a moment of collection, as well as a chance for the music to intimidate the player!

    Other doors:

    • Doors [E] and [I] are trap doors which are located in areas that see heavy traffic. Door [C] is an exception to this, as the player is likely to only pass by the one time, but critically, all three examples occur in somewhat unpredictable locations, rather than immediately behind the player following the collection of the yellow or red keys, for example.
    • [L] is a rather interesting door that can probably be certified in being aesthetic rather than practical. Note the unique switch rather than door texture here.
    • Door [J] is located within a trap location. The player is rewarded by exploring new facets of the level as they open up, however small.
    • [P] is a remotely controlled door.
    • As with all other maps in the episode bar the final one, door [Q] is the signature exit door leading to the “airlock” or “exit chamber”.

    The Shores of Hell:
    Doom’s second episode is where doors are first seen being used in drastically different ways, no doubt as a by-product of Petersen’s mapping style. Whereas Romero’s door deployment is more precise and controlling, Petersen’s is a great deal more haphazard, if not impossible to deduce. If you’re mapping for The Shores of Hell, you could probably get away with a great deal more in this department than you might in the first, and even in the third episode.

    layoutandstruct2E2M5 & E2M6
    These two maps, fortunately, have a very distinct procedure when it comes to door placement, in that they both feature very tightly framed doorways that branch off from a central passageway or area. The below diagram indicates, as before, the whereabouts of all the standard doors (those without remarkable linedefs and which are not secret related), but also the use of standard doors using a switch texture as indicated by the blue circle; a trend which is largely omitted in other maps of the game (E2M7, E3M3 and E3M5 sees some semblance of this style return, but it is here that the epitome resides!).

    An astounding 35 doors in E2M5 sees the player drawing to a halt almost every couple of paces, and at first glance the whole setup can seem sort of chaotic. However, there is a great deal of order to the door arrangement here both stylistically and with relation to gameplay.

    You will notice that a few of the doors lead to areas that, unlike E1M7, are not accessible only from one direction. Indeed, there are still many that do (such as with [M], [J], [Q], [A2] and [F2]), but there is a great deal of connectivity here, regardless of most entrance and exit points being located just feet from one another. Doors [A] and [G], [V] and [W], and [X] and [Y] all lead to looped pathways/areas, giving a stronger sense of perceived non-linearity, and many others such as [I] and [R] or [H2] and [I2] are linked via distinct, feature filled areas. A key thing to take note of here is that even the passageways are detailed. In addition, many of the blue circled doors (those which have a switch texture) branch off from hub-like areas.

    With regards to gameplay, it is plausible to suggest that the doorways were used as a means to encourage the player to go exploring. While vast tracts of secret area are stowed away in the northwest of the map in a place which is everything but compartmentalized, there’s a great deal of goodies stashed behind closed doors.

    Other doors:

    • Door [T] is less so a door than it is a lengthy passageway that functions as a door in its entirety. Though the placement of the door-passage itself is purposed with hiding a secret area, the effect that is created might be considered wholly aesthetic.
    • Doors [Z] and [A2] are placed symmetrically opposite each other, but [A2] leads to an area of questionable significance. In this case, the map’s symmetry takes priority over any indication of where to go, and is further indication that the doors here serve solely to compartmentalize rather than control combat.

    Inferno:
    For the most part, the use of doors as presented in E2 is replicated here, but a decrease in orthogonal design and an increase in abstract shaping sees substantially less intricate compartmentalizing of the sort seen in E2M5 and conversely more focus on the aesthetic - though not obstructive - and the experimental. Those who are mapping for E3 should seek to consolidate the flow retention seen in E1 with the more abstract or even gimmicky qualities of E3 maps such as Limbo’s gate system, Cathedral’s patterned layout, or Slough of Despair’s severed hand...

    E3M1
    As was mentioned with E1M1, E3M1 is a linear map that employs a many doors of which are passed under only once. There’s not an awful lot to say about this one except that it affirms an increase in standard door permissibility where linearity is descriptive of level progression.

    layoutandstruct3E3M5

    Unholy Cathedral has a monumental 38 doors in total, but pulls of the impressive feat of not having a single one of these standard doors interfere with the flow of gameplay. This is because they are not at all spread out, unlike in E2M5 or 6 for example, and are in fact grouped strictly with regards to map layout. Each group of four, central doorways links the corners of the map to the centre, and the player is able to deduce extremely quickly because of the remarkable structure of the map just where all the doors will lead, and how to navigate from one corner of the map to the other. In an instant, almost all of the doors in the map are less an obstruction and more an indicator of where to go. It is the perfect example of how best to combine symmetry with door usage while still giving the impression of having ample space to run around in and a clear sense of location and baring.

    Also important to note are the first 4 doors in the map which allude to the maps structure and means of progression before the player has even made a move. After passing through one doorway and observing the way in which the map curls around the centre, the player, just as before, is able to develop an idea of where those other doors might lead.

    Other doors:

    • Secret doors [A] and [F2] are marked not by any offset, but by their positioning between two symbols. This is an interesting design motif that is usually unseen in other wads, where it is preferable to have decorations, lighting or texture variation give away a secret location.
    • Doors are substituted twice in this map for another unique design motif involving the simultaneous raising and lowering of interlocking bars to allow passage. Both examples (in the north and northwest areas) lead to areas of the map that are somewhat distinct from the rooms adjacent to them.

    Summary

    • Regular doors are used sparingly in general, though even less so in episode 1.
    • Regular doors are used less in areas that see a lot of heavy traffic, where other design motifs such as height and direction are used to separate areas and retain flow.
    • They are mostly used as area dividers and for combat control rather than for aesthetic purposes, although in Petersen's case the two can be made to cooperate under a highly stylized motif.
    • Irregular doors (secret doors; key doors etc) are exempt from following any strict rule set, and may be used freely as long as they adhere to strong connectivity.
    • Petersen loves using doors to compartmentalize areas both central and extraneous to map progression.

    Lifts

    It might seem a trivial subcategory to go under Layout and Structure, but there’s a considerable difference between how lifts are used in most modern maps and how lifts are used in id’s. In Doom’s case, most lifts are not used for rescuing players from slime pits, for instance, or for entirely separating areas such as is the case with doors. Instead, they function as dividers within an area, as an atmospheric piece, or again as a means to control the flow of combat. Crucially with regards to this last point, the speed at which they rise or lower can make them a unique tool for forcing a player’s stay in a combat scenario, whereas a door might allow an easier escape. Lifts, like standard doors, are not all that common in Doom.

    Let’s take a look at a few of the ways in which lifts are used in Doom, to what effect, and in what ways they might be exclusive to each episode. If at all.

    The Raised Platform:
    This is a basic technique which is commonly used in Doom, and especially in the first episode. Simply put, it is a lift that doesn’t lower or raise the player into an area that is out of sight when viewed from the top/bottom. While all lifts in Doom are technically “raised platforms”, this name is meant to signify the fact that many lifts do not really separate different areas, and can be seen more as a means to get from one part of an area to another (If we are to pinpoint what exactly is meant by “area” in this case, we can suppose that it is in most instances the movement from one distinct location to another via a sort of geometric standard in connectivity - doors, teleporters, connecting lifts, hallways/tunnels etc.), often accompanied by a shift in visual style. In episode 1 they will often take the player to a ledge, doorway or dead-end rather than leading them to another part of the base.

    Here are a few examples of the raised platform type as seen in Doom. Please skip to the summary of this chapter to view some of the discrepancies in lift use between episodes:

    layoutandstruct4

    Example #1

    At the top of both lifts featured near the starting area of E1M2 is a ledge. The ledges themselves cannot really be considered a separate area, and although the area surrounding the lifts at the lowest point is probably too small to be considered an area either, the lift does not raise the player into a area which could not be seen by the player prior to being stepped onto.

    Example #2
    Again in E1M5 and 6, we see more raised platforms. However, both of these lead immediately to doors rather than ledges, though all 4 examples showed so far lead to places that are incredibly small by themselves. If we are to count in such examples as the lift next to the secret exit of E1M3, the chaingun secret in E1M3, the blue L shaped ledge reached from the lift in E1M4 and the yellow key area of E1M7 (as well as behind the yellow doors), we begin to see how, as previously mentioned, many if not the majority of lifts in episode 1 take the player into some sort of cul-de-sac or doorway.

    layoutandstruct5

    Example #3

    E2M4 is one of the few maps in episode 2 that actually features lifts, so when we are discussing how they are used between episodes it’s worth keeping in mind that if they are to be used at all, this is probably the best map from which to draw principle. The raised platform lowering into the circular pit here is similar in a way to the non-raised platform - or closed lift - that is used at the end of E1M2 (see below). In this case, a switch needs to be pressed in order to lower the lift, and its functioning as both an atmospheric piece and as a way to prevent the player from escaping quickly the many Barons and Cacodemons is affirmed (note too the spinal texturing).

    All the lifts in this map are raised platforms, and two of them lead into symmetrical areas. It is similar to Petersen's E1M8 in that the room of symmetry is aligned with a lift, but different in that one lift is "closed" and the other is not, a point which could either show the triviality of differences between the proposed lift types or the further tension gained by sealing the player from view of the Baron's lair.

    The Closed Lift:
    There certainly aren’t many lifts of this sort. Unlike the raised platform, the closed lift is encased by wall from all sides bar the point of entry (prior to being stepped onto). It blocks the player from view of its destination, which can be incredibly useful in such circumstances as the aforementioned E1M8 or E1M2, as shown below, where the mapper intends to surprise or bewilder the player as they are struck by new surroundings. Closed lifts are perhaps the best example of how lifts may be used to separate areas in a similar way that many doors do, and so to that end whether or not the player uses it is a matter less to do with blocking the player's view but maintaining a sense of diversity in tight spaces.

    Example #1
    E1M2’s descending lift toward the end of the map is perhaps the best known example of this lift type. It forces the player into a somewhat difficult situation, and intends to prevent him from escaping without at least some damage being sustained or the opposition killed. It is also accompanied by a sudden albeit analogous shift in lighting. In other words, it is intended to push the player into harms way. It may also be worth noting the introduction of remote switches as a means to open doors (disregarding the earlier secrets), which is again similar to E2M4's own introduction for lowering lifts remotely. In both circumstances the player is required to work out how to escape the sudden ambush should they opt against killing everything off.

    layoutandstruct6Example #2

    E3M3’s closed lift has no monsters waiting at the bottom. Nor does it have any real shift in lighting or effect. It simply stands to segregate the areas in their style. The dual stairwells that branch from the symmetrical wooden area close to the start represent a similar shift, but if we are to consider the geometry here we might also suppose that the lift was opted for to conserve space and retain variety: something this map does particularly well on the whole. Again, it’s use is somewhat experimental, and it lends the purpose of the closed lift to the mapper’s discretion, if not at all proving it to be hopelessly negligible.

    The Doorlift:

    Exclusive to E3M1, the mighty doorlift is as its name implies: a door that lowers as a lift rather than raises as a door. It is difficult to provide any explanation as to why this trick is performed other than to say that it was probably intended to freak out the player a little bit. “Now you’re really in Hell!” sort of thing.

    Summary

    • Episode 1 consists of many “raised platform” style lifts, and the majority of lifts in episode 1 take the player into either a cul-de-sac, ledge or doorway of some kind.
    • Petersen uses lifts considerably less than Romero, but uses doors considerably more!
    • Petersen seemingly does away with Romero's tendancy to use lifts as dividers rather than gateways to new areas - regardless of type
    • Episode 2 has almost as great a lack of lifts as episode 3. The few that are seen are followed either by areas of symmetry or violence, or function simply as raised platforms without the first episode's trait of leading the player to a dead end or door. The lack of lifts allows for a bit of variety as to how they should be used here.
    • Episode 2 introduces switches as a means to lower lifts.
    • With the slightly ambiguous use of the “closed lift” in E3M3 and the use of the mighty "doorlift" in E3M1, Episode 3’s use of lifts, though limited, reveals the more aesthetic principles underlying the unequivocal quirkiness of Hell. Even more so than episode 2 thanks to the abstractedness in design, the mapper is free to experiment with lifts as long as the number of lifts used remains... well, close to zero.

    Teleporters

    Doors and lifts exist. This much is true. But because teleporters don’t yet exist, were relatively new inclusions to the virtual gaming world on account of its being so young, and because Doom is a game of emersion, how teleporters are presented even before the considering of their use with regard to layout and structure is critical to their implementation. This chapter covers both how they are presented and how they allow the player alternative (or necessary) means of navigation. The two never seem to correlate, but they are of equal importance.

    layoutandstruct7Episodic Differences
    With only two of the three teleporters featured in Knee-Deep in the Dead being usable by the player, and only one of those two taking the player to a location that won’t see him torn to tasty strips in a matter of seconds, it might seem at first reasonable to say that the role of teleportation in episode 1 is negligible. Quite to the contrary however, the inclusion of teleporters in episode 1 is of great importance because of its being central to the story of the game. Having a teleporter feature in a secret area of Phobos Labs demonstrates clearly the intended experimental nature of teleportation in this episode, as does perhaps the red cobble texture for representing the “red dust” over which the anomalies were built; so explained in the Doom Bible. Clearly its use here is aesthetic and does not in any drastic way alter gameplay or change the means by which one might realistically navigate the map, but it remains relevant to the story, and in that sense necessary to making any mock Knee-Deep in the Dead episode a complete one; provided an identical storyline.

    With The Shores of Hell and Inferno episodes teleporters are used primarily as gameplay devices central to map layout and navigation. Between both of these episodes little difference can be seen, but there are a couple of things worth mentioning. Much like the lifts in episode 3 being used more experimentally, teleporters here seem almost to transcend any set of rules that they should follow with regard to their appearance (see below). Presumably, this is because the laws of reality in Hell are suspended, and teleportation is a slightly less remarkable or perhaps even naturally occurring phenomenon that merely requires a lesser means of establishment (a plain texture). Consider, for instance, the Demon in E3M6 that teleports just a few feet upon sighting the player in the wooden building to the east.

    Episode 3 teleporters are often one-way, in addition, and in E3M6 will typically take the player to a destination which is visually bare of teleport markings. We could claim this to be something unique to an outdoor setting in Hell or as a result of an increase in teleport permissibility due to there being a Hell, or we could simply put it down to preference and allow unremarkable teleport destinations to occur in any episode 3 environment.

    Finally, episode 2 teleporters often give the impression - through the various shifts in design that the 3rd episode often lacks - of being either manmade or demon made (again, see below under “appearances”). This strengthens the concept of the Deimos base undergoing demonic subversion.

    layoutandstruct8The Dumbbell Complex
    Now then. Call me an inadequate wordsmith, but it’s true what they say about pictures. Here’s one of them now!

    Harmless looking enough, isn‘t it? But just in case you don’t yet have a strong enough idea of how teleporters are used (turbo pun!), or haven’t quite gotten to grips with how they are presented, here’s a pretty handy analogy for you to memorize:

    Teleporters in Doom are never used trivially except in the sole case of E1M5 - for reasons I hope have been made clear enough. Episodes 2 and 3 really focus on using them primarily as integral gameplay elements, but that isn’t to say that they completely disregard their impressive implications. Remember that the idea of teleportation was a great deal more popular in the 90’s in the realm of science fiction, hence its inclusion, and to have the player merely teleported from one side of a room to another - for however practical a reason - wasn’t doing it justice.

    You really had to go places.

    Where does the dumbbell come in then? If we assume that each weight on a dumbbell is representing an entirely separate area in a Doom map, and that the handle between the two weights is the line of teleportation, then we can apply this image to every single use of teleportation in the entire game and find that both the point of departure and the destination lie in separate areas and that the analogy holds true - with just one exception (that exception being E3M5. We can call this a “Waffleport” or a piece of Swiss Cheese if you prefer. I’ll let you figure out why). Obviously this is a super typical use of teleporters and isn’t anything at all unique to the stock maps, but it needs mentioning because of how the respective areas are designed aesthetically with relevance to this original “idea” of teleportation. In exaggeration it would be the difference between teleporting from the Himalayas to the Amazon in one instance and a living room to a lounge room in another. There are, interestingly, many ways in which we can show this without the need for silly dumbbell analogies, although it would require digging into far less objective grounds...:

    First Impressions
    What do you want the player of your map to see when they arrive at the other side of your teleporter? Reminding ourselves of the “closed” lift type which encourages a greater shift in atmosphere or pace of play due to a sudden revealing of information (E1M8; E1M2), the teleporter will unfailingly thrust the player into a new bearing. It’s what the player sees first off that causes me to draw this comparison with the closed lift, as this can promote a greater sense of shift in an area even if it is otherwise pretty similar.

    layoutandstruct9Case in point is this teleporter in E3M5. Instantly your movement stops. You click into a different mode. You can’t just barrel through these idle Demons without getting munched on. Note however that the room is otherwise fairly ordinary. More ideally the shift in geometry would be pretty considerable, but this is an effective way to take good advantage of the sudden shift while keeping consistent with the Doom design. Put something of value to see right at the immediate, and to be even more effective make it more than just visual impact. If you can change the player’s train of thought or pace of play, you’ve bagged yourself a real winner.

    Other examples include E2M1’s Demon ledge, E2M5’s Lost Soul surround (secret), and E2M4’s scrolling face texture (note that this texture had not been used up until this point).

    layoutandstruct10Appearance
    The appearance of the Doom teleporter is an important one, and not something that is restricted to mere texture selection. Geometry is vitally important, and it’s evident that the game designers were interested in having teleporters thought of not simply as a set of linedefs for the player to step over but as physical world objects / setups - like doors and lifts. Episode 1’s teleporters are obvious examples of this with their five point stars (the scientists behind them possibly (un)intentionally emulating a necessary demonic design), but let’s look at some of the latter cases:

    E2M1’s first teleporter is an immediate departure from those couple seen in the first episode, but not just in its size, shape and texture. There are candle decorations surrounding it for starters, giving the air of a ritual having taken place, and there is a mock star shaped step as well, which could easily mean to be a makeshift mound of some sort; something the demons might have placed in hurried preparation. E2M7’s teleporter is almost gate-like in its appearance, and is similar to the previous example in that it too appears makeshift, what with the tunnel branching off from an insignificant looking vat, as though it had been bored out in secret.

    As mentioned, Episode 3 forgoes some of these design principles and opts for just having a plain teleporter texture with no real geometric feature. Admittedly E2M1 does this as well with the exception of the first, but when we consider the connection between teleportation and anomalies as presented in the Doom universe we can make sense of the fact that again, as mentioned, Hell and teleportation are fairly synonymous. The visuals can be downplayed.

    Summary

    • Episode 1 teleporter use is primarily aesthetic, but is also implicit in the portrayal of teleporters in the Doom storyline (experimental; mysterious etc.). They are therefore key to the identity of the first episode.
    • Teleporters featured in episodes 2 and 3 take greater priority in gameplay than in the aesthetic, but do not forego the latter in favour of this gameplay; particularly in the case of episode 2.
    • In almost every case, teleporters take the player to and from completely distinct areas (the dumbbell complex).
    • In both episodes 2 and 3 it is important to impress the player with what is immediately seen upon exiting a teleporter, taking advantage of texture usage and monster positioning / facing in particular.
    • Teleporters are thought of typically as actual geometric objects like doors or lifts are rather than just a set of linedefs.
    • The previous point having been mentioned, the appearance of teleporters in episode 3 can be downplayed slightly, featuring either just the typical teleport texturing as opposed to any unique geometric feature or even no texture at all.

    Read Tutorial

  • Making a powered/unpowered weapon
    Every once in a while, I see a post asking how to make weapons affected by a Tome of Power, or a weapon that doesn't implement it 100% correctly, so here's a tutorial to explain it.

    First off, there are three wiki pages to look at:

    • PowerupGiver with the Powerup.Type WeaponLevel2: This is the powerup that activates it. For creating a new weapon, it's not necessary to deal with, but it helps to explain how the system works. For testing, you can use the Powerup console cheat to activate.
    • Weapon.SisterWeapon: This goes on both the unpowered and powered weapons, it's what tells the WeaponLevel2 powerup what weapons go together.
    • +Weapon.Powered_Up: This tells it what weapon to use when under the effects of a WeaponLevel2 powerup. Without this or Weapon.SisterWeapon, it can't work.


    I'll use Doom's Pistol to illustrate. This is it before we add support for WeaponLevel2.


    Actor Pistol2 : DoomWeapon 5010 //This is named differently so it won't conflict with Doom's
    {
      Game Doom
      Weapon.SelectionOrder 1900
      Weapon.AmmoUse 1
      Weapon.AmmoGive 20
      Weapon.AmmoType "Clip"
      AttackSound "weapons/pistol"
      Obituary "$OB_MPPISTOL"
      +WEAPON.WIMPY_WEAPON
      Inventory.Pickupmessage "$PICKUP_PISTOL_DROPPED"
      States
      {
      Ready:
        PISG A 1 A_WeaponReady
        Loop
      Deselect:
        PISG A 1 A_Lower
        Loop
      Select:
        PISG A 1 A_Raise
        Loop
      Fire:
        PISG A 4
        PISG B 6 A_FirePistol
        PISG C 4
        PISG B 5 A_ReFire
        Goto Ready
      Flash:
        PISF A 7 Bright A_Light1
        Goto LightDone
        PISF A 7 Bright A_Light0
        Goto LightDone
      Spawn:
        PIST A -1
        Stop
      }
    }

    To get started, we create a second weapon inheriting from the pistol:


    Actor PoweredPistol : Pistol
    {
      States
      {
      Fire:
        PISG A 4
        PISG BB 0 A_FirePistol //Added this just to make it different
        PISG B 6 A_FirePistol
        PISG C 4
        PISG B 5 A_ReFire
        Goto Ready
      }
    }

    You'll notice there is a LOT less code here, in the powered version. That's because with inheritence, it's getting information like states and properties from the original. If you want to change anything, replace it in the new version, like with this Fire state.
    Something to remember, if the powered version has its own Ready state, it will play the Lower and Raise animations when the WeaponLevel2 powerup starts and ends. You can see this with the Staff in Heretic.
    Next, we add Weapon.SisterWeapon and the +Weapon.Powered_Up flag.


    Actor Pistol2 : DoomWeapon 5010
    {
      Game Doom
      Weapon.SelectionOrder 1900
      Weapon.AmmoUse 1
      Weapon.AmmoGive 20
      Weapon.AmmoType "Clip"
      AttackSound "weapons/pistol"
      Weapon.SisterWeapon "PoweredPistol2"
      Obituary "$OB_MPPISTOL"
      +WEAPON.WIMPY_WEAPON
      Inventory.Pickupmessage "$PICKUP_PISTOL_DROPPED"
      States
      {
      Ready:
        PISG A 1 A_WeaponReady
        Loop
      Deselect:
        PISG A 1 A_Lower
        Loop
      Select:
        PISG A 1 A_Raise
        Loop
      Fire:
        PISG A 4
        PISG B 6 A_FirePistol
        PISG C 4
        PISG B 5 A_ReFire
        Goto Ready
      Flash:
        PISF A 7 Bright A_Light1
        Goto LightDone
        PISF A 7 Bright A_Light0
        Goto LightDone
      Spawn:
        PIST A -1
        Stop
      }
    }

    Actor PoweredPistol2 : Pistol
    {
      Weapon.SisterWeapon "Pistol2"
      +Weapon.Powered_Up
      States
      {
      Fire:
        PISG A 4
        PISG BB 0 A_FirePistol //Added this just to make it different
        PISG B 6 A_FirePistol
        PISG C 4
        PISG B 5 A_ReFire
        Goto Ready
      }
    }

    That links them together. It should be just that easy; when a WeaponLevel2 powerup is activated the Pistol2 weapon will automatically become the PoweredPistol2 weapon. You now have a version of Doom's pistol that can be affected by a Tome of Power.

    Read Tutorial

  • Making Sprites from Models

    This tutorial provides step-by-step instructions for creating sprites for ZDooM or GZDooM from models. You can use essentially the same steps to create sprites for vanilla DooM/2 or or for other source ports, but you may need to use a different file format than the one primarily covered in this tutorial (i.e., png format), which could result in reduced resolutions and additional steps. This tutorial does not cover every possible way of undertaking such a task; rather it provides one possible way that I have found to be reasonably effecive. For this tutorial I will provide an example for Barney (the security guard) from Half-Life.

    Section A. Extracting Models and Capturing Images

    1. Browse the installed version of Half-Life on your hard drive. Typically, the path will be:
    C:\SIERRA\Half-Life\valve\models\player\barney
    2. Select the file 'barney.mdl' and copy it to the folder of your choice (e.g., C:\DooM\HLDooM\Sprites)
    3. Use a utility such as Half-Life Model Viewer (the newest version appears to be Jed's HLMV 1.3.5) to open barney.mdl. The rest of the instructions in this section are based on this utility.
    4. From the Sequences tab use the drop down menu in Animation Sequence, and select the model's first position. In this case I have selected 'deep idle'. [The default is walk, and the model will be animated. Use the Stop button at the bottom to stop the animation.]
    5. From the menu select 'take screenshot'. An image in .tga format will be saved to the same folder in which your barney.mdl file resides
    6. Click on the model and move your cursor to the left. When you have positioned the model in your next position, take another screenshot. I moved the model to the position of a "quarter turn". In other words, if the start position represents the hour hand at 6 o' clock on an analog timepiece, the quarter turn to the left represents the hour hand at 7:30.
    7. Repeat Step 6 until you have taken a total of eight screenshots. [Note that you can move the model an eighth of a turn, so that you wll have a total of 16 screenshots. This will give you a "smoother" rendered animation, but also requires a great deal more work (especially if you want animations for idle, walk, run, attack, and death sequences) and will take much more disk space.]
    8. Select the model's second position. In this case I have selected "walk".
    9. Repeat Steps 5 through 7 for the first set of walking animation screenshots.
    10. Using the arrow (Speed) buttons in the Sequences tab, advance the frames to the next desired position of your model's walking animation and take a screenshot. In this case I advanced the position until the model's rear leg had moved to be level with the fore leg. In other words, this is the mid-position of the model's stride. Again, I selected this mid-position for economy of work and frames. You have the option of five additional positions between the start of the walk sequence and the mid-stride.
    11. Use your cursor to move the model to your left until you have reached the desired position, and take a screenshot. If you are using 8 frames for the 360 degree rotation of your idle sprite, I suggest you continue to use 8 frames for each of the remaining positions of your sprites' various animations.
    12. Repeat Step 11 until you have taken a total of eight screenshots.
    13. Repeat Step 10 until the rear leg (now the fore leg) has reached its forward-most position, and take a screenshot.
    14. Repeat Steps 11 through 12 for the second set of walking animation screenshots.
    15. Advance the model's walking frames to the next mid-stride and repeat Steps 11 through 13 for the third set of walking animation screenshots. At this point you are done with capturing frames for the walking animation.
    16. Select the model's next position (e.g., run, shoot, death, etc.) and repeat Steps 5 through 15 as necessary to capture a complete set of animation frames for that position.
    17. Repeat Steps 5 through 16 for as many positions as you desire. When you have a complete set of sprites for your character move to the steps in Section B, below.

    Section B. Converting Captured Images

    1. Use a utility that will allow you to convert your images from .tga (TARGA or Truevision Advanced Raster Graphics Adapter) format to .bmp (bitmap) or .png (portable network graphics) format. I have identified these two formats as they are both supported in ZDooM and GZDooM. My preference is to use .png format, because the final file size is considerably smaller than that of a comparable .bmp file. Moreover, .png format images retain their color pallettes, so even though each image may only have a finite set of colors, several images will collectively have a far greater range of colors. To convert and modify images from .tga to .png format I use a simple but effective utility known as XnView. It is available for free, and I believe the latest version is v1.90.2. The rest of the instructions in this section are based on this utility.
    2. Use the browser in XnView to find the .tga images that you created in Section A, above.
    3. Select the first image and double-click on the image to open it up in a new tab within XnView. In my case the first image was barney01.tga.
    4. From the menu bar select File\Export. This will open an Export window from which you can make your format selection.
    5. Select the PNG tab, in the color mode select 256 Colours (Adaptive), and select Set Transparency Colour ... [Notes: I have recommended 256 colors for file size considerations. If you choose the default of 16 million colors you will get a large file, and I'm not even sure that ZDooM or GZDooM will actually render the image in all its colors. You must select Set Transparency Colour ... in order to assign a transparency property to the background of your image. If you do not, the character sprite will be displayed in-game with a colored, rectangular "box" around it. The defaults for the other options are: no interlacing, compression level 7, and no filtering. I have chosen to stay with these defaults.]
    6. An "Edit Colormap" window pops up. Find the cell with the color that matches your background color. In my case the color is RGB 68,130,132, and if you started with barney.mdl you will likely have this color too. Select this color, and the Index number along with the RGB values are displayed in grey text on the right of the window. Note that the Index value for this "transparency" color may change from image to image. In other words, the cell with that color may not be in the same position from one image to the next.
    7. Select the "Enable Transparency" box. This step is essential, so do not forget to check the box. Click OK, and you will be returned to the Export window. If you compare the file sizes, you will see that there is a HUGE reduction in file size (without a corresponding reduction in image quality). For example, my .tga file is 666.04 kB while my .png image is only 12.89 kB.
    8. Press the 'Save' button and you will be prompted for a file name. The default is the original file name with a .png extension. Change your file name if you wish, then press 'Save' again. You have successfuly converted your original .tga format image to a much smaller .png image. [Note: I recommend that you limit your file name to 8 characters, as wad editors such as XWE (and DooM in general, I believe) only recognize the first 8 characters of a lump's name. So, if you have two files named BarneyIdle01.png and BarneyIdle02.png, the second image will be ignored because there already is a lump with the name BarneyId.png.]
    9. Repeat Steps 3 through 8 for your remaining images.

    Section C. Modifying Captured Images

    1. You will notice that the "transparent" area of the image is much wider and taller than you need for a sprite. You will need to crop the image to a more reasonable size. Again, I have used XnView to do the job, but I imagine that other image editors will work just as well. [Note: I have tried to crop the image using MS Paint, and for some reason the transparency property seems to disappear upon saving the modified image. For this reason I recommend not using MS Paint for this task.]
    2. In XnView, use the browser tab to find your first .png image. I have found that XnView often does not refresh the browser, so that files you have converted from .tga to .png format in Section B, above, may not be displayed. To rectify this, simply select View\Refresh from the tool bar, and the converted images will appear. Double-click on your first .png image, which will open in a new tab.
    3. Use the ZooM tool in the tool bar to make your image larger. I typically click the button twice to bring the image to a reasonable size.
    4. Click your cursor on some part of the "transparent" section, not too far wide or high from the character image. Drag your cursor so that you have a box around your character. Don't worry if you fall short or go too far; the program allows you to modify your box. Drag and drop the edges of the box until you have a one-pixel margin around the top, bottom, left, and right edges of your character.
    5. From the tool bar select Edit\Crop. Your image will be cropped to the dimensions you indicated by your box.
    6. From the tool bar either select File\Save or File\Save As, or click on the Save As icon. Depending on your selection you will either be told that a file with the same name exists and aked if you want to overwrite it, or will be prompted for a file name. Make the appropriate responses, and you will have successfully modified your image to be more suitable for use in DooM.
    7. Repeat Steps 2 through 6 for your other images.
    8. At this stage you can opt to resize your images. Resizing is different from cropping in that the latter simply removes unwanted areas of your image, whereas resizing enlarges or shrinks the entire image. To resize, use the browser in XnView to find and select your image, double click on it, and select Image\Resize from the tool bar. A Resize window pops up, from which you can make your desired enlargement or reduction. You can either manually enter the Screen Size width and height, or use the Standard Size drop-down menu to select the desired size or percentage. Select OK, which will result in your image being resized, and save the file. [Important Note: Because of the daunting dimensions of the images you get at the end of Step 7, you may be tempted to shrink your images for use in DooM. Doing so will result in a loss of resolution, without significant benefits if you are going to use ZDooM or GZDooM. First off, there is no change in the file size (as a matter of fact, my file size increased factionally with a 50% reduction in size. Second, with the Scale feature in (G)ZDooM you can scale the sprite down in-game without any loss of resolution. Accordingly, I recommend that you do not shrink your images in a graphics editor.]

    Section D. Inserting Sprites Into a Wad

    Now while most DooM editing folks are quite familiar with how to insert sprites into a wad, the insertion of png images as sprites may not be quite as intuitive. As such, I have outlined a few steps that will allow you to insert your png sprites into a wad with the least amount of effort. I will illustrate this section through the use of XWE, a free DooM editing utility, although DeepSea and other utilities will be more than adequate for this task. Make sure you are using the latest version of XWE (currently a Beta version, available at XWE Beta Downloads), as v1.16 does not support png transparency, automatic sprite offsets for png images, etc.

    1. To allow XWE to automatically offset your sprites you should rename them using the common DooM nomenclature before importing them into your wad. For example, I named the idle Barney sprites BARNA1-BARNA8, the first set of walking sprites BARNB1-BARNB8, the second set BARNC1-BARNC8, and so on until the final set of walking sprites as BARNE1-BARNE8.
    2. Open XWE and select the wad into which you wish to insert your sprites. If you wish to create a new wad, simply select File\New from the menu bar.
    3. Select View\Options from the menu bar, and an Options window will pop up. Go to the Special tab, and make sure the Always Load PNG Files as Raw Data box is checked off (I believe this is the default, but make sure). Select OK to exit the Options window.
    4. At the bottom of the screen is a Filter Tool Bar, in which one of the selections is Sprites. Double-click on this selection, and a browser window pops up. Navigate to the appropriate folder, and select the sprites you want imported. Make multiple selections if you wish, as this will save time to load the images into the wad. Press the Open button, and XWE will properly import your png images, put them between the appropriate SS_START and SS_END markers, offset the sprites, and assign transparency. You have successfuly imported your sprites into your wad.

    Section E. Animating Your Sprites

    Animating your sprites will require the use of DECORATE in ZDooM or GZDooM. As this discussion is not meant to be a tutorial on the use of DECORATE, I will not go into the different variables, but will focus on a few key aspects. If you wish to create your character definition from scratch, feel free to do so. I have chosen to start with an existing definition for a DooM 'actor' that most closely resembles the Barney character - the ZombieMan (basic Trooper). You can start with pretty much any DooM enemy, but as both Barney and the ZombieMan are human (at least in origin), it makes sense to model the former after the latter. Stock definitions for all DooM enemies may be found in the ZDooM wiki or at mancubus.net.

    1. Open up a text file in MS Notepad, and name it DECORATE.txt. Copy the relevant actor definition from one of the sources listed above into this text file.
    2. The first (non-comment) line will be: actor ZombieMan 3004. The name 'ZombieMan' is a unique identifier of the actor, and already exists. Therefore, you must change this name to something that has not already been defined (i.e., for this and other 'actors'). I chose Barney, but you can use a different name. The value '3004' represents a unique thing ID number, and this too already exists. Change this to a number that has not already been defined. I chose 20119.
    3. The next variable you see will be: spawnid 4. This represents the value for the actor that you will use to spawn it in-game, typically via a script. You will need to assign a different number (unless you want a ZombieMan to be spawned whenever you call up Barney); I have chosen 209.
    4. Feel free to experiment with the other properties, but at this point they are not as important (in my opinion) as one that is not yet in the definition, namely 'scale'. Converting from a model to sprites typically results in very large images. Unless you wish to actually use large sprites, you will need to scale them down. Insert a line that reads: scale 0.17 somewhere in the definition before the line that reads: states. I find that the Barney sprites are scaled down to the right size with the value 0.17 (17% smaller than the original), but you may wish to try slightly different values.
    5. The first line in the Spawn state of the stock definition reads: POSS AB 10 A_Look. Rename it from POSS to the first four letters of your sprite's name. In my case it is BARN. The next two variables in the definition are AB, which represent the two sets of 'standing-walking' animations for the ZombieMan. In my case there is only one set of standing frames (namely BARNA1-BARNA8), and I do not want Barney to appear as if he is walking in place, so I replace AB simply with A. My new definition, therefore, becomes: BARN A 10 A_Look.
    6. The first line in the See state reads: POSS AABBCCDD 4 A_Chase, which represents the walking animations. Rename POSS to BARN, and insert the appropriate frame letters that represent the complete walking sequence. In my case, they are BBCCDDEE. My new definition, therefore, becomes: BARN BBCCDDEE 4 A_Chase.
    7. Following the guidelines in Steps 5-6, above, go down the list of States, and replace the stock definitions with those specific to your sprites.
    8. Use XWE to insert the DECORATE file into your wad. You have succesfully completed animating your sprites.

    End of lesson.

    Read Tutorial

  • Mapping Art - Great Conception
    CHAPTER 2 : The Art of Great Conception
    So, after fighting your way through the first chapter of my mapping article that dealt with tricks and ideas how to achieve a good level of detail, it's now up to me to take on the most important thing concerning mapping: The Conception of your map, which later can turn into an unforgettable atmosphere if done right.

    Honestly, your map can have more than 5000 sectors and still that's no guarantee for success, believe me (and some doomers won't trust their eyes, that I am actually writing this, but it's true ;)). A real good map is just as good as the idea behind it but as we all know after the 38974th UAC Bases and Dungeon Caves, it's not always that simple! What you get here are several tricks to get a good idea, a memorable map and beyond some guidelines to set up a atmosphere that the player really can feel...