Knowledge Base - Sliding Doors Using Poly Objects
Sliding Doors Using Poly Objects
The development of ZDoom has been a milestone in Doom source port development. ZDoom offers a feature-rich game, incorporating the extensions of the successful Boom product, developed by TeamTNT with the extended features of Hexen, plus some original extensions. No other port, to my knowledge, has such a broad base of capability for both the level designer and the Doom player. With ZDoom it is possible to create truly immersive worlds that interact with the player; and since ZDoom is still in development, the product will only get better.
One of the features that ZDoom supports is the poly-object, developed by Raven in their Hexen product. Poly-objects (polyobjs) are movable constructs and can be used for things like moving pillars, sliding and swinging doors and movable walls. They are simple to construct and use, but their use is not intuitive. In this tutorial I will go through the process of creating a sliding door using polyobjs. I have included a demo wad testdoor.wad, that illustrates the techniques.
Please refer to the above illustration while reading this tutorial. You may want to open this tutorial in a separate browser window for easier viewing. I used WadAuthor to create the demo wad, but any game that supports Hexen editing should work.
The steps in creating polyobjs are straight forward:
- Create the game-space where the polyobj will appear in the game.
- Create the polyobj in an unused sector of the map.
- Assign the startline to identify the polyobj.
- Place the anchor point.
- Place the start point.
- Create an activation for the polyobj.
The game-space is where the player will roam around in the map. The first thing to do is to create a sector that the polyobj will occupy when the player plays the level. In the illustration above, the game sector has two rooms separated by two sectors, labelled polyobjs sectors, where the sliding doors will be generated when the map is played.
In order to simplify the calculations the game engine has to perform, polyobjs are created in a separate, unused sector, and then moved to the location marked with the start spots. The polyobj sectors in the game-space should be the same size as the polyobjs themselves (or larger) and one polyobj can only occupy one sector or sub-sector (i.e. sector within a sector). It is not recommended that you overlap polyobjs.
In the Figure 2, two of the sidedefs are marked as switches. This is what will be used to activate the sliding door in the game. You can also use a line on the polyobj itself for the activation, just like a normal door in Doom. (Figure 1 shows one sector using colored lighting, which will be covered in another tutorial).
Next, create an unused sector that will hold the actual polyobjs. A polyobj is a collection of one-sided linedefs marked with a startline that indicates that this collection of lines make a polyobj. Create the polyobj so that it will fit inside the container sector using one-sided linedefs. Choose a line and mark it as the start line. In this tutorial, we are using two polyobjs, one acting as a mirror of the other, so two separate polyobjs will need to be created.
There are two line specials used to identify a polyobj. Polyobj_Startline and Polyobj_ExplicitLine:
Polyobj_Startline tag mirror sound-id
Polyobj_ExplicitLine tag order mirror sound-id
- tag: This is a unique number that identifies the polyobj.
- order: This is the line number when using explicitline.
- mirror: This is the tag of the mirror polyobj.
- sound-id: This is the sound sequence to play when the polyobj is activated.
If the polyobj is a simple polygon, using startline is the preferred method. Simply select a line of the polyobj, and mark it with Polyobj_Startline. Enter a unique number for the tag; this number isn't a reference to any sector tag, it is just a number that will be used to reference this polyobj. In this tutorial we are using a mirror polyobj, so the tag of the mirror polyobj will be entered in the mirror field. In the demo wad, the polyobjs are number 1 and 2 for the mirror. The third field is the sound-id and is the number of a sound sequence that is played when the door is activated. In the demo wad sound sequence 0 is being used. Refer to Figure 3.
The mirror polyobj is set up in the same fashion except the mirror field will be 0. It is not recommended that two polyobj mirror each other. The sound sequence number will be the sound that is heard when the door is activated. Unless a sound sequence is defined, the polyobj will be silent. Creating and using sound sequences will be covered in another tutorial.
If the polyobj is more complicated then a simple polygon, then Polyobj_ExplicitLine must be used. In this case, you must select all lines and in the order field, enter the line number. The numbers must be in sequence and must traverse the polyobj.
The anchor and start points must be placed for the polyobj. The start spot is the location in the game-space where the anchor point will be moved, with the attached polyobj. Looking at Figure 2, the start spots are placed at the left-most and right-most line of the polyobj sectors. When the game start, the engine will move the polyobj and place the anchor point on top of the start spot. Since the anchor points are placed on the right and left-most points of the polyobj, the polyobj will exactly fit in the sector creating the door.
Figure 4 shows the anchor point definition. The circled field is the byte angle field and is used to enter the tag for the polyobj. In this case this is the anchor for polyobj 1, so 1 is entered into the byte angle field. The anchor point for the mirror is defined in exactly the same fashion, except 2 will be entered into the byte field.
The start spots are defined in the same manner as the anchor points, as is illustrated in Figure 5. There are two types of start spots, normal and crushing. Using the normal start spot, the polyobj will stop when it encounters an obstacle, like the player. The crushing start spot, as the name implies, will cause the obstacle to take damage as it crushes. This can make for some nice traps. :)
The last item of business is to define an activation line for the sliding door; refer to Figure 6. In Figure 2, the game sector has two lines marked as switches. These will be defined with the Polyobj_DoorSlide special.
Polyobj_DoorSlide tag speed angle distance delay
- tag: This is a unique number that identifies the polyobj.
- speed: This is how fast the polyobj moves.
- angle: This is the direction of movement (see table below).
- distance: This is how far the polyobj will move. Polyobj have no problem going through walls, so be sure the polyobj will not block any passages when it moves. However, it is not recommended that polyobj move into the void. This can cause odd display problems. Make the container sectors big enough to hold the polyobj as it moves.
- delay: This is how long the door will stay open before it moves to its original position.
The angle parameter is a byte number that represents a direction. Table 1 lists the compass points and the associated byte number.
Since we are using a mirror polyobj, the doorslide special only has to reference the one polyobj. The other polyobj will mirror its partner.
In Figure 6, polyobj 1 is setup to move west at speed 32 for a distance of 128 units and to pause for 100 game tics (35 tics to the second) then return to its original position. Polyobj 2 will mirror 1 and move in the opposite direction at the same speed and distance and with the same delay. The linedef is marked as a Repeatable action, so the door can be opened multiple times, and is set to activate when the Player uses the line.
This polyobj behaves like a sliding door. However, by using different activation lines, you can make polyobjs that rotate and swing as well. The techniques are the same and the uses are limited only by your imagination.
SourcesZDoom reference by Marisa Heit. Thanks to Marisa for correcting some errors in this tutorial.
3D Game Alchemy by Steve Benner, et al. Copyright © 1996 By Sams Publishing