Using DEdit to Create Worlds for
The LithTech™ Development System is
copyright 1998-2000 by LithTech, Inc., Kirkland, Washington, U.S.A. All rights
No One Lives Forever is copyright ©2000 by Twentieth Century Fox Film Corporation. All rights reserved.
Welcome to the DEdit overview and tutorial. DEdit is the tool created by the LithTech team that enabled the NOLF Level Designers and Artists to create the geometry and gameplay you experienced in No One Lives Forever (NOLF). DEdit allows you to build the ground, sky, walls, ceilings and shapes for your levels. You will then apply textures, props, prefabs, lights and sounds to give them a realistic appearance. No One Lives Forever was created using literally thousands of these assets which you may appropriate to create the base for your own level. You may also add your own assets where applicable. Finally, you’ll add the game objects that allow other players to interact with your world.
Creating levels is an extremely complex and time consuming process, and the following is merely the starting point for those who want to learn the basics of building worlds for the LithTech engine. If you’ve done game design before on a 3D or near-3D game, you’ve probably worked with tools like DEdit. A separate document will cover ModelEdit, the companion to Dedit, that allows you to create characters and models for your world.
These terms are relevant to a discussion of DEdit.
Project — A project in DEdit represents the sum of all the resources in the game: all the code, all the textures, all the sounds, all the worlds, and so on. Unlike other world geometry editors, DEdit first opens the project, rather than a world file.
World — When your players walk around in your game, it is a world that they’re standing in. Worlds divide your game up into sections where different parts of the game take place. In other games, these are sometimes referred to as maps, levels, scenes, or episodes. World-editing is the primary focus of DEdit and each world is stored in a separate file on the hard drive.
Objects — Simply put, anything a player interacts with that moves, lights up, shoots, growls, or goes into the player’s inventory is an object . DEdit allows you to place any kind of object that your game’s code or the engine’s code can create.
World Geometry — Parts of the world that act as walls, floors and sky are generally made of world geometry . Such geometry is solid, immovable, and generally never changes.
Brush — The basic unit of world geometry. A brush is made up of planes that define its faces, lines that define its edges, and vertices that define its corners. All brushes must be convex for reasons that will be discussed later. You can manipulate either an entire brush at once or any of the vertices, lines, or planes in the brush.
Primitive — A simple shape that you can add to the world as the foundation of a more complex shape. Typical primitives are things such as cubes, pyramids, and cylinders.
Prefab — A prefab is like a primitive, but more complex. If you build a street lamp complete with textures and a light source that gives off just the right shade of light, you can select the lamp and its associated source (or any group of objects and brushes inside DEdit) and save it as a prefab . Thereafter, you can copy and paste that streetlamp into your world without having to rebuild the whole object.
Unit — The basis of measurement in DEdit and the LithTech engine. Units don’t equate directly to real-world values. Instead, the game designers can select a scale of game units to real-world measurements. As an example, in No One Lives Forever the following values are used: railings are 48 units tall, a chest-high box would be 64 units, and a typical doorway would be 128 units high.
Mode — DEdit has several different modes that allow you to change certain elements of your world (i.e. just brushes or just objects) without accidentally affecting others. They’re designed to simplify interacting with your world while editing, so it’s important to choose the right mode for your task.
Processing — When you process your world, DEdit creates a second version of the world with some information removed (parts only you need to know about), and other information added (parts only the game engine needs). Processing is a necessary step you’ll take in getting your world up and running in the game, and is often the first place where you will discover problems with your level.
Texture — In DEdit, textures are used like wallpaper, paint, or plaster to cover the raw plywood of your walls, floors, ceilings, doors and so forth. Without a texture, your brush will appear flat-shaded in the game, almost always with unpleasant results. Just as you wouldn’t want a house with raw plywood walls, you always want to apply textures to the brushes in your level.
The first step we’ll want to follow in building our new world is to pick a project. As mentioned above, a project specifies all the resources you’ll have access to in your world, from the game code on up. Generally, you’ll only create or use one project per game. Projects can be modified over time very easily, since they simply consist of a collection of files laid out on disk in a structure that DEdit can recognize.
In the File menu select the Open Project command or press CTRL+O . Navigate to the directory in which you have installed NOLF, you’ll notice that DEdit lists a .dep file. This is the project’s root file, and it stores various tidbits about the project. This is the only type of file you will directly open with DEdit.
Now that you have your project open, you’ll want to create a world to work in. This is also easy to do. Go to the File menu and select New World . When DEdit asks you what to name the world, type “Simple1”. This is the name your world will have when you go to open it in DEdit.
Tip: The name you provide is also the name of the world’s file on your hard drive (Simple1.ed ). Later we will cover how the project is written to your hard drive.
What you see in front of you will look similar to this:
The callouts in this screenshot illustrate the various sections of DEdit’s UI. Use the buttons in the Toolbars to make new worlds, switch modes, and run your world. You can learn an individual button’s function by hovering your mouse over it to get a Tool Tip.
In the Project Window , DEdit gives you access to all of the resources in the game. Most tabs represent a resource you can add to the game. There are two special ones ( Properties and Nodes ) that relate to objects inside your maps. We’ll discuss all of these in a later section and they’re documented in the DEdit Toolbars chapter as well.
There are four viewports that provide windows onto the world you’re building. Each one presents a different view of the world. The upper left window shows you a Perspective view shot from a movable camera point in the level. The other three views have a fixed-view camera that displays either Top, Front or Left view (going in clockwise order). You’ll spend a lot of time working with these views.
In the Status Bar , DEdit provides information about the level or about the view you’re currently in. We’ll get into the depths of the user interface in later chapters, although you’re welcome to stop and explore if you’d like. Use the Tool Tips and the Status Bar to learn more about what the controls do.
Our first world is going to be very, very simple. We’re going to make a box with a light. If you’re a programmer, this may be as complex of a level as you need to create, since you’ll mainly be making levels only to test your code and not for inclusion in the game itself.
Even though this level is extremely simple, we’ll still want to texture it. Use your mouse to select the Textures tab in the Project Window . This tab is where you select textures to apply to your brushes. In the top section of the Textures tab, there’s a box with folders listed in it. Click on the folder that is called Textures.
When you do so, the list box in the middle of the tab should fill up with subfolders that break the textures up into categories. Within these subfolders there is a folder called Tex. Within this folder are subfolders organizing the many categories of textures used in the game. Within these folders are listed the individual texture names. Click on the folder called metal and then click on the folder called mt01 . In the list of textures choose a texture named mt0010. Notice that there’s a preview of Met0010 in the bottom window of the tab. From now on (until you select a different texture) this texture will be applied to every brush you create.
To actually start putting brushes into your world, first move your mouse pointer over the upper-right-hand viewport (top view). The green crosshairs (also called the marker or the insertion point ) is like the cursor in a word processor: it’s where the objects you add to your map (brushes, objects, and things you paste in) will appear. If the viewports are your eyes, then the marker is your hand. We can leave the marker where it is for now, but you’ll learn how to move it around shortly.
The first step, since we’re zoomed in fairly close to the grid, will be to zoom the camera out a little in the viewport so that we can see more of the grid at once. Camera control is done in DEdit using the I, O and C keys with the mouse.
In the Perspective View, press I and move the mouse pointer to scroll in the X and Y plane. In all other views, this combination scrolls in all available directions.
Same as above, but faster.
Scroll along the Y-axis in the Perspective View.
In the Perspective View, press O and hold the left mouse button to pan the camera in all directions. In all other views, this combination zooms in and out of the displayed geometry.
In the Perspective View, press O and hold the left mouse button to move or “fly” forward through the level.
In the Perspective View, press O and hold the right mouse button to move or “fly” backward through the level.
In the Perspective View, press C and move the mouse pointer to adjust the draw distance.
Same as above, but faster.
Press the O key and move your mouse pointer slowly up. You should see the grid in the upper right viewport getting smaller. We’re actually zooming out to see more of our map, not changing the scale of the grid. Don’t zoom out farther than you need to in order to see a few more grid squares on the screen (perhaps four or six squares across the screen). Your screen may be at a high enough resolution that you can already see six or so grid squares. If that’s the case, play with the camera a little but make sure you come back to a scale of about 4-6 squares across.
Now press CTRL+B to switch into Brush mode. This is the mode reserved for moving brushes, as well as adding them to the world. From the center of the marker, count up two gridlines and then over to the right by two gridlines. Move your mouse pointer to that intersection in the gridlines. Once you have the mouse over the intersection, press the SPACE key once and move the mouse away. You should now have a line following your mouse pointer.
The line you see is the first side of the brush you’re about to create. To continue the brush, move your pointer until it’s over the grid two gridlines below and to the right of the marker and press SPACE again. DEdit drops the vertex on that point and adds a new vertex and side to the brush. Now move the mouse and place another new vertex four grid units to the left of the current vertex. Add your next vertex four units straight up (two units above the green marker). Last, move the mouse pointer back to the vertex you started at. When you press SPACE over the original vertex, DEdit displays a dialog box that asks you to enter the thickness of your brush. Enter a value of 64 and click OK . This completes the creation of the brush.
What you see should look like this:
In the 3D Perspective viewport, you can see that your square has been created and given a height of 64 units. This square will form the floor of our simple room. Each time you create a brush in the editor you will be prompted to give it a thickness. The 64-unit thickness was chosen to make the floor brush easy to find in the editor by eye.
Using relatively large units where possible also helps in other ways: You can more often let the editor align your textures for you if you build to the grid, since typical texture sizes fall along the grid as well. If your textures are mostly 32x32, 16x16, 32x64 and so on, laying textures out becomes a very simple task when you build to the grid. You’ll need to scale things to fit much less often, you can more easily make use of textures that tile together and you can realign a texture much more simply. We’ll talk about that in a later chapter as well. For now, assume that building to a large grid where possible is a good rule of level design practice.
Next, we’re going to use the Copy and Paste feature to create a ceiling for our room. In the Edit menu select the Copy ( CTRL+C ) command. Now there is a copy of the floor brush on the clipboard. Now in the Edit menu select Paste ( CTRL+V ) to paste. If you look in the perspective viewport (the one in the upper left), you should now see the new brush near your original brush.
Since the brush isn’t lined up quite as you’d want it for a ceiling, you’ll want to move it around a little. In the Top viewport (upper right), press the O key and click the mouse to zoom out until you can see both brushes. Move the mouse to the black drag handle in the center of the brush. Drag handles can be used to move or to resize the objects they’re attached to. In this case, click the left mouse button and drag the center handle towards the center of our original brush (which should still be the center of the marker as well).
When you have the center handle over the marker, your selected brush should be lined up exactly on top of your first brush. Drop the brush there and move your mouse to the bottom right viewport (Front). Use the O key again to zoom the viewport out until you have a good view of the selected brush. Next, click and drag the center handle of the brush until you’ve moved the brush straight up 4 grid units. Don’t worry if that means dragging the brush out of the visible area. The viewport will scroll up for you when you reach its edge.
Your ceiling is now a good height above your floor, at 192 units. That’s about the height of a tall conference room ceiling in most games.
Now we need to create four walls. In the Front viewport, hold down the X key and move the mouse upwards a few grid lines. What you should see is that the green marker moves wherever you move your mouse. Since the marker represents the insertion location where new brushes will appear, we’ll need to move it upwards until it reaches our ceiling in order to add our walls. Move the marker until it’s at the same grid line as the top edge of the ceiling brush.
Now you’ll want to switch back to the Top viewport. Use the O key to zoom out a little further until you can see a few rows of grid around the selected brush. Now use the SPACE bar to draw a rectangular brush that’s 1x4 grid squares and runs along the whole right edge ofyour ceiling brush. When you’re prompted for a thickness, give it a value of 320. That’s a lot thicker than you used for the floor, but there’s a reason. We want this wall to reach all the way from the ceiling to the floor. If you’ll look in the Front view, you’ll see that our new brush does just that, neatly sealing off one side of our room.
To make the next wall, copy and paste your new brush. Then use the center drag handle on the pasted brush to move it until it seals the west side of the ceiling brush the same way that your first brush seals the east side.
Now we have to make two more walls. Using the SPACE bar to draw a 6x1 rectangle on the north edge of the ceiling brush. By making it 6 grid squares wide, you’ll make a good seal against both the floor/ceiling brushes and also against the two existing wall brushes. Make this new 6x1 brush 320 units tall as well.
Note: Sealing a level is another topic that we’ll cover later. For now, accept that it is important.
The last step you’ll need to take making brushes for your level will be to copy your latest brush, paste it and move it to cover the south edge (in the top viewport) of the ceiling brush. Your room now has solid walls, a floor and a ceiling. You’ve created 75 percent of your level.
There are only three objects left that you need to add in order to see your level: a GameStartPoint (which specifies the location where your player will first spawn into the world), a light (without which you won’t be able to see your level), and a WorldProperties object (which specifies some of the rudimentary information necessary to create your level).
To place your start point, switch to the Front viewport so that you can move the marker vertically. Use the X key to move the marker down until it is one grid square above the floor. You should also check the Top viewport and make sure that the marker (if it isn’t still at the very center of the level) is at least 1 grid square from any of the walls. Since 1 grid square is 64 game units, this ensures that your player won’t accidentally appear halfway into the floor.
Press CTRL+H to enter Object mode. Object mode is the main mode you use for creating, moving, and setting the properties of objects. Once you’re in Object mode, select Add Object from the World menu. In the Objects dialog, the left pane of the dialog lists all the objects that your game code supports. Scroll down the list until you see a “ GameStartPoint ” object. Select it and click OK .
Once you’ve done that, look at the center of the marker. The small white square is the newly created start point. Your player can now actually enter the world.
Now move the marker vertically upward one grid square, using the X key in the Front viewport. Although you could add your light right at the location of the GameStartPoint object, it will be easier to select later if you add it at a different location. In the World menu select Add Object again. This time, go through the list of objects until you find one called Light. Select it and click OK .
Your start point will become unselected, and a small new cube will appear at the center of the marker. You should also notice a bluish circle that surrounds your whole level. That circle represents the radius of the light in the level. The light fades out as it gets further from its center point, and it ends completely at the edge of the blue line. Since you have a small level, one light will illuminate it all without trouble. Lastly, you will need to add a WorldProperties object. Use the X key to move your marker forward one grid square in the Top viewport. As before, select Add Object from the World menu, scroll down, select WorldProperties , and select OK .
The last step you’ll need to take in preparing your level is to process it. In the World menu, select Process and you’ll see a large dialog box appear. The only two checkboxes on the dialog that you need to worry about are Import Geometry and Apply Lighting . The Processor’s options are all documented in the Processor Controls, Options and Parameters chapter, which you can feel free to read now if you want. However, for now only those two boxes must be checked. Don’t worry if the Import Geometry box is grayed out. DEdit is just assuring that the option’s turned on, since the level has never been processed before. You can leave the rest of the checkboxes as they are by default. Once you’ve checked both boxes, click OK to process the level.
The dialog box will change into a progress monitor and a log of what the Processor’s doing. Once an OK button appears in the dialog, your level has been processed. Your world’s now ready for you to explore.
To actually load your level in the game, click on edit, and the options, to bring up the Dedit properties menu. Click on the Run tab. In the Executable field browse to LithTech.exe. In the Working directory enter the location of the root NOLF directory i.e. C:\NOLF\. In the Program arguments field enter the command string –rez nolf +runworld %worldname% . After entering all of this you should be able to launch your level by clicking world and the run, by pressing CTRL+ALT+R , or by clicking the Run World button on the tool bar.
Before starting, you should learn a little more about the structure of the resources that DEdit and LithTech can use in a game. The LithTech engine can access and use a wide variety of file types and other resources. The list below is arranged by resource type, and each resource type includes a list of the sorts of files LithTech can use in that type, as well as a description of those files.
Project — As mentioned before, the project is the total of your whole game and all its resources. A .DEP (DEdit Project) file at the top of your tree of game resource directories serves as a guide to DEdit. The .DEP file is a pointer to the rest of the resources for DEdit and includes some of the information about your game resources. The rest of your game’s files exist in subdirectories of the directory where your .DEP file resides.
Directories — The subdirectories that contain your other game resources are a type of resource in themselves. The structure of these directories defines the tree views you see in many of the tabs in DEdit’s Project window. If you find a game’s .DEP file and look at the subdirectories in the same folder with it, you’ll see names such as TEXTURES, WORLDS, SOUNDS, and MODELS. These folders contain whatever resource they’re named for, so if you want to add new textures to a game or copy a world from one game to another, you should look in the directories named Textures and Worlds , respectively.
Note: Inside each of these directories is a tag file with a name that tells DEdit what resource it contains. A file called DIRTYPETEXTUREStells DEdit that the directory contains textures; DIRTYPEWORLDS says the directory contains worlds, and so on. If you want to add new subdirectories or reorganize your resources, just copy the proper tag file into any new directories that don’t have one, and they will appear on the proper tabs in DEdit.
Worlds — Worlds come in two forms: .ED files and .DAT files. If you think of worlds as programs, the .ed file is the source code: Editable and understandable by the user and DEdit, but not executable. The .DAT file is like an actual program: it can be run in the game, but since it’s been “compiled” ( processed , in this case), the user can no longer modify it. The .ed files are what you change and save changes to inside of DEdit, and the .DAT file is the output of Processor.exe, which prepares your world to run in the game and optimizes its performance.
Textures — LithTech uses its own form of texture, the .DTX file. Textures can be up to 32-bit images, although you can obviously choose to make lower-color textures. The .DTX files also contain flags for additional information used by the engine and the game. You can convert .PCX and .TGA files into .DTX files by importing them inside of DEdit.
Sprites — Sprites (.SPR files) consist of a series of .DTX files linked together as an animation with a set frame rate. They’re commonly used for animations and special effects such as smoke, bullet holes, and liquid droplets.
Sounds — LithTech supports standard .WAV files directly with no custom modifications. When you double-click a .WAV inside of DEdit’s Project Window, it will open in your system’s default sound editor so that you can preview it.
Models — Models in LithTech are in a custom format, the .ABC file. This contains the mesh/geometry for the model and other information used by the game engine. You create these files in an external editor such as Maya or 3D Studio Max, then save them in the .ABC file format using a plug-in. Use ModelEdit , to modify files in the .ed format once they’ve been created.
Objects — Also known as Entities , these are objects that programmers construct using code. Some of this code exists in the engine and doesn’t appear in the project directories. However, many objects are created in code written for the specific game. These objects are called game objects (to distinguish them from the engine objects inside the engine code) and are stored in a file called OBJECT.LTO in the same directory as the project’s .DEP file.
Prefabs — A prefab is a collection of objects, both brushes and code objects that are stored in their own .ed files (just like a regular game world) in a separate set of directories. Anything you make in a level can be exported as a prefab to make it easier to re-use later. Examples are benches, camera systems, hallways, doorways, and statues. Prefabs can be useful if your group needs a way to distribute standard-looking objects to its members.
Our first step will be to add a new world. Since we’ll be doing a bigger world than before, let’s call it “Big1”. Create it just as you did in the last chapter.
Also, we will want an appropriate texture for our floor. Go to the Textures tab select the stone container, the container named st04, and then the texture st0183. This is a good-sized tiling texture that will make a good floor. Once you have it selected, go to the Top viewport (the upper right one). Look in the Status Bar for the Grid box, which shows the size of the grid blocks in the current window. Make sure that it says Grid: 64 , indicating a grid block size of 64 units.
Tip: The Grid is a way of organizing the placement of objects, similar to a ruler. It keeps you from laying out points totally at random and it allows you to measure the size of the objects you’re creating and their relative positions.
Using the grid makes for much more efficient level layout. When you build to the grid using standard units, your walls are more likely to line up properly and others can more easily understand your level just by looking at it.
If your grid setting shows something other than 64, you’ll want to adjust the grid scaling. First, single-click in the Top viewport to make sure that the focus is in that port. Then, either use the Expand/Shrink Grid toolbar buttons or the PLUS SIGN (+) and MINUS SIGN (-) keys on the numeric keypad to scale the grid up or down until it’s at 64 units.
Note: Each viewport can have a different grid setting, according to the user’s preference.
While 64 units is a reasonable grid block size for laying out floors, walls and ceilings in indoor spaces, if you were working on a large, open outdoor level, 256 units might be a more manageable grid scale. Your goal is always to use a large enough grid to allow you to tell how big your current brush is going to be, but still small enough to create whatever detail you’re going to create.
You’ll want a floor that’s about 512 units on a side, centered on the marker in the Top viewport. That means you’ll want to make a square that’s eight grid squares on a side. Create one now, and you should get a brush that looks like this:
Now that you have a floor, the next step will be to use DEdit to make complex brushes, beyond the simple squares that you’ve used so far. You’ll also learn tips and techniques for good brush construction.
The simplest technique is to use DEdit’s vertex-by-vertex brush creation method to build a brush that is close to what you want right from when you lay the brush down. Unlike many other editors that force you to start with simply shaped primitives such as squares or pyramids, DEdit allows you to create a brush by placing its separate vertices wherever you want them. While this doesn’t make it possible to instantly create anything , it speeds things up a lot.
For the next step, select a new texture. On the Textures tab, select the texture called st0116 in the st03 container. It’s different enough from the floor texture to make a good contrast. Then, go into one of the horizontal views (Left or Front viewports). Press and hold the X key to move the marker up 4 grid squares above the floor, where it is now. You can press the O key to zoom the view out further if you can’t see enough of the grid to complete this task. Your marker is now 256 units above the floor, about the right height for a tall and imposing support structure. Now, switch back to the Top view.
In the center of the map, create a pillar that’s eight-sided and shaped like a rectangle with the corners cut off. Make it 256 units thick/tall.
This is an example of an object that can be created quickly using DEdit but would require several steps in most other editors. However, the ability to create brushes this way does allow you to create brushes that DEdit and LithTech cannot properly use in games.
So far, you’ve only done small and simple things that haven’t required you to do too much with the DEdit interface, but now we will discuss two key elements that you’ll be using a lot: the camera and the marker, or insertion point.
You’ve already learned to use the camera in the three 2D viewports. To reiterate quickly, press and hold the I key and move the mouse in a 2D viewport to pan the view around the level. Press the O key and use the mouse to zoom the camera in and out.
The 3D view is more complicated and very useful. Hover your mouse over the 3D viewport (top left). Right now you should be seeing a very close-up view of the pillar you just made. Press and hold the I key and move the mouse around slowly. The window’s camera moves in the horizontal plane as you move the mouse. To move vertically, press and hold the right mouse button. To move faster, press and hold the left mouse button.
Release the I key. Press and hold the O key, then move the mouse slowly. Now, instead of moving, the camera turns. It operates just as the “mouse look” mode does in a first-person game. If you’re not careful you can turn the camera completely upside down, so be sure not to move the mouse around too wildly. Also, you can use the left and right mouse buttons to move forward and backward along the camera’s sight-path, respectively.
With these controls, you can move the camera anywhere in the map you need to see something. You can also see the object from any angle. For now, maneuver your view so that you can clearly see the column you created.
There are two other controls that set camera location. On the WorldEdit toolbar, these two buttons set the center point of the camera. The Center View button centers the camera on the selected objects or brushes, or on the middle of a selected group of objects or brushes. The Center View On Marker button moves the camera so that it’s aimed at the green marker. These are useful for rapidly moving the camera to a new location on the map, and you’ll probably find yourself using them a lot in large maps.
Right-click on any viewport to display the Context menu. Use the commands on the Context menu to change the view that your camera presents in the Perspective viewport. The Shade Mode and Move Mode commands both control the way that the camera works in that port. The Shade Mode menu lets you switch between textured, flat-shaded (un-textured), and wireframe views of the level.
Flat shading and wireframe display are useful for seeing how your brushes are laid out, since textures can obscure seams between two brushes, making some tasks difficult. These modes are also faster in some cases, so if DEdit runs especially slowly on your machine you may want to use them to speed things up.
The Marker controls all aspects of where you place things, such as lights, start points, brushes, or pasted objects, in your World. When you first worked with the marker, all your work was done in the top viewport, but it works exactly the same in any of the ports. It even works in the Perspective view, although most often it’s not useful to work in that view.
Object placement in ports other than the top view is simple. The object being added always appears at the center point of the marker, and the viewports do not affect this functionality. However, the viewports do affect the placement of brushes.
Go back to your map and move the marker in the Top view so that it’s one grid square south of the center of the column you created earlier, as in the image on the left.
If you were going to add a support to your column, this is probably where you’d want to add it.
Now, switch to the Front viewport. Zoom out a little so that you have some space to work and add a brush that is a triangular wedge with a thickness of 128 from the top of the column and looks similar to the figure below.
Look in the top view and see what’s been done. What you should see is that the brush lines up exactly with the green marker, and its thickness of 128 units extends along the front/back (X axis). The marker’s location in each view defines where the brush starts and the thickness you specify determines how far from the marker it extrudes.
By placing the marker carefully, you can lay brushes out exactly where you want them. Although this system of viewports and marker is somewhat different from many of the traditional editing tools, it’s also very powerful once you get used to it. Remember always to be aware of where the marker is and where you need it to be.
One last way of creating a new brush is to insert a primitive into the map. Primitives are pre-defined shapes that can be used instead of placing vertices. The main purpose of this is to quickly add brushes that would otherwise be very complex to build. You can add five shapes: Cubes, Cylinders, Pyramids, Spheres, or Domes.
To add a primitive, go to the Brush menu and choose Add Primitive . Select one of the primitive types. You’ll get a dialog that asks for a few options to set up the brush, and then the primitive appears at the marker. One difference between creating a brush this way and making it using Brush mode is that primitives come in un-textured. Be sure to apply the proper texture to your primitive once you’ve inserted it. To do so, select the new primitive and press CTRL+T .
Note : You may be tempted to fill your level with lots of domes and 20-sided columns, but be sure to read about optimizing performance in your levels before you do this. These objects can create great beauty where they’re used, but used in the wrong place they can create big problems with your level’s performance.
To select a brush, left-click on it. In any of the viewports, move your mouse over the brush you want to select. If there are brushes stacked on top of each other, DEdit tries to pick the one it thinks you want. If a big brush is in front of a smaller brush, clicking inside the smaller one will select it even though the bigger one is “closer” to you. You can select brushes in order of their depth in the current viewport by pressing the T key when you click. In other words, if two identical brushes are stacked on top of each other in the current view, the T+left-click combination would select the one closest to the “front” of the view, and subsequent clicks would select the brushes behind that one.
One way of speeding up your work is to select multiple objects or brushes at once. The primary way to do this is using multi-select mode. In the Mode menu, select the Multiple Node Selection command. While you’re in this mode, selecting an object no longer de-selects the objects you have previously selected. With Multiple Node Selection chosen, when you select a new object it’s added to the selection. If you mistakenly add a brush to your selection, hold down the CTRL button and left-click on it again to remove it from the selection. It can be difficult sometimes to select the brush you want, and you can accidentally select the wrong brush. Pressing the U key de-selects all brushes, after which you can select the single brush you want to work with. Be sure to use the camera in Perspective view and press the U key frequently to be sure that you don’t grab the wrong brushes.
You can press and hold the CTRL button while clicking on brushes to add them to your selection. While the CTRL key is pressed, you can click any brush again to remove it from the selection.
Another way to select a group of brushes at once is by using a block selection, which can be used in any mode. Move the mouse into the top view, then left-click and drag out a rectangle that covers the pillar in the center of the level as well as the support you added before. You will see a white highlight that outlines the area you’re selecting. Once you release the mouse button, all the objects under the highlight are selected. In the case of brushes, a brush only becomes selected when the highlight touches one of its corners, so you can select a brush that’s on top of a larger brush without selecting the brush below it.
Project Window with Nodes tab open
Lastly, you can use the Nodes tab in the Project window to select and find objects by name instead of having to find them visually. Click the Nodes tab to switch to it and examine what looks like a tree diagram of your whole level.
The list you see shows all of the brushes and objects in your level. Each of the names has a box and a symbol next to it. Move the camera in one of your views out so that you can see the whole level. Then, click on the box next to the object called “Brush1.” Two things happen. First, a check mark appears in the box and its name is highlighted. Second, one of the brushes (your pillar) is selected.
This way of selecting things is useful on larger levels, where you may know what brush you’d like to select, but can’t easily jump to it to select it. In that case, you can then use the Center View button (described earlier) to quickly center your views on the brush. You can do many other things
with the Nodes tab to organize your level as well. The Nodes tab is covered in greater detail later in this chapter.
The last major method for selecting brushes and other objects is via the Selection menu. The menu provides useful commands for working with several brushes at once, as well as a few commands for organizing your brushes.
The first two commands, All and None, are straightforward. Clicking None behaves exactly the same as pressing the U key: it clears all selections. If you choose All , then DEdit selects everything in the level: all objects and all brushes.
The Inverse command inverts the selection so that everything selected is unselected and vice versa.
The Container command tells DEdit to select an object’s parent object in the Nodes tree. You can use container objects to organize the objects in your maps without affecting the way the map works. You can read about using containers in the section on using and understanding nodes.
The Advanced command displays a dialog that will help you find objects and brushes based on their name or type. This is another feature designed to help you find objects in large levels where you may not be able to locate something right away visually, or to find large groups of objects quickly.
The Hide and Unhide Selected commands let you hide selected parts of the level from view if you’re not currently working on them. This will help your editor run a bit faster, and can help you to see parts of the level that would otherwise be hard to view with your camera. You can also use these commands to accomplish some complex tasks with carving and geometry mode (which you’ll learn about later). Since a hidden object isn’t affected by most actions while it’s hidden, hiding brushes can be used (like masking tape in painting) to protect certain brushes from work you’re doing on other nearby brushes. This is another command that you’ll read more about in the Nodes section.
The Hide Inverse and Unhide Inverse commands are just like the above commands, but they operate on anything that you have not selected. They are commonly used for hiding items other than the ones you’re currently working on. For example, in cases where you’re working on only a small area of a large level, you can speed things up by hiding the rest of the level. It can also be useful to hide other brushes when you need to do work on the geometry of a brush that’s too tightly packed in among others to easily find its vertices.
The Mirror command allows you to flip a shape or group of objects in a level. You can use the mirroring commands on any brush, object, or group of brushes and objects. We’ll discuss the Mirror command later.
The Save as Prefab command takes the currently selected objects and brushes and stores them as a Prefab in their own file so that you can use them in other levels, or in other places in the current levels. Once you’ve saved a Prefab into its own file, you can then import the prefab again using the File menu Import World command. Prefabs can be as simple as a vending machine or as complex as an entire room complete with lights and characters.
The Generate Unique Names command creates a unique name for objects that have identical names. In cases such as AI paths and scripting, this can be important, since some objects use the names of other objects to select them as a target, to move them, or to send them messages. Unless you’re working on such tasks, you shouldn’t have to use this command.
The Group Selection command (related to the Container command) adds a new container object and groups the selected objects together in it. This command is very helpful for sorting large levels or rooms into smaller parts. See the Nodes section of this document to learn more about containers and their use.
In addition to the grab handle at the center of each brush, there are several other ways to rearrange your brushes in the editor. Use the M key to move selected objects, including brushes. Press and hold the M key, and then click and drag with the mouse to move the objects wherever you drag them.
You can also rotate your brushes, which is very useful when building symmetrical areas. As an example, assume you want to make a second copy of your pillar and its support but facing the opposite way. The slow way would be to lay out each brush again by hand, which would be tedious. The faster way would be to copy the current brush, then just rotate it into the new position.
Switch to multi-select mode (using either the toolbar buttons or Mode menu Multiple Node Selection command. Select the pillar brush, and then select the support brush. Once you have them both selected, press CTRL+C to copy them. Since you don’t want to insert the brushes at the green marker when you paste them, from the Edit menu use the Alternate Paste command.
When you perform an Alternate Paste, DEdit pastes the object into the current world at the coordinates where it was copied out instead of at the marker. This is most useful in two cases. First, when you want to rotate or realign the brush slightly in relation to the original. Second, in cases where the new brush will be in a new world, but be in the same exact position there as the old brush was in the old world. For example, you might want to copy or paste parts of your world into a test world, just to try a few ideas without modifying the original world’s design. You would not want to align rooms, lights, and so on by adjusting the green marker for each paste operation.
Press CTRL+ALT+V to paste in the new brush. The selection will flicker, but since you pasted into exactly the same place that you cut from, nothing will appear to change. Next, go into the top view and move the marker so that it’s right at the tip of the support brush:
Right-click in the top view and select Rotate Selection . Since we want to make an archway out of the two pillars, enter 180 in the Degrees box that appears. When you click OK , you’ll see your selection move. If you use the camera in the Perspective viewport to look at what’s happened, you’ll see that there’s now a mirror image of the pillar on the opposite side of the original. Notice that the marker defines the center around which the brush is rotated.
Note: You can also hold down the N key to rotate the selected objects, but since this rotates the brush in very small increments you must be careful to rotate neatly. It’s difficult to rotate an object by exactly 90 degrees by hand; using the menu command is generally faster and more accurate. Additionally, you can hold down SHIFT+N to rotate in 15-degree increments. The most important thing to remember about rotations is that if your rotation operation leaves brush vertices off the grid, then precision errors can occur during processing.
Another way to flip objects is to use Mirror commands in the Selection menu. This method works well for brushes that are not symmetrical enough to rotate, such as a brush that’s beveled on one edge in order to meet up neatly at a corner. Each command flips the brush along a different axis relative to the world. It doesn’t matter which viewport you use the mirroring commands in, since the flip axis is relative to the world, not the viewport. A top/bottom mirror inverts the brush along its Y-axis, a front/back mirror along the X-axis, and so on.
Resizing a brush (which you’ll want to do now, since your level’s floor is too small) is done using the drag handles on the edges and corners of a brush. Press the U key to unselect everything, then select the brush that makes the floor of your level. You will see filled boxes appear at each corner and on each edge that look just like the one in the middle for moving the brush. The ones on the edges are for stretching the brush in the direction of that axis. The handles on the corners allow for resizing in both directions at once.
Go to the top view and resize your floor brush with the drag handles until it is four times its current size on each of the edges and it is underneath both of your pillars so that players can walk underneath them. You should get something like the picture below. It may also be useful to make the grid size larger (128 or 256) to simplify resizing the brush properly.
Having the two types of drag handles helps when you want to either quickly resize a brush in multiple dimensions like your floor (corner) or resize it in only one direction as you’d do if you extended a hallway (edge). These handles appear around any group of things in the world, including objects. You can use the drag handles to widen a circle of lights or spread out a group of start points as well as using it to increase the size of a brush. You can even mirror a brush by dragging it inside out. DEdit is smart enough to flip the face normals of the brush so that they still end up pointing outward as they should.
However, one thing that can happen when resizing a group of brushes is that you can re-shape some of the brushes in ways that you didn’t intend. For example, select both the floor brush and the right hand pillar in your level. Drag the right edge resize handle to the right by one square. What you should see is that not only does the pillar grow, it also moves to the right. This is because DEdit treats the entire group selection as one scalable object/brush.
That sort of movement, if you’re not aware of it, can cause leaks when you use the handles to resize a hallway whose floors and ceilings aren’t all the same length. For the same reason, you don’t want to use these handles to move a pair of walls to narrow a hallway. The walls thicken or shrink as they’re moved, and not usually by nice, neat increments. A pair of walls that began as 32 units thick each and 128 units apart might end up 196 units apart as you intend, but be 45 units thick each. That’s not a unit that will be easy to fit textures to or align with your other walls and floors. Conversely, if you scale a lamp post that has a lens flare sprite attached at just the right location, resizing the lamp post and the sprite as a group will ensure that the sprite stays as the proper location.
This brings up the last possible problem with resizing objects. If a brush has vertices that fall on points that wouldn’t line up with even a 1x1 grid spacing (the smallest DEdit and LithTech can handle without possibly producing precision errors; see the section of this chapter on problem brushes), the Processor may have some trouble getting the corners of the brush’s faces to line up when the level is processed. This can cause gaps to appear between faces and may also cause level leaks.
Note: You should undo your resize by hitting CTRL+Z in order to return your column to its proper size now.
If you do use the drag handles to resize an object, make sure you verify that all of the moved vertices wind up on the grid. If you can’t, be sure to correct the error by shifting vertices back onto the grid in Geometry Mode as described in the following section on brush manipulation power tools.
Even with DEdit’s primitives and its vertex-by-vertex brush layout tool, you still can’t create all of the brushes you want in a single step. DEdit has four main tools for changing the actual shape of a brush: Hollowing, Carving, Splitting and Geometry Mode.
The reason that these tools are in a section called “Power Tools” is because that’s what they are. While they are very useful tools, they are also very effective for destroying brushes, making your levels slower to process and slower to run, and making bad designs worse. As in carpentry, think twice before you cut. Be sure of what you will get before using these tools.
Using hollowing, you can empty the inside of a brush, like hollowing out a pumpkin. For a demonstration of how to use this technique, you can very quickly build a box around your entire level to contain it for processing.
First, raise the marker about 128 units above the tops of your columns. Then, zoom out your Top view until you can see all of your level’s brushes and a little space around it. Re-select the texture you used for the floor of the level, since the texture of your pillars and supports is a bit too dark for easy viewing.
Draw a square brush that surrounds the whole level in the top view and make it 1024 units tall. That’ll make it large enough to contain the whole level with some space left over. Now, with the big new brush (and nothing else) selected, select Hollow from the Brush menu. When prompted, enter 64 for the new brush thickness. This is the thickness of the walls of the brush, which will be created around the brush. Then the original brush is deleted.
You’re probably annoyed that you’ve been taught to create rooms using the slower method of laying out each of your wall brushes and ceilings by hand instead of just creating and hollowing cubes. However, if you look at the created brushes, you’ll see that DEdit created brushes whose edges are beveled instead of straight. This is to fit them together neatly with the minimum number of faces visible, although in some cases hollowing can drive up the number of faces on your brushes, leading to higher polygon counts inside your game. Also, because of the beveled edges, hollowed rooms must be resized by moving vertices, instead of by scaling whole brushes.
Hollowing can be useful, especially when the bevels fit in with the design of your room, or are in areas that won’t affect the rest of the layout. If you’re using it in an area of the map that you plan on changing a great deal, consider building your brushes by hand instead. It’s usually neater even if it is slower.
Your next tool is carving , also known as CSG Subtraction . It’s similar to hollowing and the two can even be used interchangeably for some purposes. However, as with hollowing, it can often produce unintentional results.
In order to carve a brush, first you need to create the brush to be carved. Next, you need to create a second brush that will serve as a tool to carve with . As you may guess from the name of the operation, the volume of the second brush will be subtracted from the volume of the first brush.
As an example, you can bevel an edge off of the top of your two pillars to give them a little more of an interesting look. Select one of your triangular supports. Copy ( CTRL+C ) and Alternate Paste ( CTRL+ALT+V ) it, then move ( M ) it so that it overlaps the outside edge of the support.
Resize the copied support so that its edge is a 45-degree slope in the Front view, then resize it in the top view so that it overhangs the north and south edges of the pillar a little. You should get a brush that looks like this:
The purpose of the overhang is to make sure that the brush cleanly carves the surface of the pillar. It’s not necessary, but it’s a good idea. DEdit may occasionally create a bad edge or face when using carving, and overhanging a little helps to minimize the chances of this. If it does happen to you, use undo to back up and then try resizing your carving brush to overhang the area where the problem appeared if it’s possible to do so.
If you can’t overlap the carving brush for some reason, see the section on fixing damaged brushes later in this chapter. It includes techniques that might help you fix any damaged brushes that result. You may also be able to use splitting planes (which you’ll learn about next) to do what’s needed.
Notice that your carving brush only touches the pillar and not any of the other brushes in the level. That’s because carving with a brush cuts its shape out of any other brushes it’s touching. Make sure that your carving brush isn’t touching anything you don’t want to carve. You can select both the column and the carving brush, then use the Hide Inverse command on the Selection menu to hide brushes that are in the way. Then select any brush and use the Unhide Inverse command to bring them all back. Alternately, you can move the carving brush and the brush to be carved to an area of the level that’s open enough to avoid the problem and move them back when you’re done.
Once you have the carving brush in place (make sure only the carving brush is selected), press H or use the Carve command on the Brush menu. Move the carving brush away from the column and look at the result. What you should see is that a new edge has been carved off of the column, leaving a large beveled edge. As with resizing brushes, it’s a good idea to line your carve up so that any new vertices stay on the grid, although this is most often a problem for brushes you plan on doing more to after the carve. If you’re building chunks of rubble, you may not care as much about the results being on the grid.
This technique can be used with more complex shapes as well. If you stick a cylinder-shaped brush into a wall to make a doorway or into a ceiling to make a window, you can create some very complex effects quite quickly. However, as with hollowing, your decisions on how to lay out brushes are very often better than the computer’s, and your cuts are probably going to be neater and easier to understand. The splitting planes tool, your next power tool, is designed with exactly that in mind.
Note: You might want to create some brushes outside the current map and try playing with carving for a little bit to better familiarize yourself with how it tends to cut before moving on. Try more complex carving shapes and carving multiple brushes at once. Be sure to watch the brushes that you get as a result. To more easily view the splits on your brush faces, turn off the textures. Right-click on the Perspective viewport, choose Shade Mode and then click Flat Polies .
The splitting plane tool is like carving, except that instead of using a full brush to remove a section from other brushes, you use a single plane as a saw to cut brushes into pieces. Although this tool only cuts along a single plane, it’s a very useful and refined device for making complicated brushes for two reasons. First, it doesn’t require the creation of a cutting brush. Second, it allows you to pick the exact position and order of the cuts as they’re being applied instead of letting DEdit make the decisions.
To see the tool in action, select the pillar whose edge hasn’t been beveled off yet. Splitting planes only splits through the brushes that are currently selected, so they can be used even in crowded parts of your level without the problems inherent in carving.
Next, you need to draw a splitting plane that’s located where you want your cut to be. Since we’re trying to be symmetrical with the other side, our cut should cut off the outside corner from two grid lines in at the top to two squares down on the side, a 45-degree angle cut. To define your cutting plane, you do as you’d do if you were starting to create a new brush along the line to be carved: Go to the Front viewport and press SPACE to define a line between the two points where you want the cut:
Make sure you only define two points on the line, since splitting only uses the first segment of the line to split on and will ignore any later segments. Use SPACE to place the first spot, then move the mouse to your second spot and press SPACE again to define the second point.
Note: Splitting occurs along an infinite plane defined by the two points you place. You do not need to ensure that you overlap all selected brushes or make the line the full length of the split you’re creating. Just make sure that the two points you choose are on the exact line that you want.
Once you have your split line defined, press S to perform the split. Your selection will be cleared, and instead of one brush you now have two: a pillar with a beveled edge and a wedge of pillar that’s been cut cleanly off. If you select and delete the wedge, you’ll have a pillar that’s a mirror of the pillar on the opposite side.
For a more complex case, imagine that you want the floor of your level to float in space. Now, imagine that you want to blow off a corner of the platform to make it appear damaged. What is the best and cleanest way to do it?
First, select the floor brush. Now, go into the top view and center in on the 4 squares in the lower left hand corner of the brush. Once you have a good view of them, split the brush vertically at the edge of the second square in from the left.
Select the smaller of the two resulting brushes (the left-hand one) and split the bottom two squares off so that you have a rectangle above a small square that forms the lower left corner of your floor. What we’re doing is isolating the rest of the brush from the area we’re going to work on. This is important, since one of the things we want to add is a splintered, irregular edge. Always choose carefully where you make your cuts. Otherwise, in this case, the whole floor here would be splintered and irregular which would drive up polygon counts and look ugly.
Now, select the square that you created. Zoom in on the square and lower your working grid size in the top viewport to 32 units so you can create smaller cuts. Now, using the splitting tool, carve up the brush and delete any excess bits until you have a nice jagged corner like this one.
You may want to use the flat shade view in your Perspective viewport again to do your carving, since it’ll be easier to select items that way. Note that you can now create a pretty complex shape without destroying the rest of the floor. Imagine what the floor would have looked like if you had used carving instead of splitting.
DEdit’s last brush power tool, which you’ll use to fine-tune the raggedness of your destroyed corner, is called Geometry Mode. Unlike Brush Mode, where each operation works on a whole brush at a time, Geometry Mode works on a single face, edge or vertex of a brush at a time.
Press CTRL+G to switch to Geometry mode. Move your mouse around in the Perspective viewport and watch what happens. What you should see is red highlights around the brush faces as you pass over them. You will also see green highlights on nearby edges and vertices. For the most part, you don’t make normal selections in Geometry mode the way you do in Brush or Object mode. The red highlight is DEdit’s way of indicating where the focus is instead.
In the Top viewport, move the mouse over the end of the triangle on the upper left edge of the jagged area. Get the mouse over the tip of the triangle that juts out of the corner into space. You’ll want to move that point so that the jagged edge sticks out further into space and looks more torn. Press and hold the M key, then click and drag the point of the triangle a grid line to the left.
What you’ve done is move the two vertices that make up the point of the brush over to the right. Something you may also notice is that you actually moved two vertices, not just one. You moved the vertex on the top face and the vertex on the bottom face, which was directly below it in the top view. DEdit knows that since the vertex on top had another vertex directly connected to it that was below it, you probably wanted to move the whole edge. DEdit only makes this assumption when the vertices are both on the same brush and are directly connected by an edge. In order to move vertices that aren’t linked this way in a single step, you have to select them a different way.
The right corner of the triangle you just resized butts up against the corner of another brush. Get that corner in view in the top pane. Then hold down the left mouse button and drag out a rectangle that surrounds that corner. Be careful to only select the one corner, and not any other vertices. When you release the key, you’ll see a yellow dot indicating that the vertex is now selected. If you use the other viewports, you’ll see that all the vertices at that point are selected, whether they’re on the same brush or not.
The nice thing about this is that you can now move all of them as a single unit. Press and hold the S key and drag the yellow dot to the right by one grid space. You should see that both brushes change shape when you do this. It’s important to know what vertices you’ve selected when using this method, since it’s easy to grab the wrong ones. If you have trouble, you can always hide the surrounding brushes to make it easier. Remember, M moves the vertex you click on (and those below it if connected via an edge) while S moves the vertices you have selected.
Now, press U to unselect the vertices you currently have selected. Go back to the triangle that you re-shaped before. Use the same technique to select its tip. However, instead of moving it left/right, you’ll be moving it downwards. Go into the Front viewport. Press the S key to drag the two vertices down three grid lines. In the Perspective view, use the camera to look at the result.
What you’ve done is bend your original brush downwards to make it droop. This is where the real power of Geometry mode comes in: You have the ability to totally re-shape a brush down to its smallest features. You can use Geometry mode to fix brushes when their vertices don’t line up with the grid, to resize irregular objects and to repair all kinds of problems.
One other way to select objects in Geometry Mode is to use the Y key to highlight all the vertices on a single face. Move the mouse over a face so that it’s highlighted, then press Y . What you see is that all the vertices on that face are now selected. This is the method most commonly used in DEdit to skew a brush: you select the face and then use the S key to move it around, skewing the brush.
The last area where Geometry Mode is highly useful is face-by-face texture management. There are cases where applying a single texture to a whole brush won’t get the result you want. For example, perhaps you want to darken the edges of your ragged corner.
In the Perspective viewport, highlight the side of one of your pillars. Next, right-click and choose Select Texture from the context menu. If you now go to the Textures tab, you’ll see that the texture on the pillar is now the active one. Using this tool helps you to quickly grab a texture without needing to know where it’s located in your texture tree.
Move the camera so that you can see the edges of your ragged corner.
Hover the mouse over one of the edge faces of your ragged brushes and press CTRL+T . The highlighted edge now has the dark texture on it. By moving the mouse and camera you can quickly re-texture all of the brushes to the new, dark texture.
Since Geometry mode is such a powerful tool, it also allows you to damage brushes and create objects that the LithTech engine can’t run. DEdit assumes that users in Geometry mode are experts doing things for a reason, so it allows them to do actions that might cause problems because it thinks that is what they want to do. You can probably easily imagine ways to make concave brushes using Geometry mode, but there are more subtle problems you can cause using this mode as well.
Do not use Geometry mode to mirror brushes. If you select a face or group of vertices and drag them so that the brush becomes inverted, the brush will literally turn inside out, with the normals of each face towards the center, resulting in a bad brush when compiled.
Do not twist the faces of a brush. This is a hard concept to demonstrate. Say you have a face that’s rectangular, and you pull one of the vertices straight downwards, as in Fig. A . What results is a twisted face.
Since faces must be totally flat, you have effectively split this one face into two without creating an edge to separate the new faces. To DEdit this will register as a concave brush, and Processor will not be able to properly compile it. Twisted faces are probably the most common kind of Geometry mode problem, and the hardest to spot in many cases. Open the World menu, select Debug and click the Find Concave Brushes command to double-check your work occasionally if you’re working heavily in Geometry mode. If DEdit complains about a brush and you can’t see anything wrong with it, chances are good that you have twisted a face.
You can delete faces and individual vertices, but unless you really, exactly and specifically know what you’re doing, do not do this . More often than not, you’ll create a bad brush. There are tools to do this in the Debug and Special submenus under the World menu for fixing the problems that can result.
Geometry mode is very effective for doing many things that otherwise simply couldn’t be done, but it’s also very easy to do serious damage with it. It’s the most powerful of the power tools, and as such should be used with plenty of care and attention.
So far, most of the texturing that you’ve done has been relatively simple, but DEdit supports more intricate texture work as well, both on a brush-by-brush level and on a face-by-face level. You’ve seen how to texture whole brushes, as well as how to texture single faces. You’ve also learned to select a texture off of a face without having to find it in the Textures tab.
Even when you follow all the rules of good brush layout and level design, some textures don’t line up where you want them to be when you first apply them. Either the texture’s edges don’t line up with the edges of the brush, the only texture that has the symbol you want on it is too large, or a crate is rotated off the grid and its textures are not.
This section will show you how to scale, rotate, offset and flip textures. In Brush mode, select the largest piece of the floor under your pillars. Get a good view of the brush in the Perspective viewport, then right-click. In the context menu, select Map Texture Coordinates.
You can use this dialog in either Brush or Geometry mode. In Brush mode, the settings affect all the faces on the brush. In Geometry mode, this same dialog can change each face individually. Instead of selecting the face you want, just highlight it in red by hovering the mouse over it in the Perspective port, then right-click.
The dialog’s controls are mostly intuitive. The U/V offset controls tell you about the alignment of textures on a face. U (horizontal) and V (vertical) offsets are used to move the texture around on the face pixel by pixel. You can apply a negative or positive offset, which allows you to move a texture in any direction along a face. They are especially useful for things like aligning a sign to properly fit the brush you’ve created for it.
For instance, a texture may perfectly fit the brush but hang a little off-center: say, 4 pixels too low and 8 pixels too far to the left. To correct this, you would add to the U and V offsets. Setting the U offset to 8 would move the texture 8 pixels across the face to the right, and setting the V offset to -4 would move the texture up 4 pixels on the face.
This isn’t something you want to use for all of your textures; it’s much better to build such that the bulk of your textures fall naturally along brush boundaries so that you don’t even need to think about texture alignment on most of your brushes. It’s meant to be used for detailed, standout objects like crates, signs and display screens which are often set at odd locations and need to be exactly aligned.
The next control, the Rotation control is what you use to align a texture on a brush that’s been rotated. Perhaps you’ve made a poster that’s hanging on a wall at a slightly weird angle of 17 degrees to make the room look a little unkempt. By applying a 17-degree rotation to the texture of the poster, you can get the poster to look as it should, properly lined up on the brush.
The next controls are the U and V scaling controls. By default, these are each set to the horizontal and vertical size of the texture on the current face in pixels. However, by changing these values you can change the size of a texture in the world. By modifying just one of them (say, doubling the value in the U scale) you can stretch the texture. By doubling both of them, you quadruple the size of the texture on the brush. Lastly, you can flip a texture without rotating it by putting a negative value into either of these boxes. There are many cases where mirroring a texture can be useful: aligning trims on a wall, building a fake mirror image of a screen, and giving a clue to a secret door. The dialog also has two Flip buttons that allow you to do the same thing.
Finally, there are two check boxes. When you check the Stick checkbox, DEdit will attempt to hold the textures aligned to the brush’s faces as they currently are. This allows you to move the brush around without the texture sliding around on the face. DEdit will try to automatically update the textures’ offsets and even rotation to keep the faces. Although DEdit doesn’t always make the right choices, for simple moves and simple rotations it can be faster than doing the math yourself.
The XZ Only checkbox is used to force textures to map on the brush from straight above it. It’s generally only used for terrain, to make it easier to align textures. You can experiment with it, but it generally causes undesirable results on anything but terrain.
There are also some texture alignment hotkeys that allow you to do some of these operations without going into the dialog. K rotates the texture on a face in Geometry mode, attempting to align it accurately with the corners of the brush. It’s frequently faster than going into the Map Texture Coordinates dialog for simple problems like our sign problem above. The other useful shortcut (also used in Geometry Mode) is the R key. When this key is held down, moving the mouse will move the texture around on the face of the brush. It is difficult to exactly align a texture using this shortcut, but it can be very helpful for getting the texture roughly aligned. You can then use the Map Texture Coordinates dialog to clean up the result, cleaning up the UV offsets to exactly fit.
You can also hold R and click the right mouse button to rotate textures freehand. Holding SHIFT+R keys changes from totally freehand rotation to rotating in 15-degree increments. Holding R while clicking with the left mouse button allows you to scale the texture freehand.
Though we’ve already talked a little about invalid brushes earlier in this chapter and other chapters, this section goes into a little more detail on the how and why of bad brushes and a few ways to repair them. Not all problem brushes cause terminal problems, and some of them are even useful under very specific circumstances (such as 1-sided polygons). However, until you learn how to use them, you should always be sure to avoid creating invalid or problem brush types.
The first type is usually created accidentally. Move to the Top viewport and press CTRL+G to switch to Geometry mode. You’re now in the mode DEdit reserves for editing on the level of faces, vertices, and edges, rather than brushes. What happens if you create a brush in this mode? Try it: Use the SPACE bar to create a square brush in the Top viewport. Notice that when you close the brush by placing the last vertex, you are not prompted for a brush thickness the way that you are when you build a brush in Brush mode.
Press CTRL+B to switch back to Brush mode and look at the new brush you’ve created. Use the I and O keys in the Left or Front viewport to bring it into view.
What you’ll probably notice is that the brush is completely flat. In fact, not only is it flat, it has only one side. What that means is that from one side it’s solid and has a visible surface, and from the other it’s completely transparent. The processor will alert you if it finds one of these brushes in your level, and often you’ll notice yourself that the wall you thought you’d just created isn’t as thick as you intended and has very strange properties.
These brushes can be used in building your level as hullmakers , which are brushes with a very specific and special purpose that is described later. However, in almost all other circumstances they will cause problems and errors. If you create a brush in Object or Geometry mode, or if you ever notice you haven’t been prompted for a brush thickness, you should immediately switch to Brush mode using CTRL+B . The one-sided brush will be selected. In these cases, you should delete the one-sided brush and then create the brush as it should be in Brush mode.
The second invalid brush type is the convex brush. Brushes in LithTech and most other current game engines can only be concave. Brushes can most formally be described as the space located inside the intersection of a series of planes. They are composed of vertices , lines and planes . A vertex is a geometric point that defines one end of the line that composes a brush’s edge. A line is two connected points. An X, Y, and Z coordinate define each vertex . Any three points on a plane can be used to define that plane. For editing purposes, a plane is three or more lines connected to form a closed polygon. Planes must always be flat. Brushes must always be convex, never concave.
Since the engine sees brushes as “All space inside the area defined by the intersection of their planes,” a brush that’s concave can intersect with itself , which effectively gives it multiple “insides.” Unlike a 3D modeling package, game engines don’t handle this at all well. The game will pick one “inside” as the right one, then throw out the rest of the brush. This almost always produces unpleasant results.
The best way to deal with concave brushes is to split them up into convex brushes. You should ideally do this before even building them, by carefully thinking out your brush layout and building the concave shape with convex brushes. However, if you’ve built a concave brush you can sometimes split it up using splitting planes as discussed earlier and get healthy convex brushes. Be sure to check the resulting brushes to make sure that when you’re done you haven’t accidentally missed a concave section.
Brushes also sometimes develop a loose face. If you try to move one face on a brush in Geometry mode and the rest of the brush doesn’t follow it, the face has probably been detached from the rest of the brush. This is rare, but it’s also easily fixed. Undo the move so that the face goes back where it was, then use click-and-drag selection technique to carefully select the vertices at one of the corners. Press CTRL+J to join the tagged vertices. Keep doing this for each corner until you’ve reattached each of the corners. Afterwards, use the Remove Extra Edges option from the World menu Special commands, followed by the Update Plane s command on the same menu. Your brush should be properly sealed again afterwards.
This technique can also be used to correct problems from a carve where one plane of the brush protrudes too far, another rare problem. Just move any misplaced vertices to where they should be attached and then join and clean them up as described above.
Another problem that can occur is brushes whose vertices don’t all land on the grid. Sometimes, a vertex that’s off of the grid slightly will be miscompiled due to rounding errors in the floating-point math involved in processing the level for the engine. As a result, you may see gaps between brushes where two faces don’t line up as they should. Again, making sure that you don’t create brushes whose vertices leave the grid is the best way to prevent such problems. Care when stretching, carving or splitting brushes can prevent most of these problems, and you can correct them after the fact using Geometry mode.
These types of errors are especially common when you import terrain using the old-style height map method from LithTech 1.0. Most of the terrain sections will probably have vertices that are off of the grid. Usually, it’s possible to correct some of these by selecting all of the terrain brushes and setting their NoSnap property to True . That tells the engine not to force their vertices onto the grid. Some errors will often remain, but you can correct these by fixing the vertices of just the problem brushes and their immediate neighbors by moving these vertices onto the grid.
One last type of error occurs when two faces of different brushes occupy the same space. In such cases (a handrail sticking through a wall, two walls whose corners overlap), if the overlapping planes are both visible to players, the engine may not know which to remove. In these cases, it will leave them both. This results in a weird flickering display of both surfaces at once, which is pretty unpleasant. You’ll recognize the effect when you see it.
The way to avoid this is to make sure that where surfaces meet, they don’t overlap on surfaces where the player can see. Don’t overlap two walls at the corner; just neatly join them.
Don’t run a handrail all the way through the wall; just end it where it touches the wall. Figure B presents the proper way to connect two brushes at a corner. Surfaces that the player can never see are always removed when a full Processor run is done. Luckily, that means you only need to worry about this issue in cases where both surfaces are visible to the player.
As your levels grow larger and more complex, it becomes increasingly important to have ways of grouping areas of your map into subsections for easier selection and management. The Nodes tab is designed to help you do this, as well as to manage doors, windows, and other objects that are composed of a brush bound to an entity, rather than an entity or brush on its own.
Note: Binding brushes to entities is discussed in more detail in the section on adding entities to your map.
Your level may also have groups of entities like AI paths or scripting paths that would benefit from being in groups so that you can easily find them.
The Nodes tab is a tool for organizing your level, for viewing its structure and for quickly locating objects in it. As mentioned previously in our section about selection, the nodes view reflects objects you select in the other views and vice versa. If you select a brush or object in one of the viewports, it becomes selected in the Nodes view. If you select a node, it will be highlighted in the viewports as well.
Go to the Nodes tab and look around at your level. What you’ll see is that the tab lays out your level not as it’s visually organized, but as a tree, showing the connections and relationships between objects in the level. At the very top of the tree is the root node . This object has no properties, and selecting it selects all of the child nodes below it, but doesn’t actually select the root. Selecting a node that contains other nodes always selects the contained nodes, but usually it also selects the parent node as well. In this case, the root node is special. You can’t delete, change, move or rename the root node , so there is no reason to select it other than as a quick way to select all objects in the level.
You’ll also see that there are multiple levels in the tree of nodes. Some nodes are hanging off of nodes other than the root node . Most of the objects that contain other nodes probably have the name Container . Container objects are special. When an object is contained as a child node below another object, it inherits the parent’s properties. This is called binding and will be talked about in the section on entities. The reason that containers don’t affect the objects that they hold is because Containers don’t have any properties. They only exist to hold and organize the other objects in your level.
You’ll probably also notice that most of the nodes have somewhat cryptic names like Container or Brush1 . That’s easily fixed, though. By default, DEdit creates object names based on the class of the object. When a new brush is added to DEdit, its name is automatically set to Brush# , where # is a unique number. DEdit tries to give each object a unique (albeit boring) name to make each one easier to find.
If you don’t like the names DEdit gives to objects or want to change them for other reasons, you can change the name of a node just like you’d change it in Windows Explorer. Click on one of the node names, then press F2 or single-click once again on the node’s name. You’ll see the name become highlighted, just like a file or folder in Windows, and you can now type a new name. When you press ENTER the new name is applied.
Since the regular viewports are linked to the Nodes view, you can also rename objects in their Properties dialog, which is useful when you want a group of objects to have the same name. Using the Perspective view, select all of the brushes you used to seal your level, the six brushes that make up the level’s outside walls. Select the Properties tab and look at the Name field. Though you only see a single entry there, if you change the Name field here, the names of all selected objects will change. Type in “Outer Wall” in the Name field and then switch to the Nodes tab.
You should see six nodes, all of which have the same name: “Outer Wall.” You can also see how the Nodes tab indicates that an object is selected. The little box next to the object’s name is checked. If you look at the other objects that are visible but not selected, you’ll see that their checkboxes are empty. If you click on a checkbox, it becomes checked, indicating that you’ve just selected the object. Likewise, you can unselect an object by clearing its checkbox.
You’ll also probably notice that our six outer wall brushes are inside a Container node. Since you didn’t know where the brushes were in the Nodes view until you selected them in the Viewport, you couldn’t take advantage of that container to quickly select the brushes. However, now that you do know where it is, click on the Container node and rename it to “Outer Walls” to make it easier to find.
The reason that these brushes are inside a container is because you used the Hollow command to create them. Certain operations like hollowing, carving and splitting that take a single brush and turn it into multiple brushes automatically create a container and put the resulting brushes into it to keep them organized.
Using containers to organize your level is a very good idea. Imagine a level with 200 brushes, 50 lights and 75 enemies and you can imagine why. Using containers to group brushes by room, lights by area and enemies by squad turns your level from a massive jumble into a logical order.
Note: Now that you know about container nodes and renaming things, you may be tempted to carefully name each brush and object, or to build six layers of containers for all of your items. Don’t spend more time than necessary on organizing things. It’s wise to sort out your level in a general way to make things easy to find and to help others who may need to work on your level. However, it’s easy to go overboard as well. Spending hours laying out your level in the Nodes tab is as much of a waste as the hours you may spend searching through an unorganized level to find a brush or entity. Be careful to find a balance.
You add a container of your own from the Context Menu in the nodes view. Right-click on the Root node. The top item on the context menu is Add Container Node . Select it and you should see a new container node appear in the tree. You can have as many container nodes as you want in your level. Since containers are removed from the level when it’s processed, they have no effect on the actual operation of the level in the game. They’re present exclusively to help you structure your level within the editor.
The context menu has many useful commands on it, all of which are covered in the DEdit references in this guide. However, there are several that deserve to be highlighted. The first of these is the Set Active Parent command, the second one on the menu. The active parent node is the node where new and pasted objects are added. By default when the level is opened, the active parent node is always the root node. Thus, each brush, entity and container you add is added directly below the root node.
This command allows you to make another container node into the active parent. Thus, if you’re creating a new room you can create a new container node and designate it as the active parent to have all new brushes and entities appear below that node. This helps a great deal when you’re trying to make a level neatly without wasting a great deal of time. Instead of organizing beforehand, you can organize as you go.
The various hide commands hide the targeted nodes in the Viewports, but you can still see them in the node view. They’re most useful for getting brushes out of the way if you want to do tough geometry work or if you’re having trouble seeing how parts fit together.
Move Tagged Nodes Here moves all the objects that are currently selected under whichever node you right-clicked on. This is useful for organizing things into containers quickly, since otherwise you must drag brushes under a container node individually. You can also use the Group Selection command to group objects under a node, but that creates a new container for the selected brush, which isn’t always what you want.
Go To Next Tagged Node is a command you can use to easily jump between selected objects in the node list. Each time you select this item from the context menu or press F4 (the hotkey for this action), the Nodes view will scroll and highlight the next selected node. If you’ve used the Selection\Advanced menu to do an advanced selection in the level and therefore don’t know exactly what is selected, this is a quick way to jump to the objects you want. It’s also useful in cases where you can find something in the viewports but not in the nodes view. Last, if you’re just not certain what’s currently selected (or if anything actually is), you can use this command to quickly find out.
One last useful tool that the Nodes tab offers is the set of radio buttons at the top of the node list, right below the tab name. You can use these commands to toggle between viewing the names of the level’s objects and their class. This is often helpful when you need to identify nodes or find objects.
As mentioned before, the Nodes tab also shows the relationship between the objects in the level, which can be very important in the case of entities.
Of course, there’s more to a map than just the brushes it contains. A map with just brushes is like a movie with no actors: It’s a still life. In order to have weapons, enemies, and even lights, you must add objects to the map that tell the game engine where to place these things. A map can’t even be started if you don’t designate a player start point in the map.
This section deals with adding objects like the above, as well as other types of props, to your maps. Most of the objects mentioned above are referred to as entities . An entity can be defined as an object that is defined not of brushes but by code (either in the game or the engine). The LithTech engine has certain classes of object that any game built on LithTech can use.
Most games also define their own sets of entities, some of which are brand new, and some of which are subclasses or children of the engine classes. A subclass incorporates most or all of the behaviors and attributes of the parent, but also adds some new behaviors of its own. In the case of most LithTech games, for example, you can add a Door (“Make this brush move.”), you can add a Door-subclass RotatingDoor (“Make this brush move and turn on a point.”), or you can add a RotatingDoor-subclass DestructibleRotatingDoor (“Make this brush move, turn and explode when shot.”). Each of these subclasses takes the properties and behaviors of the object above them in the tree (their parent) and extends them in new directions. You can still use the root classes in cases where you don’t need the added properties of the child objects, and often will.
This tree system is easy to see when you look at the Add Object dialog inside a LithTech game. For example, each of the AI classes derives from the root class, but each type of enemy, civilian and major character is its own subclass, many of which have their own subclasses for different armies or different versions of the character.
Our example will be using the SDK’s sample project, which has a much simpler and smaller object list. Begin by moving the green marker so that it’s centered in the archway you built earlier and about 64 units above the floor. Next, right-click in a viewport and select Add Object from the context menu.
This dialog is where you select and add objects to your level. Look down the list until you see the one labeled GameStartPoint . This is the first object you should add to your level, since without a start point your game doesn’t know where to start the player off in the level. The reason for raising the start point 64 units off of the floor is to ensure that the player has room to stand when he or she appears. If there’s not enough room for the player to appear, the start point is too low to the floor, or if the start point is inside a solid object, the player will just fall out of the bottom of the world.
Select the GameStartPoint object from the list and click OK . Now, if you look closely at the center of the green marker, there’s a small square located there. If an entity doesn’t have a discrete volume that’s specified by the player, this square is how it will be represented in DEdit. Many objects such as models have a volume associated with them and are therefore represented by a box that’s the right size for them.
Another way that some objects are represented is a combination: A point that shows the origin of the object and a circle, square or cone representing their area of effect. One object that uses such an indicator is the light. Move the green marker up 64 units above the start location and go back to the Add Object dialog. From the list of objects, select Light and OK the dialog.
What you should now see is a new box above the old one that is surrounded by a large sphere. The sphere is the radius within the level that the light will fill. Go to the Properties tab in the project window and look at the properties of the light. In most cases and entity’s properties are the most important tool used to control its behavior. In the case of lights, this is where you can change their size, brightness and color. The light’s current size (set in the LightRadius property) is 300. That’s probably a little small, so change the value to 500 and press the enter key. In the viewports you’ll see the size of the light radius increase as well. Now it’s large enough to make a good-sized pool of light around the player.
Terrain can be lit by ordinary lights just as any brushes can. (For more information about terrain lighting, see the Lighting LithTech Worlds topic on page 25.) There is also an additional lighting resource that is very useful with terrains. You can also use a StaticSunLight object to light the entire map with a single source. StaticSunLight objects require a working skybox in order to light the map. Most of their properties are self-explanatory and similar to a DirLight, but without FOV (Field Of View). The light projects in from the level’s sky portals. The main different property is Bias , which controls the softness of the light when it falls on terrain. Varying the light’s Bias varies the level shadows from sharp and harsh-edged to soft and rounded. To have a StaticSunLight affect your terrain, set the terrain brushes’ DirectionalLight property to TRUE; their other lighting properties should be set to FALSE, since GouraudShade and Lightmap will override the directional lighting.
StaticSunLights will illuminate normal brushes just as they will Terrain brushes, so a single StaticSunLight can provide all of the main lighting for an entire level if it’s largely open. It is still recommended to place individual point sources around your level for highlighting and fine control.
The next property you may want to modify is the light’s color. LithTech is a little unusual in that its lights have both interior (LightColor) and exterior (OuterColor) color properties. By default, the interior color of the light is set to white and the exterior color is set to black. That means that the light starts out as a pure white, then fades out to black at the edge. This becomes useful in areas that have a non-black ambient light, such as a cavern of lava lakes, or an outdoor scene on the savannah in bright daylight. If you wanted to fade a light out more gradually in one of these settings, you could set the exterior color to a mix of black and the ambient light’s color for a slower fall-off.
To change the colors, click on the color sample button next to the property name. Start by clicking the white button (LightColor). The dialog that comes up is a standard color picker dialog, and it allows you to pick from a standard palette or create your own custom colors. Choose one of the very light blue colors for something similar to a fluorescent light. You can use the slider on the far right to lighten or darken the color to your taste. When you’re done, close the dialog and you’ll see your new color in place on the LightColor button. The OuterColor property is changed in exactly the same way.
Lastly, you can set the brightness of the light using the BrightScale property. At its default setting of 1.0, the light appears at a normal brightness. If you change the value of BrightScale to 0.5, the light’s brightness is halved. However, the radius stays the same. Thus, you can create a very large light that doesn’t overwhelm the area closest to its center. Likewise, if you want an intensely bright light, you can increase the BrightScale value to 2.0, which will make the light much brighter. For now, leave BrightScale as it is.
There is another useful type of light with very different behavior from the regular one: The DirLight. While a normal light throws light in a sphere all the way around it, a DirLight acts like a spotlight: It throws light in a cone, the diameter of which you can control.
Switch to the Top viewport and move the marker 256 units (4 lines on a 64-unit grid) down, towards the edge of the platform furthest from your archway. Then move the marker 64 units closer to the floor, so that your DirLight will show up better on the floor. Then, right-click in one of the viewports and select Add Object again. Find the Dirlight class and add one.
What you should see is a pyramid-like cone extending from the marker towards the top edge of your platform. The cone represents the area where the light will fall within the game. If you look at the Properties tab, you’ll see that the Dirlight has most of the same properties as your regular light from before, but it has an additional property, FOV, which stands for Field of View. It represents the arc within which the Dirlight actually sheds its light. You can increase this value to widen the pattern or decrease it to reduce the pattern’s width. Change the FOV to 60. You should see the base of the light’s preview cone shrink down in size.
You can aim a Dirlight using the object’s Rotation property. Click the button next to the property’s name and you’ll see a dialog appear. Within this dialog, you can control every aspect of the object’s facing. Each of the three aspects has a range between 0 and 359. Yaw controls the horizontal facing of the object, and is aligned identically to the Top viewport like a compass needle. You can use the preview display at the top of the dialog to see how the results will appear. A setting of 0 points the object straight “north,” towards the top edge of the Top viewport. A setting of 90 would aim “east,” a setting of 135 would point “southeast” towards the lower right corner of the viewport and so on. For now, set the yaw to 180 to spin the Dirlight around so it’s facing the opposite direction.
Pitch controls the vertical angle of the object. The Pitch preview display shows the result of your changes. Since the Dirlight is pointed at the proper angle already, there’s no need to change this.
The Roll control controls the spin of the object. This is useful mainly for props or cameras, where you want the object to bank or its viewpoint to sway. You would change a motorcycle’s Roll, for example, if you wanted it to lean as it turned a sharp corner. Again, there’s no need to change this value in the case of a Dirlight.
You should also increase the LightRadius of the light to 600 to extend the reach of the light a little further.
In addition to the DirLightclass, there is an additional light class that is useful for creating outdoor scenes—the StaticSunLight class. StaticSunLight objects require a working skybox in order to light the map. StaticSunLight objects light the level through the level's sky portals. Most of their properties are self-explanatory and similar to DirLight objects, but StaticSunLight objects do not have Field of View (FOV). In addition, StaticSunLights have a Bias property, which controls the softness of the light. Varying the bias values changes the cast shadows from sharp and harsh-edged to soft and rounded.
In order for StaticSunLight to affect your terrain, you must set the terrain brushes' DirectionalLight property to TRUE.
StaticSunLights illuminate both normal brushes and terrain brushes, so you can use a single StaticSunLight for all of the main lighting for an entire level if it's largely open. It is still recommended to place individual point and directional sources around your level for highlighting and fine control.
LithTech uses a combination of lightmaps and vertex lighting to light worlds. Lightmaps are textures generated by the processor at world compile time. Lightmaps contain ray-traced lighting information for an individual polygon. Lightmapping is used for all world geometry, along with world models, except for terrain. Terrain is lit by vertex colors, generated at compile time, and gouraud interpolated across the polygons. Models are dynamically lit with normal lighting, attenuated with the equations below.
Below is the list of equations used by LithTech to calculate light attenuation. Light attenuation is the value multiplied by the light color to obtain the final lighting value for a vertex or lightmap texel.
Key: Att = Attenuation, d = distance from light, Lr = Light Radius.
Lightmap & Terrain lighting (Default): Att = 1 – (d / Lr)
Custom Model lighting: Att = 1 – (d 2 / Lr 2 )
The Direct3D & PS2 model lighting use the function:
Att = 1 / (A + B d + C d 2 )
Processor gives the option to use this same lighting model for lightmaps & terrain (marked Inv Quad Falloff in the Processor dialog). This lighting model generally yields more realistic looking lighting.
A, B, & C are constants: A = 1, B = 0, C = 20 / Lr 2
We recommend that if you are using the D3D or PS2 T&L lighting models for your models that you also use the Inv Quad Falloff for your world lighting (as your lighting values will more closely match the world lighting values). Note that if you have build your levels with the older lighting models, your level will probably appear darker and you will probably need to increase the radius of many of your lights to compensate.
The last way of creating an entity is by binding it with a brush or group of brushes. In order to bind brushes, you first select the brush or brushes you want to bind, then right-click and select Bind to Object from the context menu. The entities list appears and you can then select the entity you want to bind to. By binding brushes to an entity, you tell the entity to use the brushes to define its structure or its volume. Two general classes of bound objects commonly appear in LithTech: WorldModels and Volume Brushes .
WorldModels change the geometry that they’re bound with into an object that can be moved, destroyed and manipulated. Usually, brushes can never move or be changed in any way. WorldModels are the basis of things like doors, exploding walls and elevators. Some props may also be constructed out of WorldModels as well. In the later section about different types of models, you can learn more on how to use WorldModels.
Volume brushes convert the brushes they’re bound to into spaces that affect players standing inside them. They’re the basis for things such as water, zero gravity rooms, poison gas and teleporters. In order to fill a pool with water, you would make an empty pool. Then you would create a brush that takes up the space of the water in the pool. Last, you would bind the brush to a volume entity with water properties.
There are many different types of entities and they tend to vary dramatically from game to game. It’s a very good idea to ask your game’s coders to carefully document their work and to write explanations on the use of their custom entities, since they are the ones with the greatest understanding of the specific entities used in your game. DEdit itself can provide help on properties on the fly using a file called Classhlp.BUT.
You can view a separate tutorial that describes how to add a prefab, simple, or complex sky to your NOLF level. Click here.
The term “geometry” in LithTech actually describes several very different classes of object: Models, WorldModels and World Geometry. It’s useful to know and remember the difference between these three classes of geometry, since they are made very differently and can be used in very different ways.
Models are, as the name implies, objects built in 3D Studio or another external modeling package. Their mesh is stored in an .ed file that is exported from that package and loaded by LithTech. Models are usually used for objects in the world that have a high polygon count, require complex animation or would be very difficult to make inside DEdit. Players, weapons and props like dishes and chairs usually are made with a model. Doors, walls and other large, structural features are usually not. Models can’t block visibility the way world geometry can, and they generally don’t integrate with the brushes in the world. Instead, they sit on top of brushes. This makes them very suitable for props like chairs and desks, since you can quickly place a large number of them with less work. It makes them unsuitable, however, for making a whole building or parts of terrain.
WorldModels are a hybrid: they consist of an object with a brush or brushes bound to it, which provide its mesh. The brushes are built and textured inside of DEdit, which allows better integration with the rest of the level. Unlike regular brushes, though, WorldModels can be translucent, can move and can be destroyed and removed from the level. WorldModels are often used for parts of a level like large mechanical props, vehicles, doors, glass and fences. They usually don’t block visibility but can be made to do so with customized game code to an extent. They’re not useful for character models, since they’re not easily deformable.
World Geometry is made of brushes. These brushes are (with the exception of terrain) are always built and textured in DEdit. World Geometry makes up the vast bulk of almost all worlds in a DEdit game. Its main ability is that it can block visibility. It’s used for walls, ceilings, columns, ground, sky and many other solid, immovable objects in a world. However, due to World Geometry’s limitations (can’t move; can’t be translucent, must be convex), world geometry must be bound up in a WorldModel to make things like doors and .ed models are much more appropriate for complex objects like statues or chandeliers.
There is overlap between the various classes. You can build a vehicle as either a Model or a WorldModel, depending on how flexibly you need it to move. You could even build a vehicle out of World Geometry if it was never going to move. Likewise, trees can be made as any of the three depending on what’s most convenient. For complexity, the Model is preferable. For interactive, solid world objects, the WorldModel is usually best. For solidity and visibility control, World Geometry is best.
The Processor ( Processor.EXE ) is a separate executable from DEdit itself that is used to pre-process your level. Pre-processing a level is a great deal like compiling code. You take the human-readable version you constructed and turn it into a machine-friendly and heavily optimized version for the computer to use. The computer doesn’t have much use for your version, and you can’t do very much with the computer’s version. You must process your level in order to run it in the game.
In LithTech, the human version of your level is stored in an .ed file that is readable by DEdit. It contains all of the brushes in the level as you laid them out, references to all the textures needed by the level, a list of all its entities and any other information about things you’ve added to the level.
The computer version of an .ed file is a .DAT file. .DAT files have the same name as the .ed file they were compiled from aside from the extension. Thus, if you built a level called “Level01.ed” and compiled it, you would get “Level01.DAT” as a result. Unlike the .ed file, the .DAT file doesn’t contain all your brushes as you laid them out. It also does contain some things that your .ed file does not.
The first difference in a .DAT file is that the brushes in it have been broken down, digested and reassembled so as to optimize them in number and in layout for actual gameplay. Any polygons on the outside of the level or in areas that the player will never be able to see are stripped entirely away. The remaining brushes are all split up at each point where one brush touches another until nothing remains but convex shapes. You can read more about this process in the section below on optimization, as well as how to see the splits that result.
Another difference in a .DAT file is that things are now arranged as a series of hulls , which are LithTech’s way of sorting out the areas within the level to determine visibility, as well as the connections between them. Between these two factors, a map inside a .DAT file and the same map in an .ed file would be vastly different if you could open and compare them.
Another addition in the .DAT file is lighting data. Although you get a preview of each light’s effects in DEdit, the actual intersections and combinations of each light don’t get calculated until the level is processed. All of that data is then added into the .DAT file, mainly in the form of a second layer of textures for all brushes that are lightmapped.
Last, there’s the addition of visibility data. The Processor builds a list all points in the level that specifies which areas can possibly see into which other areas. This is an important step because it vastly speeds up all but the smallest levels by cutting out of view any brushes that the player doesn’t need to see. As an example, if the player is standing in a small room on one side of a hallway and a doorway on the other side of the hallway leads into a large room full of boxes, the Processor might determine that there’s no way for the player to see into the large room without moving a substantial distance. It will therefore remove the large room from the visibility list for the small room. The engine will therefore not render the large room if the player’s in the small one, freeing up cycles when the level is running.
If this sounds like a time-consuming process, that is because it is one. Compiling a large level completely with all optimizations turned on can take hours. Quick compiles can sometimes take as long as 30 minutes, although generally the time is much less. However, Processor gives you fine control over all of the steps in the compile, and by changing what gets processed and how thoroughly you can choose between a highly optimized level that’s ready to ship and a quickly-processed level when you want to quickly check your results.
There are a few settings you will want to know about for all compiles. When you start the Processor by selecting Process from the World menu in DEdit, this dialog appears.
DEdit remembers your settings from session to session, but you must set them the first time you run and may need to change them if you’re working on more than one project. Our first important parameter is Project Directory , which informs Processor where the files for your game are located. You should set this to the full Windows path to the folder where your game’s .DEP file lives. This enables Processor to get any necessary information out of textures in the game. Since some textures have lights or other special effects, it’s important to make sure you have the right value here.
When a brush edge meets another polygon’s edge not at a vertex, this forms a situation known as a T Junction (the name comes largely from the fact that it does indeed look like a T when the edges are perpendicular to each other). This can result in pixel-sized gaps in the final image, most commonly known as sparkleys . You can use the Fix T Junctions function to insert a new vertex into brushes that have T Junctions on their edges so that the these gaps can be avoided. Ideally it is best if the level artists handle resolving T Junctions since using this feature can occasionally result in sliver-like polygons.
The second is the Log file check box. Checking the box tells Processor to store a journal of its activities on the hard drive. It will also display this information while it runs, but this is still sometimes useful. For instance, if a level causes Processor to crash, you can use the log to figure out what part of the compile the crash happened in.
Last is the Extra Parameters field. You can use this field to specify any command line option that Processor supports. It’s highly advisable that you look over the list.
The first type of compile is the quick compile. If your level is under heavy construction, hasn’t been sealed and you only want to look at a few changes you made to lighting or brushes, this is the type of compile to do. In this case, you only care that geometry is built and the level is lit so that you can look around. You must set Import Geometry and should probably set Ignore Hidden , Import Texture Flags and Apply Lighting . If your level makes heavy use of lights and the lighting stage takes a long time, set Vertex Lighting Only for a speed-up.
The second compile is a more thorough (although not full) compile. This is used when you want to check the quality of lighting and your geometry placement, as well as to get a rough idea of polygon counts. Set all of the flags listed above except for the two for lighting speed-up, and also the Light Animations button, which tells Processor to build the lightmaps for any animated lights you’ve added. Last, set the Full Optimization flag and the Fast Approximation flag. These tell Processor to generate visibility data, but to build it quickly instead of accurately (which would take longer).
Next is the full compile. Check all the options from the thorough compile above except for Fast Approximation . For a really thorough compile, you can vary the settings of the Less Polies/Balanced Tree slider (higher is more optimized) in the Advanced section. Generally, the slider should be near the top, but perhaps one notch down. Having the slider all the way up can cause the compile to take longer and sometimes causes errors.
This compile is much slower, but since the Processor works its hardest to make the level fully optimized, the level will run much more smoothly within the game after a full compile. This is the only compile you should ever run on a level that’s about to be released. All other compiles sacrifice in-game performance for reduced compile times. No user will care if the level took six hours for you to compile or six minutes as long as their frame rates are high.
The last compile type (entities only) is used when the only changes you’ve made in a level involved entities and not brushes. For example, if you tweak the values of your lights and then recompile, you haven’t changed any brushes. In these cases, the Import Geometry checkbox will not be grayed out, allowing you to uncheck it. When you run Processor, instead of building your geometry data from scratch and throwing out your visibility data, Processor will retain them and just write out the new entity settings. This leads to a much faster compile, especially on large levels. However, this type of compile can occasionally lead to problems in the output .DAT file and shouldn’t be used on a level that’s about to be released to the public. As always, use only a full compile on such levels.
Once you actually run Processor, the dialog will change to a log window and a display of progress bars showing compile progress. If you read the log window you can learn a lot about how the level is being handled. Some indicators you should watch for:
Number of Unseen Polies Removed: 0 — Watch for a message stating the number of removed polygons. If there’s a low number in relation to the total number of polies (especially zero), your level may have a leak. See the optimization section for more on leaks.
** Couldn’t find any textures. (Is project path set?) — This message usually indicates that you haven’t set your project path correctly. Usually not a problem, but if your game uses texture effects it can cause issues. Check the project path setting.
Found 1 problem brushes — This warning indicates that Processor found a brush it doesn’t think is valid. You can use the SelectProblemBrushes parameter to track these down, and should do so as soon as they appear.
It’s actually fairly easy to make a gorgeous Notre Dame-scale cathedral in DEdit. Once you know the basic controls, you can pretty quickly lay out the brushes, apply the textures and add in the lighting necessary to make such a structure. However, it is also extremely easy to build a level that:
This is truly where the science of level design begins to take a back seat to the art. Though there are some basic rules and a lot of guidelines to optimizing levels, the best way to learn good optimization techniques is to experiment and to carefully observe the results you get inside your levels. You must think about optimization right from the moment when you first begin designing your level, and you must watch the performance of your level every step of the way as you build. Unlike any other computer art product, computer games are rendered in real time , and this restricts you substantially in what you can get away with in your levels.
Levels can become bogged down for a number of reasons. The first of these is high polygon counts in a scene. Even a simple empty room that has only walls, floor and ceiling can be made up of several hundred polygons. In order to apply lighting and tune the level’s performance, the brushes that you specify inside DEdit are broken down, juggled around and reshaped by the Processor as it builds the in-game .DAT file out of your .ed file. As mentioned above, this process is one of the reasons why you can’t edit a .DAT file in DEdit. To measure the polygon counts in your game, you use the ShowPolyCounts console command. As a general guideline, the game designers for NOLF kept multiplayer levels to around 600 polygons/scene in general on multiplayer levels and 800 or so for single-player levels where frame rate was not as vital. It’s important to perform some tests of your own on your target platform to develop your own standards.
Lighting a level via lightmapping requires that large brushes be broken down into smaller chunks. This usually happens along texture boundaries. Thus, if you have a large room with a 64x64 floor texture, the floor may be broken up into dozens of 64x64 chunks when in the editor it is shown as a single brush. The reason this is done is to create the lightmap textures, which give the floor lighting. In the case of a moderately large room, this may add 200 polygons to the scene, but in some very large rooms it can add 400 or more polygons. It’s important to take that overhead into account.
There are ways to reduce this press somewhat. The first is to try to break up large spaces so that only some of the space is visible at a time. The second, useful in outdoor areas without great ground detail, is to scale up the texture on the floor. Often, a 64x64 dirt texture looks acceptable if scaled up to 128x128. In some cases it even helps give a sense of scale to the outdoor room. It’s important to test this technique yourself and decide whether or not you like the result.
There are also brush properties that you can use to affect the method used to light your brushes. The LMGridSize parameter listed in the WorldInfo string section describes how you can scale up your lightmaps in order to reduce the number of polygons created for lightmapping, which can lead to a decent savings in poly counts for large rooms. In many outdoor cases (one of the most common places where problematically large rooms appear), using Gouraud or flat shading can prevent subdivision while still giving a good light effect.
The second cause of high counts is complexity. It’s very hard to resist the urge to put every detail into your geometry instead of using textures to create detail. However, it is much more expensive to add detail using geometry than it is to imply detail through tricks of the eye, lighting and texturing. Avoid nonfunctional detail that can be added through textures like molding/trim, curlicues, grooves and bumpy surfaces. A level designer’s art is figuring out how to imply detail. Ask your texture artists to build a grooved surface or the face of a curlicued building ledge, and then apply that texture to a simple flat surface. Use as few sides as you can get away with on your columns and carefully consider how to build each shape with the fewest polygons.
Another typical cause of high counts is intersecting brushes. Every place where one brush touches another, the processor splits the touched brush in order to remove the hidden sections of each brush. However, this can drive counts up very significantly. A large, square room that’s normally lit would be subdivided into a simple grid of square brushes. If you place a square column in the middle of the room, the room’s still split along a square grid, since the splits around the base of the square column run parallel to the grid of splits made for lighting. However, if you put down a 12-sided column in the middle of the room, split lines run out from each of the 12 vertices that make up the base of the column. These lines disrupt the even pattern that existed before and scatter new brush splits throughout the room. You can observe this by using the DrawFlat and ShowSplits console commands.
The best way to avoid this problem is to carefully pre-plan before adding details in areas where their effects will be drastic. One way to do this is to bind such objects in a WorldModel in cases where that won’t affect the object’s functioning. Also, in many cases such as light fixtures and some columns, you can build your fixture and then move it 1 to 4 units away from the surface it would normally be touching. That prevents the split, and in many cases the player will never notice the difference. You must be careful using this technique, however. If you place a light in the right location, it will give away what you’ve done since the lifted object won’t cast a proper shadow.
Another issue that increases your polygon counts in a room is visibility leaks. To explain, the computer and the player see the level in different ways. The player can’t see anything that’s behind a solid wall or any solid surface. However, the computer always looks just a little bit ahead and pre-draws some objects that may not yet be visible to the player. This is for two reasons: One, the computer estimates cautiously when it decides what the player will be able to see. Two, the computer pre-loads some geometry that it thinks the player may soon be able to see in order to spread out the press of loading the polygons and textures.
This usually comes in the form of a wall or other fixture in the next room that adds to the poly counts in the current room. Sometimes the increase in counts makes very little sense. You can have a very small room without any real detail such as an entryway with the polygon counts of a much larger, more detailed room. If you look around in a room like this, you can almost always find either a hallway into another more detailed room or a leak to the outside of the level.
Two useful console commands come into play when troubleshooting visibility leaks: LockPVS and Wireframe . The first command, LockPVS , tells the engine to continue drawing whatever is currently visible to it (the Potentially Visible Set ) and not to load any further brushes into the world until it’s un-frozen. Use this when you’re getting high counts in a particular view and want to see what’s being drawn in another room. Once you get the high counts on your screen, enter LockPVS 1 on the console. After that, you can walk the area and see what the engine’s drawing. Only objects that are visible from the point where you locked the PVS will be drawn.
The Wireframe mode is harder to work with but more flexible. It switches your view to a wireframe view of the level. Since all brushes are transparent in wireframe view, you can see right through a wall into rooms on the other side. This means you can also see what brushes are being drawn in rooms other than the one you are in. Though it takes some getting used to, this mode makes it possible to figure out exactly when and where the view of a room or object is cut off, making it extremely useful when you want to check your visibility blocks. This command should be used in conjunction with the ForceClear command if you get bad redraw effects when WireFrame is turned on. Some games do this automatically. You may also want to use the DrawFlat command to turn off textures, which makes it easier to see the wireframe lines.
You can break visibility between rooms most certainly using a corridor with a pair of 90-degree turns in it. A U-turn should totally cut visibility, and an S-turn with the proper length of corridor in between the two turns will almost always work. Below that, controlling visibility becomes an art. Often, you will be amazed by what the engine decides you can see from a given point. It’s important to carefully walk your level and watch polygon counts for this reason.
Note: If you haven’t done a Full Optimization compile on your level, you cannot rely on the visibility or poly count results you obtain. Full Optimization cuts down counts far, far more than a Fast Approximation does. Similarly, if you don’t compile with optimization turned on at all, your whole level is visible from all points, leading to counts that are much higher than they will be after optimization.
In order to increase your chances of blocking off line of sight between areas, there are several things you can do. First, make use of kinks in between areas as described. Second, make sure that walls extend from the floor of a room to its ceiling. Third, make sure your walls fit snugly together. Fourth, keep the number of connecting doors, windows or vents between rooms as low as is reasonable so that you can more easily troubleshoot. Fifth, treat your outdoor areas in the same fashion, dipping your sky portal brushes down like a ceiling to close off one region of the outside from others. Use hills, hedges and tall buildings as walls to reach up and touch these sky brushes, thus completing the seal. The last tool to help you close off one area from another is the hullmaker brush.
Hullmakers are special brushes whose Hullmaker property is set to True. To make a hullmaker brush, you switch to Geometry Mode, and then lay the points for the brush you want to create. The resulting brush has a zero thickness (which is as you want it). You should place hullmakers in doorways or hallways where you feel visibility should be blocked off but you can still see polygons in the next room. Make sure that your hullmaker completely fills the doorway or hole that you are trying to block, and that the only property set to True on the hullmaker brush is Hullmaker . The player should never see these brushes inside a game level. Their sole purpose is to split the hulls of the level where they’re placed, encouraging the engine to block visibility there.
Hullmakers do not work 100 percent of the time; often, the engine decides that despite the split the player can still see past and into the room beyond. Sometimes, placing hullmakers can even split up brushes in ways that drive up polygon counts. Don’t dump hullmakers into a level expecting miracles. Pick a problem area and carefully add hullmakers or modify the layout around the area until you see the results you want
The last way to reduce polygon counts is to make sure that your level is sealed . The best way to think of your level is as a submarine or spaceship: right outside it there is a bad, unfriendly place. The interior of the level should always be isolated from the outside by a solid shell of brushes, none of which are bound to WorldModels, have their Invisible flag set, or have their Detail Level set to 1 or higher. In other words, it should be impossible to see or reach the outer space around your level. This is where careful brush creation habits and compiling regularly while you build are helpful. It’s much easier to catch a leak when you first cause it than after you’ve built an entire room.
If your level does develop a leak, you can use a leak file generated by the Processor to help find it. To create a leak file, enter the command string –leakfile myfile.leak in the Extra Parameters field of the Processor. Once the Processor makes its leak file, load it into DEdit using the World menu to select Debug , and then click Load Leak File . This helpsyou to follow the path that appears until you find the hole.
Plugging leaks is important for three reasons. First, leaks can cause parts of the outer shell to be visible inside the level, unnecessarily increasing your counts. Second, leaks keep the level’s outer shell from being removed by Processor, increasing the size of the level’s .DAT file on disk. Last, if Processor has to do visibility calculations for the outer shell, it will take a great deal longer to complete. It pays to plug your leaks.
Another concern is a factor called overdraw , which is the number of polygons drawn on screen that are actually out of the player’s view behind other polygons. This is related closely to the visibility optimizations referred to previously. You can often find high levels of overdraw in rooms with lots of detail: columns, low walls, complex fixtures and cracks can all lead to overdrawing. Overdraw in a scene is measured using the ShowFillInfo console command. In the development of the game Shogo , for instance, values of 2-3 here were considered acceptable and values of 4-6 were danger signs. Once again, testing on your target platform to obtain figures for your own game would be wise.
Besides geometry-related factors that may slow down your game when it’s running, you can also get significant slowdowns if you use too many textures or several overlarge textures in a scene. Even in the age of AGP, if you use a 512x512 texture for everything from tiles on the bathroom floor to murals to the nameplate on a door, the game will run more slowly. As with many problems, this is best addressed in the design stages rather than in the testing stage.
You should try to resist the urge to use the largest texture possible and instead work to find a balance between a texture that looks good and is small in size. Objects that won’t get much scrutiny like floor/ceiling tiles, wall-to-wall carpets and grass should usually be given small textures. Objects that the player will focus on (view screens with data, pictures, signs) can use higher-resolution textures. The console command ShowTextureCounts provides information on textures for help in troubleshooting.
Entities can also affect game performance. If you build a huge particle fountain that creates 1000 particles every second with a decay time of 10 seconds on each particle, the engine is going to be very busy keeping track of the particles. Likewise, large, moving objects such as props made from WorldModels can slow the engine down as it tries to manage their physics.
Character models and AI can also affect frame rate. A level that runs fine with just the player on it can bog down seriously when two very intelligent AI enemies are added to it. Likewise, a Boss character with thousands of polies in her character model will slow the engine much more than a minor character with just a few hundred. Be careful how you code, design and place your AI. Also, be sure to test the results to make sure you haven’t stressed the system too much. The ShowTickCounts command gives useful information for figuring out these sorts of generalized issues by listing what portion of the engine’s time is spent in what area, be it rendering, sound or game code.
As mentioned before, optimization is more art than science, and it takes practice. The warning signs of trouble you should always heed are low frame rates, high polygon counts in a scene, and sudden jumps in the length of time it takes to process your level. Any of these should make you take notice. Immediately backtrack and figure out what has caused the issue. Even if you don’t do anything to correct it at the time, performance issues are almost always easier to fix if they’re identified early. It is heartbreaking to have to discard a level that is completed but completely unworkable, and you will do so if you don’t pay careful attention to optimization throughout the construction process.
Below is a list and basic description of game objects used in the creation of No One Lives Forever. If you have a question about the meaning of any of the available properties of an object, you may access the online help built into DEdit by placing your cursor over the property in question until the cursor is replaced by a question mark. Left click to display a definition of that property.
AmmoBoxes are placed in the world as a powerup. Each Ammobox can contain up to ten different kinds of ammunition.
Cameras show scenes in the world outside the player.
This is a controller object used for cutscenes and in game dialog.
ClientLightFX can be used to create things like flashing lights, lightning, and switchable lights. Although many objects and weapons generate their own lights, it’s still useful to be able to individually place lights to create more customized effects. You can also design a ClientLightFX object so that it creates high-quality animating lightmaps or casts shadows on moving objects.
This object controls properties of up to 8 objects. Just setup its TargetX properties for the objects and send it one of these messages:
· FADE <parameter type> <destination value> <duration> [Wave type (default is SINE)]
Fades to the specified destination value over time.
· FLICKER <interval min> <interval max> <message to send> [count, default -1 which means forever]
Sends a trigger message to the objects in a random time between the specified interval.
Stops whatever happening.
· Supported parameter types:
· Alpha - value 0-1
· Color - values 0-255, must be specified in quotes like "1 2 3". If you specify an X for the value, that value won't be changed.
· Wave types supported:
· SLOWOFF (linear until halfway, then sin for other half)
· SLOWON (sin for halfway, then linear for other half)
· Sample messages:
· To send a message between every 5 and 10 seconds forever:
FLICKER 5 10 "Some message to send"
· To send a message every 3 seconds, 10 times:
FLICKER 3 3 "Some message to send" 10
· To fade alpha to 0 over 5 seconds using a sine wave:
FADE ALPHA 0 5 SINE
· To fade color to "0 128 256" over 7 seconds using a slow on wave:
FADE COLOR "0 128 256" 7 SLOWON
· To fade red and blue to 111 over 9 seconds using a linear wave:
FADE COLOR "111 X 111" 9 LINEAR
DemoSkyWorldModels allow objects to render in the skybox in a single step. A DemoSkyWorldModel is an object that fuses a WorldModel and a SkyPointer. By doing this, binding a brush to the one object allows it to be rendered in the skybox without the need for any additional objects.
DirLights act like a spotlight, shining only within an arc that you specify instead of in a sphere like a regular light. You can aim them to any angle you choose.
This is an incremental colored bar meter displayed on the screen. It is useful for “boss” fights.
This object displays a timer on the screen in game.
Doors are objects you bind to a brush to create a moveable worldmodel.
This is a subclass of the Door object The Breakable object can be used for both collapsing floors (default behavior) and falling objects. Since it is a subclass of the Door object, it shares many of its properties.
This is a subclass of the Door object The HingedDoor object is used to emulate the functionality of a door that swings on hinges. Since it is a subclass of the Door object, it shares many of its properties.
This is a subclass of the Door object The Switch object is used to create an easily identifiable “switch” object that the player can interact with to control things within the game environment. Since it is a subclass of the Door object, it shares many of its properties.
This object will store up to 5 different "events", with each event containing an integer value and two commands. The idea is that the game code can increment/decrement the EventCounter's value (by sending ”Increment” or “Inc” and ”Decrement” or “Dec” messages). When the counter’s value is equal to one (or more) of the EventXValue (i.e., Event1Value, Event2Value, etc.), either the EventXIncToValCmd or EventXDecToValCmd will be processes. In other words, how the counter gets to the EventXValue determines which command is sent. For example, if Event1Value = 2, and the EventCounter’s staring value is 0, if the EventCounter gets 2 “Inc” messages, the Event1IncToValCmd will be processed. If at this point the “Inc” message is sent again (so the counter is now at 3), and then the “Dec” message is sent to the counter, the Event1DecToValCmd will be processed. This object also understands the “Lock” and “Unlock” commands (Inc/Dec don’t have any effect on the counter if it is locked).
This is an object used to place explosion effects in the world.
This object is a subclass of the Explosion object. It is used to emulate land mines. Since it is a subclass of the Explosion object, it shares many of its properties.
A FastApproxArea marks an area of the level (bounded by hull makers or portals) to use the Fast Approximation method in the preprocessor. This can be useful to make preprocessing go faster in outdoor areas where visibility can’t be optimized very well anyways. This is an object that was not used in the creation of NOLF and is not supported.
This is an object used to create fire effects.
This is the point that the player enters the game world.
This is an object used to place gear power up items in the world.
This is an object used when you wish to send the same message to several different objects at once. It acts as a simple relay.
This object is used to define an area as the inside portion of a shell. The GameStartPoint normally does this. But, sometimes you will want to build other separate areas that are cut off from the main map, but that are still a part of the level. To keep these from being removed when the level is processed, you will need to add an InsideDef object to define the area as part of the inside shell.
This is an object used to define a point in the path of a keyframed object.
This is an object used to define a point in the path of a keyframed object.
This is a special light object used for animated lighting.
This is a basic point light, or omni light object used to light the world.
This object is used to create lightning and electrical effects in the game.
This is an object used to place gear power up items in the world.
This is a light that only affects models.
ObjectRemover contains several "groups" of objects. For each group, you may list up to 6 objects. Specify how many groups of objects you wish to keep in the "GroupsToKeep" property.
On the first update, the ObjectRemover will randomly select the groups of objects it will keep (based on how many were specified to keep), and remove all the objects in all the other groups, and then remove itself.
This object is placed to define the outside leaf of the world.
Any time you want to spawn a large number of similar simple objects in one location or area, you probably want a ParticleSystem object. Particle systems create a cloud of objects, usually sprites or simple models. They can make the sprites move, determine the area where they appear and how long they remain after being created.
The Prop object is used to place .abc models into the game world. Props are typically things that would be too complex or impractical to be created from world geometry. Examples would be plants, telephones, detailed furnishings, etc.
This object is a subclass of the Prop object. It is used to add detailed interactive doorknobs to doors in the game. Since it is a subclass of the Prop object, it shares many of its properties.
This object is a subclass of the Prop object. It is used to add bits of information that the player can discover during the course of gameplay. These are typically in the form of letters, rolls of film, briefcases, etc. Since it is a subclass of the Prop object, it shares many of its properties.
This object is a subclass of the Prop object. This object is used to place KeyPads in the world that the player can unlock with the Code Decipherer gadget. Since it is a subclass of the Prop object, it shares many of its properties.
This object is a subclass of the Prop object. This object is used to place Locks in the world that the player can circumvent using the lock pick, welder, or by shooting, depending on how it is set up. Since it is a subclass of the Prop object, it shares many of its properties.
This object is a subclass of the Prop object. This object is used to place PlayerVehicles in the world that the player can interact with. Since it is a subclass of the Prop object, it shares many of its properties.
This object is a subclass of the Prop object. This is a different way of managing prop placement in levels. We found that a lot of the props that we placed were set up the same as each other. Yet we still had to set all of the flags. The PropType object places props by way of a simple dropdown menu. The dropdown menu refers to a bute file where the all of the prop flags have been predefined. Since it is a subclass of the Prop object, it shares many of its properties.
This object is a subclass of the Prop object. In default mode works like a security camera (i.e., scans back and forth and it's yaw and fov can be adjusted). However, you can alternatively give it a Target object to follow (e.g., you can set up a keyframer and have the searchlight follow the keyframed object). Also there is a SpecialFXStuff property group that allows you to change the special fx (i.e., beam radius/alpha, dynamic light color/radius, and lensflare fx). Since it is a subclass of the Prop object, it shares many of its properties.
This object is a subclass of the Prop object. This object is used to place security cameras in the world. Since it is a subclass of the Prop object, it shares many of its properties.
This object is a subclass of the Prop object. This object is used to place “handles” in the world that the player can attach to using the belt buckle zip hook gadget.
The RandomSpawner is used to spawn objects randomly through multiple Spawner objects.
This object was not used in NOLF and is not supported.
These are objects that spin on any given axis. The most common example of a RotatingWorldModel would be a spinning fan.
ScaleSprites are free-standing textures that don’t need a surface to appear on. ScaleSprites get compounded into a lot of other game objects, but they can be used on their own to make a lot of things happen too. ScaleSprites are used for all kinds of things — halos around lights, floating symbols, decals on walls and objects in the sky
The ScreenShake object shakes the camera when triggered.
SkyPointer objects allow the objects that they target to render in the skybox of the level. Only WorldModel-derived objects and Sprites can appear in the skybox.
This object allows you to place sounds in the world.
This is a generic object used to “Spawn” objects into the game world.
This object is used in conversational dialogues in a cinematic trigger. If a character needs to have a conversation with a non-AI object such as an intercom, this is the object that will fill the position of that AI in the conversation.
This object sprinkles particles around the player. The particles move around in a random direction and fade out, as they get farther away from the player. The Sprinkles object supports 8 sets of particles or models, each with its own texture, size, speed, and spawn radius.
The StaticSunLight object supplies levels that have a skybox with light from a sunlike source. The light radiates into the level through all skyportal brushes as if from an infinitely far point. This sunlight’s direction is determined by the rotation of the StaticSunLight object. Its position doesn’t matter, since the emitted light acts as if it comes from an infinite distance. The StaticSunlight’s position is ignored.
The Steam object is a form of the ParticleSystem object that has been set up to more easily create particle effects resembling jets of steam. The effect created by this object travels down the forward facing vector of the object.
This object is used to define the position and rotation of a point in space that the player or an AI can be moved to instantly.
Terrains are a special case object similar to a WorldModel that are able to contain a group of brushes. Although they get the full benefits of game physics, they never block visibility or cast shadows and they cannot move or be transparent, but they have the special property that they can contain one-sided brushes. This allows them to take meshes from external 3D packages and use them as valid world objects. You can model very irregular objects in an outside package and still have it operate in the world like world geometry instead of model geometry using a terrain object. It is important for performance reasons to only use a single terrain object to hold all terrain geometry in your level. It won’t affect their physics even if pieces are in totally separate parts of the level.
By binding world geometry to a TranslucentWorldModels it becomes a world model and inherits properties unavailable to normal world geometry. The three main reasons for binding geometry to a TranslucentWorldModel are translucency and chromakeying, to be able to keyframe an object, and to simplify the physics of particularly complex geometry for performance reasons.
Triggers can be used like tripwires. When the player or an A.I. character passes through one, it sends a message to any other objects you want, telling them to do whatever they do. If a keyframer is the target, the keyframer will start moving the objects attached to it. If the target is a door, the door will open or close. Triggers can trigger any object, even other triggers.
This object is a subclass of the Trigger object. This object is used to trigger the end of a level. Since it is a subclass of the Prop object, it shares many of its properties.
This object is a subclass of the Trigger object. This object is used to create laser trip wires that are invisible without the use of the infrared sunglasses gadget in NOLF. Since it is a subclass of the Prop object, it shares many of its properties.
Volume brushes are used for a number of effects — Water, damaging environments, rainy areas, and AI movement. A VolumeBrush object is designed to bind to a brush and use the brush to determine its area of effect. If the effect is continuous, such as rain or snow, it only occurs within the space defined by the brush. If the effect happens to players and Ais, it only happens to them when they’re within the volume. The effects of the volume are triggered when the player enters the space and usually un-triggered when they leave.
This is an object used to place Weapon power up items in the world.
This object is placed in every level to define many of the global properties of the level.
This object was not used in the creation of NOLF and is not supported.
This object was not used in the creation of NOLF and is not supported.