![]() Introduction This material is meant to be a supplement to the already available Ogier documentation as opposed to a replacement. For this reason there is not much coverage of areas already dealt with by the main documentation, and as such it is highly recommend to look through that as well. The information contained within this document is considered to be intermediate, having some knowledge of the tools or experience working with similar engines is assumed. Note that this document is based primarily on the original releases of the games and tools, and not the re-releases (e.g. Enclave Wii or HD). I would like to extend special thanks to the developers who helped answer some of the questions along the way, and who were involved with the release of this great game and toolset. If you have any questions about the game or tools, feel free to contact me and I'll do my best to answer them. If you use content from the sample level in your own work I would appreciate being credited. A community for discussion of the game, engine, and editing tools is available at the Enclave Discord Server. Files Included
With This Document
Additional Ogier Tips Common Editor Troubleshooting Useful Console Commands Example Map Documentation
File Editing
Color Format Sky Listing & Atmospheres Terrain & Organic Shapes Importing Brushes Surfaces, Textures, Models, Sounds, & Animations
Files Included With This Document There are a number of files included with this documentation, the following are for the main examples:
The following files are completely optional: Atmospheres.xmp
- A map
which includes preset skies, NH fog, distance
fog, and sunlight taken from each level in the game.
Gothic.ttf, FontExample.cfg, & FontExample.mpp - Example of files used when compiling fonts for use with the game. nodetype.txt - An updated definition file to use with Ogier, adds previously missing functionality. (Goes in ..\Enclave\Sbz1\Dev) Surf_DM01_NoBump.xtx - A surface file which includes the Iellon Dungeon sewer textures without the bump map effect. Surf_LightningAlign.xtx - Example surface file containing a material to help align the lightning texture. (Goes in ..\Enclave\Sbz1\surfaces) SoundExample.mmp - Example of a MMP file used to compile audio files and 'complex' sounds for use with the game. TextureExample.xtx - Example of a XTX file used when compiling textures for use with the game. The following are also optional, and relate to the File Editing section of this document:
Additionally there are files not included with this documentation which may be downloaded separately: Ogier_Documentation.zip
- The official Ogier documentation which this file and its samples are
a companion to.
Ogier_ModelExample.zip - Example files for compiling custom models. These files are included with the KotT GDK. Enclave_SoundBrowser_Fix.zip - Recompiled audio files and source which can be used for enabling in-editor sound. Enclave_DeveloperTextures.zip - Developer textures for use with Ogier. Useful for blocking out and planning levels. Enclave_NorthernWatch_Source.zip - Source files for the custom survival level 'Northern Watch'. Additional Ogier Tips Below are a number of general Ogier tips to keep in mind.
Common Editor Troubleshooting Below are tips regarding issues which may be experienced with Ogier.
Useful Console Commands Enclave's console can be activated either by adding the line CON_ENABLE=1 to ..\Enclave\environment.cfg, or by renaming the Config.mmp to DevConfig.mmp in ..\Enclave\. (Renaming to DevConfig might also activate a number of additional key bindings.) Once activated, the console is opened using the ~ key. Additional console commands and their usage can be found by typing 'help' into the console and then using Page Up and Page Down to scroll.
Example Map Documentation The following is detailed documentation regarding each example in the included map. Each section describes how the effect is achieved and offers related tips and details. The level also includes a large amount of geometry prefabs for reference or use in your own projects. If you would like to view the precompiled demo map in-game, place it in ..\Enclave\Sbz1\Worlds, then open the in-game console and type 'map sandbox'. When it comes to the scripting, you may see similar things done different ways in some examples. For many cases there are any number of methods to set things up to similar effect, so keep this in mind! Liquids & Fog Flowing
Lava
(Lava that flows, as in Kam-Zara) ![]() The lava flow is made using a spline sheet (Shift + 6) with modified subdivisions and a LAVARIVER material from the Water surface file applied to it. In order to create the effect of being liquid, brushes were added below the spline with the top texture set to *PHYSLAVA (this material has special properties which causes brushes it is applied to act as a liquid with predefined depthfog). In order to make the effect a little more believable, a cm_smoke object was added to create puffs of red smoke rising from the lava, and a sound object was placed with ambient and random sounds. Further, an animated rock that moves down the lava flow was added. The rock in the example has a parented model which emits additional smoke particles, and two sequences which are played randomly by a set of engine_scripts and messagepipe objects to give it some variation. Lava (Simple lava) ![]() Water tiles are used to create 'waving' liquids, and the lava surface here is using a watertile object with the ELM6LAVA material specified. (Water tiles can also have their size, tessellation, and amplitude / period changed.) In order to make it act like a liquid, a brush with the top texture set to *PHYSLAVA is used. A trigger_damage is also placed below the lava surface to hurt any character that falls in. Flowing Water (Water that pushes the player along, as in Capture Jasindra) ![]() The water itself is made using a spline sheet with modified subdivisions and the WILD2STREAM material applied to it. In order to create the effect of being liquid, brushes were added below the spline with the top texture set to *PHYSWATER. These brushes also have their 'Medium_velocity' key set to '3,0,0', meaning they will push the player on the x axis by a speed of 3, and on the y and z axis 0. Water (Water with and without waves) ![]() Two versions of water are shown. Standard water is simply a brush with a water material applied to the top surface. The more complex is rippling water done using a watertile object and a brush with the *PHYSWATER material below. (Note that watertiles should use a surface with the NoCull flag so that the water is displayed as double-sided, while bushes with a water texture should not.) A trigger_waterjump is also placed along the edge in both examples. When the player enters this trigger, they can press use to leap up and out of the pool. An additional effect is added by a trigger_ext set to play a sound every 3 seconds the player is within the liquid. This trigger only has the 'Player' flag checked so that AI characters won't activate it. Healing Pool (A pool that heals a character, as in Deserted Temple and The Ancestors) ![]() This water will heal a character standing in it. To create this effect there is a trigger_ext with a message to damage the $activator by -2 every 0.2 seconds (using a negative value for damage adds health to the target). For effect, an additional second trigger_ext plays a sound every 5 seconds a character stands in the pool, another trigger_ext plays a water sound every 3 seconds, and an engine_path is used to create a sparkling particle effect. Toggling Water (Disabling and enabling water, as in The Sanctuary) ![]() Water brushes can be disabled and re-enabled through the use of the model_toggle object. After setting your water brush or brushes to this class, you will then want to add values to its 'impulse' fields. In the example, a value of 'none' has been placed into the 'impulse0' field, and a value of 'bspmodel' into the 'impulse1' field (when sent an impulse, the command in the appropriate field will be activated). With this setup, when the model_toggle receives an impulse of '0' it will be disabled and vanish, while an impulse of '1' will make it reappear. A model_toggle can be used to disable or enable any brush and not just water. Changing Water Levels (Changing water levels, as in The Sanctuary) ![]() Water can be made to move using two methods, both shown in this set of examples. The first uses an engine_path with the *PHYSWATER material applied to the top to create the actual water volume, while a watertile object is parented to it using an added 'parent' key (see the Parenting & Attaching section for more information). Be sure the engine_path has the 'GamePhysics' flag checked otherwise the watertile will not parent properly. If needed, a trigger_waterjump and trigger_ext can also be parented. The second uses an engine_path with a water texture applied to the top surface and the 'GamePhysics' flag checked. In this situation, the animation on the water texture will not work when the path is stopped so a workaround has been included to solve this. The engine_path has a blank first sequence and the 'AutoStart' flag checked so that the water texture animation begins playing right away. When the impulse is sent to begin changing the water level, it first stops the path (with an impulse of '0'), and then starts the path's second sequence which is the water's actual movement. Water Leaks (Leaking water, as in The Sanctuary) ![]() This effect uses two engine_paths with three particle systems to create the water particles, and a wallmark object to add a water splash on the floor. There is also a sound object with a looping water sound specified. (Note that an engine_path can have up to three particle systems. Add a new key for 'model1' or 'model2' and place an additional particle string into it to do this.) The Sanctuary level uses a few different styles of this effect to create the various water leaks. Volumetric Fog / NH Fog (Non homogeneous fog used for the volumetric fog in the game) ![]() NH Fog is seen throughout the game such as in pits, and also for the vertical sunbeams in a couple levels. To create it, simply add a brush and optionally set the texture to *FOG, then convert it to a brush_fog object. In the object properties select the 'Structure' flag. You can also specify the color and resolution of the fog in the properties. In the example, a trigger_damage has also been included within the fog to kill any character that falls in. FogResolution controls the amount of tessellation used for the fog volume. Lower numbers result in more tessellation allowing for (at times) more detailed fog rendering. This can often be left at the default but may be lowered if artifacts are seen or increased if the fog covers a large area. The option to change the 'FogPlane' (i.e. the direction and mid-point of the fog) is also available, but can be left with the default setting for simple pit or ground fog. The first three values plot a point in the X,Y,Z format to use as a vector from 0,0,0 which will be the direction that the fog will travel. An example is '1,0,0' to have the fog travel left to right along the x axis, or '0,0,-1' to have the fog travel top to bottom on the z axis. The last three values are modifiers in the x,y,z format for the location of the plane that acts as the top of the fog (this can be considered the fog's 'sealevel'). When the viewpoint is looking in through this plane the player is outside the fog. When looking out through this plane the player is inside. Note that when the viewpoint moves far enough past this plane the entire fog bush will show, not just up to where this plane is. Any fog_brushes which share a face will be merged into one fog volume. If the brushes use different 'FogPlane' values then artifacts may be visible. Light Beams (Brush based light beams) ![]() These brush based beams were used in levels including The Deserted Temple, The Great Wall, and others. They simply use the DM01_01_14FOG material (DM01_01_14FOG is a material which is transparent and animated to give a light beam effect). The brushes have also had the 'Solid' flag unchecked and 'Air' and 'DualSided' checked to make the light beam passable and (optionally) give the material a double sided look. Note that the 'DualSided' flag can sometimes cause sorting issues if the light beam is in front of another transparent texture (e.g. a window). In this case a brush with a small amount of thickness and the light beam material applied on both sides can be used. A brush_fog with a modified 'FogPlane' can also be used to create light beams, although these are not as flexible. Sunlight Shafts (Shafts of sunlight using volumetric fog) ![]() Vertical shafts of sunlight were used in Iellon Dungeon and The Ancestors and are created with brush_fog objects. Four wedge shaped fog brushes are used with the FogPlanevalues adjusted to have the fog directed outwards from the shaft center. The exact settings needed for this effect to render properly are not currently known. Dynamics, Hooks, Rotation, & Explosions Fuses
& Explosions
(A fuse which burns down, causing a barrel to explode) ![]() Fuses can be created by plotting out a sequence using an engine_path, and then setting its 'Model' key to 'fuse'. (This will automatically generate a fuse model along the path which will ignite when the engine_path starts.) This engine_path is also given a fuse Timedsound and sets off the rest of the explosion effects from its TimedMsgs. Two emitter objects are used to spawn the actual explosions, and a wallmark object creates a darkened patch on the ground. (Note: To spawn a wallmark it needs to be sent an impulse of '1'.) Finally, as the explosions are being set off, a Destroy message is used to make the barrel vanish as if it had been blown up. Crumbling Walls & Camera Shake (Crumbling wall similar to the ones in Iellon Dungeon) ![]() The bricks that make up the collapsing wall are brushes which have been made into dynamic objects. Dynamics allow for the creation of prerecorded physics simulations, even having the ability to hold multiple sequences so different effects can be triggered depending on the impulse sent (refer to the Ogier Documentation for information on creating these). The engine_script in this example uses ShakeCamera message to shake the screen, and also triggers the engine_paths used for dust particle effects. The individual dynamic objects use Timedsounds for the impacts of the various stones. (See the Sound Tricks with Dynamics section for some tips on setting sounds for dynamics. Note that the stones in the example are also grouped as a merged solid as described in the Merged Solids section.) As the falling stone should collide with characters, the 'GamePhysics' flag has been set, while a value filled into the 'Damage' field causing them to hurt any character blocking their path. The 'Pushing' flag can also be checked if the dynamic object should push the player while colliding rather then clipping through them if blocked. Note that the engine_path used to create the physics simulation has been left behind, but as it has the 'Exclude' flag checked, it will not be compiled into the playable level. Information on additional settings that can be applied to dynamics is found in the Additional Dynamic Settings section, and information on lighting modes can be found under Lighting Modes for Dynamics & Paths. Breakable Windows (Shattering window like the ones in Divided City and Kam-Zara) ![]() The main window example is set up similarly to those found in The Divided City. The window itself is made up of dynamics which have two sequences recorded, one for falling in either direction. In front to either side of the window is a trigger_destroy which, when damaged, triggers the dynamics to fall in the proper direction (by sending an impulse value matching the needed sequence number). In order to clean up collision, the 'GamePhysics' flag on the dynamics was left unchecked (making them non solid), and instead an engine_path with the *PHYSICAL material applied has been added. This engine_path also has two sequences and will move away from whichever trigger_destroy is damaged. (This makes the window seem solid, but keeps the shards from impeding movement of the player once broken.) A simpler example of one of the windows from Kam-Zara is also included, although only set up with one sequence. Information on additional settings that can be applied to dynamics is found in the Additional Dynamic Settings section. Bombs & Arrows (Spawning items, such as a thrown bomb, or arrow) ![]() Emitter objects can be used to spawn a wide array of items or enemies, including bombs or arrows. In this example, a set of three emitters are used to spawn a bomb and two fire arrows. Using the 'Velocity' key, these items can appear to be thrown or launched in the direction the emitter points. Hierarchy (Hierarchy example based on the breakable door in Ark Moor) ![]() This is a simple example showing the idea of a hierarchy when setting up dynamics. Each board has three sections; a top and bottom portion, and a center piece connected to the crossbeam. Damaging any of the top or bottom pieces will cause just that part to break off, while hitting it along the center beam will cause the entire door to collapse. (In this example an engine_script is used to relay this message, trigger_destroys do not seem to support more than one target in their 'Target' key.) Hooks (Used to create complex machinery) ![]() Hooks link objects together with joints. These are used to create the machinery found in Sanctuary, and also for the drawbridge in Kam-Zara. Two examples are included, one with a piston similar to Sanctuary, and one displaying the three common types and their differences. There are five types of hooks all together: hook_norotate (Connect with a joint, this object will move but never rotate.) Such as the piston in the example. The connecting arm pulls it up and down, but its rotation will never change.
hook_to_target (Connect with a joint, this object will rotate to stay lined up with another point.) Such as the rope in the drawbridge example. The rope is connected by a joint to the drawbridge, but rotates so that it's always aligned with the opening above.
hook_to_line (Connect with a joint, constrain the other end to a vector.) Such as the connecting arm in the piston example. One end is connected to the rotating wheel, while the other is only able to move up and down along a defined line.
hook_to_circle (Connect with a joint, allow the other end to rotate to stay within a specified circle or sphere.) The object will rotate from the connected joint to point towards the specified origin. It is 'loose' in that the object will be able to move further from or closer to the origin within the user defined area rather than having to be be connected directly to it.
hook_projectile (Allows an object to be launched like a projectile.) The object will be pushed in the desired direction at a set speed. Note that the velocity does not seem to diminish over time, and the object will continue to move indefinitely. You may want to use dynamics or an engine_path to simulate this instead.
The 'Attach' fields should be in the format of an x,y,z value followed by the name (if required) of the object to attach to. (e.g. '-8,0,128, gatepath'.) The x,y,z coordinates of the mouse cursor can be found in the Status Bar at the bottom of Ogier. In all cases the 'Helpaxis' usually needs to be set to '1,0,0', '0,1,0', or '0,0,1' for the hook to work properly. If the hook vanishes when you run a simulation, try changing this field. Rotation & Wheels (Rotating objects and wheels) Simple rotating objects or wheels with acceleration can be created using an engine_rotate. (The 'Interval' field can be used to make an object that rotates in stages; the first number is how far to turn with '1' being 90 degrees, while the second is the delay to wait before turning again.) The first example includes one of these, but also has a connecting arm which links to a piston (a hook_to_line and hook_norotate). An engine_rotate can be stopped with an impulse of '0'. If it has the 'NeverInterrupt' flag set, it will only stop once it has returned to its original position (rather than stopping immediately). The older (and unused) func_rotateplat object is also available, although it functions differently from engine_rotate. These objects have collision by default and can be stopped by a character blocking them (an effect which can be simulated on other rotating objects using parented triggers). They don't respond to stop messages like an engine_rotate or engine_path does. Enclave's player collision behaves better when standing on a spinning func_rotateplat compared to other objects, though the character's position doesn't keep up with the platform. The Forceorigin key is used to specify an origin point, while the Hookorigin field does not seem to have an effect (objects, including hooks, do not appear to be able to attach correctly to func_rotateplat objects). The engine_wheel can also be used to create wheels which rotate automatically when an object they're attached to moves (these were used on the cannons and catapults in Enclave). In practice they can be a bit unreliable with the direction they turn, so you may want to use other methods to simulate wheels depending on the case instead. An engine_wheel can be connected to an object using the 'Attach' field to set the point where the wheel will rotate, and to specify what it will connect to (x,y,z,name). Another field, 'Attach_radius' should be set to a point on the wheels outer radius. Finally, an axis that the wheel should rotate on should also be set. ![]() Example of an engine_wheel with the 'Attach' point set in the wheel's center, and the 'Attach_radius' set as a point on the outside of the wheel. In all cases axis keys can use negative values to reverse the rotation direction (e.g. '0,0,-1'), and can also include decimals to have rotation to occur on multiple axes but at different rates (e.g. '0.5,0,1'). Rotating objects can also be created using engine_paths. In some cases this allows for better control, for example if the rotation happens at an angle. Pushable Cart (Dynamics used to create a wheeled cart simulation) ![]() To create a physics simulation for this wagon, a mockup was first made using dynamics which had axles being held to what represented the wagon bed. Once a simulation with this had been recorded, the actual wagon geometry was simply added to these dynamics using the Workspace causing them to inherit the movement. (The Workspace window can be found under the View menu in Ogier. You can move geometry into a dynamics hierarchy to add them to the dynamic.) The original wagon mockup has been left in the example, but has the 'Exclude' flag checked so that only the final wagon will be compiled into the level. Doors & Keys Doors
(Standard doors using engine_door and engine_path) ![]() There are two common ways to create swinging doors, either using an engine_door, or by using an engine_path. In either case, you will want to set the 'Attach' key to be the point where the door should rotate from. (You can see the x,y,z coordinates needed for this key in the Status Bar at the bottom of Ogier while hovering the cursor over a location.) Generally engine_doors work well for standard doors which open then close, while engine_paths are better if you need more control over the door (e.g. have it open and stay open, or have it open and close based on a lever or other contraption). One or two trigger_ext objects are placed in each example which send an impulse to the doors to open (sending an impulse of '2' to an engine_door causes it to open in the opposite direction as normal). Both types of doors can use the 'userportal' key (note that this key must be added manually for engine_paths) which allows them to be linked to a user portal for optimization purposes. When a door is closed the linked user portal will also close, and when a door opens the linked user portal will also open. (User portals can be used to stop the engine from rendering geometry behind them when closed, see the User Portals section for more information.) Another way to create a swinging door with a bit more character is to create a physics simulation using a dynamic, and optionally converting it to engine_path after (this also gives the option to further adjust the recorded animation). An example of this is the Outland Wastes gate, also included in the sample level. Note that for AI characters to try and move through closed doors, the 'Navigation' flag should also be checked. If using an engine_path as a door, the 'BlockNav' flag can also be set. Locked Doors (Locked doors that need a key) ![]() Two examples of locked doors are included, each based on a different style found in the game. The first emits a lock rattle sound when approached and prints a message on the screen "You need a key to open this door". This is done using a trigger_ext which can be re-triggered after a delay of five seconds that plays the sound using the door as a source, and sends a Speak message to the nearby narrator object. The narrator object displays the text located in a dialogue file on the screen. (In this case, dialogue 2 from the DM02 file.) Note that the trigger_ext is only set to send its messages when a player enters it by having the 'Player' flag being the only one checked. Next we have two trigger_exts placed on either side of the door to open it as normal, but both have the 'Waitspawn' flag checked. having this flag checked means these triggers will not be active until a spawn message is sent to them, and so the door will not actually open until this occurs. Another trigger_ext is placed which has the 'Player', 'Use', and 'Once' flags checked and a 'Use Object' set. This trigger will show the use icon once the player carries the item set in the 'Use Object' field, and allow them to activate it. Finally, we have the key itself. This is a pickup object with the key type set in the 'Rpgobject' field. When the player picks the item up, it sets off the 'OnPickup' message which destroys the sound / text trigger (thus disabling the rattling sound and narrator text). Now that the player has the key, when they approach the door the usable trigger will bring up the icon to use the key. Once the key is used, the 'Waitspawn' triggers are spawned and the door will now function as normal. The second door is a simpler example and is similar to the locked log book room door in Ark Amar. This door does not print text to the screen, and the rattling sound only stops once the player uses the key. A re-triggerable trigger_ext with the 'Player' flag checked plays the rattle sound, and another trigger_ext with the 'Player', 'Use', and 'Once' flags checked has the 'Use Object' set to a key. When the key is used, the sound trigger is destroyed and the door opens. Refer to the Adding Pickups section for information about adding new keys to the game. AI Scripting Leading
Character & AI Following a Path
(A character that leads the player somewhere) ![]() This shows two methods used when having an AI character lead the player. The first is using an engine_path and the 'Lead' AIImpulse which causes the AI to follow the path but stop and wait before continuing if the player gets too far away (an example of this is the halfling in Divided City). Note that 'Lead' only works if the player character is on the same team (e.g. Light or Dark side). The second uses the 'Follow Me' AIImpulse to have the AI simply follow a path when triggered. (An example is the engineer in Outland Wastes. The engineer moves to a point where a trigger_ext is then activated. Once the player enters this trigger, the engineer will follow another engine_path to the next point and the process repeats.) Both of these methods are used in the Celadia Village mission where the player must escort Marcus. Note that in both examples the engine_path has the 'GamePhysics' flag checked, AI characters will not follow paths unless this is done. (There are other options to make an AI follow a path as well. A few of these are made note of below, and most are also described in the official Ogier documentation.) Patrolling AI, Walking AI, & Dropping Items (An AI using a patrol path, and one that drops an item) ![]() This example has a goblin following an engine_path as if patrolling. In order to make the path repeat in a loop, the 'Loop' flag has been checked. The 'AutoStart' flag is also checked in this example to make the engine_path begin when the level loads. (Note that the engine_path has the 'GamePhysics' flag checked, AI characters will not follow paths unless this is done.) To make the goblin follow this path, its 'Behavior' has been set to 'Patrol', and the 'Path param' has been set to the engine_path. (Alternately, you could use an AIImpulse such as 'Follow Me' or 'Patrol' for the same effect.) To make an AI walk while not yet alerted, simply lower their 'Idle Max Speed' to '3'. To make an AI drop an item when killed like in this example, add it to the 'Dropitem' field. Note that for the 'Dropitem' field to have an effect, at least one pickup object must also exist in the level. This dummy pickup object does not need to have anything specified. Speaking, Simple Moving, NPC Bar, Protection Missions, & Trigger Filters (Making an AI talk and basic settings for protection missions, as in Celadia Village) ![]() This is a small example with the character Marcus showing how to make an AI speak, use simple movement, add a health bar to the HUD for an AI, end the mission if they die, and have a trigger filter for a specific named object. Making a character talk is done using the 'Speak' message and the value of a line contained within a dialogue file. The dialogue files for characters can be found in ..\Enclave\Sbz1\Dialogues, and are specified in the AIs 'Dialog' field (see the Dialogues & Subtitles section for more information). The 'SetNPCBar' message with a 'Target' of $player is used to add a health bar of the named object to the players HUD, in this case of the Marcus character (to add a custom name to an AI Character, refer to the Custom Targets section below). This health bar can be removed by using another 'SetNPCBar' message with a different or nonexistent 'NPC' value. To end a mission when a character is killed, set an 'OnDie' message of 'EndRound' with a 'Target' of $game, as well as a condition and 'EndMessage' if preferred. Also shown in this example is moving an NPC using a simple 'Move to Object' AIImpulse. Unlike using paths, this will simply make the NPC attempt to move to the desired location using the navgrid (this appears to be useful for small movements, but unreliable for long distances). The trigger_ext that Marcus moves into is set to activate only for him by using the 'Intersect Objects' field. Placing the name of an object into this field will check anything that enters the trigger for a match before sending its messages. Sitting AI (A sitting AI which stands up when alerted, as in Divided City or Ark Amar. Sleeping AIs are set similarly) ![]() A sitting AI character that is alerted and stands up when a player / enemy walks near, or when injured. The standing up sequence is controlled by the engine_script (engine_scripts are simplified versions of engine_paths intended just for scripting) which has four timed messages. The first targets the AI character with a 'PlayAnim' message and starts the standing up animation. One second in, a 'PlaySound' message is used to make the AI sound surprised. Lastly at 2.3 seconds (when the standing animation ends) the AI character is sent a 'Release' AIImpulse, and shortly after a 'Spot Character' AIImpulse with $player as a 'Target'. This releases the AI from its scripted state, and alerts it to the player's location. The AI character has an 'OnSpawn' message set to 'PlayAnim' targeting $this and an animation value of 'Gameplay\elm_5:10' (starts the AI in the sitting pose), an 'onEnemySpotted' & 'OnInjured' message targeting the engine_script (to begin the standing sequence if an enemy is spotted, or if hit with a projectile), and an 'OnDie' message set to destroy the engine_script (a fail safe to prevent the sound from playing after the orc has been killed). The 'OnStart: Pause' flag is also set to prevent the AI from doing anything unscripted until released. Finally, there is a trigger_ext set for players which also targets the engine_script. (This makes certain the AI runs the stand up script even if it's not alerted directly by the player. Also handy to make the range at which it should stand up more precise.) Dead AI (A dead character with a blood decal and arrows) ![]() To create a body, place an AI character and set the 'SpawnDead' flag. You will also need to specify a 'Force Anim'; in this case 'Gameplay\diverse_animation:16' was used. The blood was added using a wallmark object with one of the materials from surf_gore specified. The arrows are simply model objects. Counters (Keeping count in scripting) ![]() For this example and engine_script was used, and is set to count three goblin deaths before revealing a congratulatory message and sound. This is done using the 'WaitImpulse' message which pauses an engine_script or engine_path until the specified impulse is received. In this case, the engine_script is told to wait for two different impulses, while each goblin has an 'OnDie' 'Impulse' message set. The first goblin starts the script which then stops at the first wait impulse, the second goblin starts the script again which then stops at the next wait impulse, and the third goblin starts the script one final time and allows it to complete. Area Infos (Keeping AIs in a specific area) ![]() These act as home areas for AI characters, and are commonly used with wraiths so they don't stray too far outside the level. Simply set the 'Area Param' on the AI to the name of the areainfo. Enemies that are exploring or fleeing will also try not to stray too far from their areainfo if one is provided. Note that areainfos appear to be treated as cubic volumes, i.e. the bounding box of the areainfo rather than its actual geometry. Spawning & Pushing AIs (Spawning an AI, as well as launching them) ![]() Spawning an AI is as easy as setting the 'Waitspawn' flag, and then sending a 'Spawn' message to it. Adding a value to the 'OnSpawn:' numerical field will also push an AI forward when it spawns, perfect for ambushes (such as a goblin jumping out of foliage or from behind a wall). Three examples using these two elements are included. A goblin as described above, spawns and is pushed forward. A Scaara lunging from the water as in Sanctuary. Two engine paths are used for the particle effects; when the first is sent an impulse it triggers the second effect, uses a 'PlaySound' message, spawns the Scaara, and then uses a 'Spot Character' AIImpulse with $player as a 'Target'. A stone gnome being thrown from lava as in Outland Wastes. In this case a model object was used for the particle effects and has been parented to the AI character by adding a 'Parent' key containing the name of the gnome. (Using the 'New Key' button in the objects properties. Parenting is described more in depth in the Parenting & Attaching section, but in this case it's used to make the model object inherit movement from the target, thus making the particle system follow the gnome.) An engine_script spawns the gnome, and then uses the 'SetModelFlags' '1' message to enable the particles. Three seconds later, another 'SetModelFlags' '0' message disables the particles, and shortly after, a 'destroy' message removes the model object entirely. The gnome also has a sound specified 'OnSpawn' to complete the effect. The final example uses an emitter with 'ai_bombardier_l0' in its 'Spawn' field. Although offering less control over the AI character out of the box, this method is useful if you need a spawn to be repeated many times (such as in Naglagard). If it's required to spawn a large number of characters while still having a high level of control, you can create a template xrg file with custom characters. (Refer to the Creating Prefabs and Campaigns & Rewards sections further on for more information on file editing.) You can also push characters using trigger_accpad objects. See the Acceleration Pads section for more information. Switching Weapons (Forcing an AI to switch weapons) No example of this is shown in the sample level, but when it is desired to have an AI change weapons, the 'Switch Weapon' AIImpulse can be used. Leaving the 'Weapon Index' field blank or using a value of '0' will cause the AI to cycle to the previous weapon, while using a value of '-1' will cause the AI to cycle to the next weapon. Forcing AI Off Ledges (Different methods of forcing an AI off a high ledge or doing a precision jump) ![]() AI characters following the navgrid generally won't jump off high ledges, these examples show three different ways of forcing this behavior. The first uses an engine_path with a sequence set up in an arc to imitate a jumping path. When triggered, the engine_path sends a 'Fly Follow Me' AIImpulse to an Assassin which causes the AI to move to, and then follow the path by flying. This gives the effect that the AI is jumping off the edge and landing where the path ends. (Used in Ark Moor for the assassins jumping off the entryway ledges. This is great for precision jumps.) The second is probably not the optimal option, but demonstrates the 'Vector Move' AIImpulse. This forces the AI to move in a specified direction until disabled by other means. (In this case a trigger_ext sets it back to '0,0,0', you could also release the AI to stop the scripted movement.) The third may be one of the most common ways to do this, using an engine_path with a 'Follow Me' AIImpulse targeting the AI character. The AI will simply follow the path and walk off the ledge when doing so. You can also push characters using trigger_accpad objects. See the Acceleration Pads section for more information. Spawning Magic Users (Effects for spawning characters like wizards) ![]() This shows off a few ways magic users can be spawned in the game. One simply spawns in place, while two others have particle trails moving to their location before spawning. Also shown is a wraith following a path which would be used for the Ark Moor liches. (Note that an engine_path can have up to three particle systems. Add a new key for 'model1' or 'model2' and place an additional particle string into it to do this.) The first lich spawns in place similar to those in levels like Kam-Zara. This is done using an engine_path which has two particle systems and, after a slight delay, sends a spawn message to the waitspawned lich character. The next two examples include both a lich and wizard which have particle trails flying through the air before spawning. In both cases there's an engine_path with two particle systems and a spline path to where the magic user will spawn. After a delay, they use timed messages to activate a second engine_path (with the actual spawning particle effects), and spawn the lich / wizard similar to the first example. Note that a feature to average the time of a path is built into Ogier which can be very useful in situations like these. See the Averaging Speed / Time of Paths section for more information. The wraith simply uses an engine_path with a 'Fly Follow Me' AIImpulse to make it fly through the air. In Ark Moor, this was coupled with the above effects to make a lich spawn. Additionally the wraith is sent a 'Look at object' impulse for a second engine_path which is kept slightly ahead of the first, this can be used to prevent an issue where the wraith follows paths while tilted at a 45 degree angle. Wizard Orb & Scripted Sequence (Wizard similar to those in The Guardian, and an example scripted sequence) ![]() This scripting demo uses many of the already mentioned elements, but assembled to make a small sequence. The trigger_destroy sets off the engine_script above the orb when damaged, causing the orb to burst and the wizard's shield to drop. A few things that haven't been mentioned previously are orbs, stopping engine_paths, 'Ghost', 'Immune', and 'Teleport Follow Me'. Orbs can be created using an engine_path or model object, with the string 'sphere' typed into the 'model' field. (Similar to particle systems, there are lots of options to modify these.) To stop an engine_path or engine_script, simply send an impulse of '0' to it. (Used in this sequence to stop the scripts if the wizard dies.) The 'Ghost' AIImpulse is used to enable noclipping mode on an AI. (Used to allow the wizard to float.) The 'Immune' message enables or disables invulnerability for an AI. (Used to make the wizard unable to be injured while behind his shield.) The 'Teleport Follow Me' AIImpulse teleports an AI to the target engine_path, which it then follows. (Used in conjunction with 'Ghost' to make the wizard hover in midair.) Misc Effects Leaf
Dripper
(Used to make leaves spawn and fall to the ground) ![]() Leafdrippers act as a particle system, creating leaves which fall to the ground and then vanish. These are mainly used around trees in the Jasindra level. Sharks (Shark like the ones used in Ark Amar) ![]() Sharks in Ark Amar are engine_paths with the '/Shark' model specified. The paths are then animated to give the appearance of them swimming through the water. Flee Zones (Used to end the mission following a countdown if the player wanders too far) ![]() Fleezones are used to set boundaries to the mission area. When a player enters one, the message 'Leaving mission in 5 seconds' appears and a countdown begins. If the player does not exit the fleezone before the countdown completes, the mission ends. Ending Missions (End a mission in either failure or success and give rewards) ![]() Ending a mission is done by sending an 'EndRound' message with a 'Target' of $game. You are able to set a condition (Lose, Win, Flee, Restart), and a message that will be displayed on the mission end screen. (These messages are set in the StringTable file found in ..\Enclave\Sbz1\registry. Parenting & Attaching (Make objects inherit movement from one another) ![]() Parenting and attaching are two ways to make objects inherit movement from one another, useful for creating more complex effects, disabling and enabling triggers, or moving pickups. Multiple objects can be connected together in a chain through parenting and attaching so that each inherits the others movement. The most common of these methods is parenting, where the name of the object you wish something to follow simply goes in the 'Parent' field. Many objects do not have a parent field listed; in these cases just click the 'New Key' button in the properties and add a key called 'Parent'. Note that to parent a trigger or pickup to a path, the path must have the 'GamePhysics' flag checked. Also note parented objects may appear to lag slightly behind the object that they are parented to. Standard parenting does not work for making one engine_path inherit movement from another. For these, use the 'Attach' field (below) instead. Attaching is generally a more precise version of parenting but can be limited to specific cases. A good use for attaching is when needing one engine_path to follow another. In these cases, there is an x,y,z value of the origin followed by the name of the object to attach to. (In this example that looks like '360,-352,28,startstoppath') Note that the engine path which is set to follow another must have at least two keyframes and will only follow while a sequence is active. When activated, the path will update or jump to the current position of the path that it's attached to and then follow it. If the sequence is stopped the path will stop following the path that it's attached to. In the example, there is an engine_path which has both a model and trigger_damage parented to it, while another engine_path is attached to it. When triggered, all the objects will move together as they inherit the first engine_paths movement. A second example showing a potion appearing and then falling is also included, in this case the pickup object begins below the play area and is parented to an engine_path. When the engine_path is triggered, it moves into the play area and then begins its falling animation. Note that if a pickup should appear instantly in a level, it's best to have a larger distance between the pickup's initial and final position so that the transition appears instant. This was used in levels such as The Ancestors and Ark Moor to make pickups appear and animate (e.g. the different items in the arena in Ancestors, and the gold and potion that are dropped through the trap door in Ark Moor). Another example showing parented pickup objects being used to make gold appear when a chest is opened is also included. In this case the pickups are parented to an engine_path. When the chest is opened the gold immediately appears following the engine_path's stepped path (this is similar to the chests in the Deserted Temple level). Bushes (A rustling bush like those used in the game) ![]() The bush itself is just an object, but it is accompanied by a repeatable trigger_ext with a delay which makes rustling sounds when the player passes through. This is commonly used effect in the games levels. Hanging Skeleton & Spawner (Animated hanging skeleton that spawns an AI when shot, like in Ark Moor) ![]() This is a re-creation of the hanging skeletons in Ark Moor which spawn AI characters when damaged. The hanging skeleton is an engine_path with the '/WorldObjSkel' model which has been animated to swing back and forth. There's a trigger_destroy that sends an impulse to an engine_script when damaged, and this script completes the rest of the sequence. The skeleton AI character is spawned and the engine_path with the swinging skeleton is sent a destroy message. Two emitters are triggered which spawn 'test_dustcloud's to help cover this swap. (You'll also notice that the trigger_destroy is removed by having a 'Destroy' message sent to it. This is due to trigger_destroys absorbing any damage caused within their volume. If the trigger_destroy was left, the skeleton AI could not be injured until moving outside of that space.) Butterflies (Fly around a level, seen commonly in Divided City) ![]() The butterfly object spawns a randomly textured butterfly which will move around the level and land on world geometry. These are common to see in the Divided City level. Ladders (Climbable ladders) ![]() Ladders are made by creating a brush with the *PHYSLADDER material applied to the climbable surface. As in the example, this brush should end around 48 units below the top of the actual ladder. Note that the animation used for characters when they climb ladders may not line up as expected. To better match the climbing animation ladder steps will often vary in distance from one another slightly. Toggling Sounds & Models (Changing or muting / hiding sounds and models) ![]() Sometimes you may want to activate, deactivate, or change an ambient sound. In these cases, the 'SetSound' message can be used to modify the sound path. (Setting the 'Sound' field to blank will silence it, while placing the name of a sound will activate it.) Models can also be changed similarly by using the 'SetModel' message. (This was used in the Capture Jasindra mission to hide and unhide tree models for optimization purposes.) Rats (Animated rat like those in Iellon Dungeon) ![]() Rats are engine_paths with the '/SewerRat' model specified. The paths are then animated to give the appearance of movement. You'll notice that Timedsounds have also been added so the rat emits squeaks as it moves. Changing Characters & AI Die Trigger (Changing the players character) ![]() Characters can be changed using the 'Switch Character' message. The target will take control of the named character. In the example, this is demonstrated by switching the players character to a spawned paladin AI. A trigger_aidie is also included in this example to demonstrate how it works as well. Any AI character (not the player) that enters it will be killed if they do not leave within the number of seconds specified as the 'Activationdelay'. Lightning (Lightning strike like in Kam-Zara) ![]() The lightning is actually an engine_path with a number of splinebrushes grouped to it. (An engine_path must be created first, and the splines grouped to it through the Workspace after. The Workspace window can be found under the View menu in Ogier.) The S_DEBRISTRAIL_ZALE material should be applied to the splines. When the engine_path is triggered, this texture will begin animating. In this example, a Timedsound is played to emit a thunderclap, and after 2 seconds a 'Destroy' message is used to remove the engine_path (if the path is not removed or stopped, the texture will continue animating). A dynamic light has also been added in the example using a dynamic2 object which is parented to an engine_path. While this was not used in Kam-Zara, it offers an option to have the environment briefly light up during the lightning effect. (See the Dynamic Lights section for more information.) With this documentation, a surface file named Surf_LightningAlign.xtx has been included. Placing this file in ..\Enclave\Sbz1\surfaces will give you an additional material to help align the lightning texture to splinebrushes. Moving Ropes (A trick to make a stationary rope appear to move, like in Sanctuary) ![]() This effect works in a similar (but simpler) way as the above lightning example. The rope is made into an engine_path and textured using the DM01_07_35B material (which has a scrolling animation). When the engine_path is triggered, the rope material will begin to move. When the engine_path is stopped, the rope material will stop moving as well. Teleporters (Teleporter and effects) ![]() Teleporters can be created using a few methods, including using a trigger_teleport as shown in this example. (This is the most common used in the game, and comes with a particle and sound effect built-in.) At its core, this teleporter is simply a trigger_teleport which points a named info_teleport_destination object in its 'Target' field. To create a dust particle effect when a character moves through the teleporter, a trigger_ext has also been placed which covers the same area as the trigger_teleport. This trigger sends a message to an engine_script, which uses the 'SetModelFlags' message to enable the dust particle system of the engine_path, and then disable it after one second has passed. An additional engine_path and sound object are also used to add some more ambient effects to the example. Note that if the info_teleport_destination is placed too close to the trigger_teleport, they player may sometimes retain their orientation when passing through the teleporter rather than facing the direction of the info_teleport_destination. To toggle a teleporter on or off, one option is to parent the triggers to an engine_path (see the Parenting & Attaching section) to move them below ground when it's not to be used. This trick was used in Kam-Zara and Ark Moor. Telefragging occurs with a trigger_teleport / info_teleport_destination if a character teleports to a position intersecting with another character. Cutscenes & Player Control (Camera work and controlling the player) ![]() This example covers both creating a cutscene, and controlling the player character during cutscenes. Engine_paths act as cameras, with the viewpoint facing forward, while cuts between paths can be done using the 'Jump' field (this is entered as time in seconds followed by the target engine_path name. e.g. '5,cutscenepath2'). Cutscenes are started from the first path / camera in the sequence using the 'BeginCutscene' message targeting $player and ended with a 'FadeScreen' message targeting $game with a 'Duration(ms)' of '500' followed by an 'EndCutscene' message targeting $player 0.5 seconds later. When controlling the player as an AI (or to animate and move them), you'll want to use the 'AI Control' message targeting $player. (A 'Param' of '1' switches the player character to AI control, while a 'Param' of '0' returns control to the player. When under AI control, a player can be scripted like any other character and even use AI pathfinding.) In the example, the trigger sends an impulse to the first engine_path right above. This engine_path acts as the first camera, and starts the cutscene by sending a 'BeginCutscene' message. As this scene involves animating the player character, the next message is 'AI Control' with a 'Param' of '1' which disables player control. (Notice that this message has a slight delay following the beginning of the cutscene. This avoids 'jerkiness' when the control is switched from the player to AI.) A 'Teleport Object' message is then used to move the player character to a named object, in this case an engine_script being used as a placeholder, and then a 'PlayAnim' message sets the player character to be laying on the ground. At the five second point, the 'Jump' field takes effect and switches the camera to a second engine_path. (Having being set with '5,cutscenepath2'. This automatically starts the second path as well.) You'll notice that there are still two timed messages left on this first path, one that plays the standing up animation at the same time as the camera change, and another that returns control to the player character just before the end of the cutscene. A little while into the second engine_paths sequence, the cutscene is ended. This is done using a 'FadeScreen' message to fade the screen to black, and then an 'EndCutscene' message shortly after. Note: When the player skips a cutscene, the game effectively fast-forwards to the point where the 'EndCutscene' message is called. This means that even if the scene is skipped, everything that was scripted to have taken place will still have completed. Also, if you would like to override the camera rotating around the players character at the beginning of a level with a custom scene, just start a cutscene immediately using either a path with the 'AutoStart' flag, or a trigger located in the same position as the player start. Note: Ambient sounds that the player is within the radius of may stop when a cutscene is skipped. This can be solved by creating a duplicate set of the problematic sounds and setting them to 'Waitspawn'. At the same time as the 'EndCutscene' message is called, a 'Destroy' message can be sent to the original ambient sounds, and a 'Spawn' message sent to the duplicates. This effectively stops the original sound and re-initializes it. Additional tips for setting up cutscenes include selecting an engine_path and then using Paste camera position to match its orientation to the camera's current position in the 3D view (useful for setting a camera's position and angle), and selecting an engine_path and using Preview camera to preview the camera's view and movement from that path. For information on cutscene levels, e.g. those played before or after missions, refer to the Campaign Challenge Settings section. Using Prefabs (Using the included prefabs and creating your own) ![]() Included with the editor are a number of prefabs of complex objects from the game (such as cannons or Mordessa's portal), and also support for creating your own. In many cases using the prefab is as simple as placing the related prefab object in the level. Prefab lighting is based on how the prefab file is set up, some use baked lightmaps and are unaffected by the level's lighting while others use Gouraud shading. Creating your own prefabs can be very useful when you wish to create instances of an object that can be reused. Refer to the Creating Prefabs section for information on creating your own prefabs. There is a bug in Ogier which causes a crash when running a world or physics simulation with some of Enclaves built in prefabs (specifically those with rendered lighting affecting particular types of surfaces). An example of a workaround for this is included in the Sandbox level - in the example, there is both a prefab_cannon and a model object, the prefab_cannon will spawn a usable cannon once the level is compiled, while the model is simply an empty visual placeholder for use within the editor. In order to prevent the crash with this particular prefab, the prefab_cannon has been hidden by flagging the checkbox next to it in the Workspace, and then grouped with the model object. ![]() (The prefab_cannon has been hidden and a model is used as a reference object in the editor.) External Geometry / Shadow Casting / Collision (Using external XW files to display pre-lit geometry or add additional shadow casting and collision) Anything with a 'Model' field is also able to use external XW files. This can be used to display external geometry with baked lighting (the lighting in the external XW will remain and will not affect or be affected by the level), or to add additional shadow casting or collision geometry. Two additional keys also exist for the latter, the 'Light_shadowmodel' and 'Physmodel' keys. In all of these cases the value should be the name of a XW file local to the ..\Enclave\Sbz1\Worlds directory (e.g. 'WORLD\LIGHTS\S_Candle01.XW'). An example of these fields in-use are the light and tree models in the game; the shadow casting and collision use external XW files which have been linked to these objects in the Templates.xrg file (see the Creating Templates section for more information). Custom Targets & Cannon / Ballista Targets (Custom target information shown on the bottom of the screen, and aiming targets for cannons or ballistas) ![]() This example shows a custom NPC Bar (a health bar displayed on screen with custom text), and target for use with objects such as cannons which displays a targeting circle around it. A trigger_ext has been placed on the crate which acts as a damage target for a cannon. This is done by setting the 'Projectile' and 'Destroyable' flags, and also the 'Explosive' flag for damage type. The 'Hitpoints' have also been set a bit higher than their default. A trigger with these settings will automatically display the aiming circle when the player is using a cannon or ballista. The trigger_ext is also set to display a custom health bar on the screen by adding '§Ltarget_l_msb' into the 'Autotargetname' field. This is an entry found in the StringTable text file located in ..\Enclave\Sbz1\registry. To display this on screen, another trigger_ext uses the 'SetNPCBar' message with the 'Target' of $player and the 'NPC' field pointing to the name of the destroyable trigger. Siege Objects (Player controlled objects or weapons) ![]() Siege objects are player controlled objects which are used to create the cannons, ballistas, and catapults found in Enclave. A number of these are available as prefabs which can be inserted into your own levels, but entirely new siege objects can also be created. The required trigger message, keys, and flags for these have been left out of the default Ogier definition file, but can added either manually, or by placing the updated nodetype.txt file included with this documentation into the ...\Enclave\Sbz1\Dev directory. Use a siege object for the main portion of the controllable item (such as a cannon barrel or body of a ballista), and set the 'Attach' field to the point where it should pivot when being aimed by the player. This object acts like a 'base' while any additional components (such as engine_paths, hooks, or emitters) can be attached or parented to the main siege object. (Note that you may want to enable the 'Unreliable' flag for these objects in order to avoid possible issues.) Siege objects work on the principal that they are first 'charged' and then 'released' before triggering / firing. This is portrayed in three different ways in Enclave; cannons where a delay is present while they charge before firing, ballistas which begin charged and then release when the player presses the fire button, and catapults which allow the player to decide how long to charge and when to release. Additional objects which should be triggered to animate along with the charge and release states (engine_paths, hooks, etc) are added to the siege objects 'Engines' field (separated using commas if there is more than one). When paired this way, the objects will receive an impulse and animate forward while the siege object is being charged, and animate in reverse back to their original position when being released. As an example of this, the limbs of a ballista will bend back when the siege object is charged, and then return to their original position when released. Place a hook object to use as a camera, this can be attached to the siege object if you wish for the camera view to move with it. The name of this object should be entered into the siege objects 'Camera' field. Place an emitter if desired, this can be parented to the siege object so that it moves with it. The name can be entered into the siege objects 'Emitter' field, causing it to trigger when the siege object fires (e.g. for spawning a cannon ball or arrow). To trigger player control of the siege object, a Siege Control message (0x100f) must be sent to it. From here, you'll want to further specify how the siege object should function by using the additional keys and flags which are available. Below is a description of what each of these is used for.
The siege object may also trigger other messages at different points of the objects use. Commonly, you may want to set a Msg_mount and Msg_unmount to send a SetFade message to the $player in order to hide them from view while the object is in use (setting the fade to '0' and '255' respectively). Cannons (Additional information on cannons and the related effects) Cannons come in two varieties in Enclave, those that the player is able to control (siege objects, these are included with the game as prefabs), and those that are non-interactive (i.e. the ones built directly into the Divided City level). Most levels where cannons appear also use additional effects for gameplay sequences (e.g. the gate in Iellon Outpost or cannon fire in Divided City and Ark Amar). Player controllable cannons which are available as prefabs include the following. These prefabs can be tweaked (see the Changing Prefab Keys & Flags section), or fully custom setups may also be created. The Using Prefabs, Custom Targets & Cannon / Ballista Targets, and Siege Objects sections include additional information relating to these types of cannons.
Effects used generally consist of particle effects, fuses, cannon projectiles, explosions, and dynamics.
A note on having a cannon return to its original position after firing as per the player controllable versions in the game; the 'Point forward' button can be used to align an engine_path's rotation to its direction of travel, and the engine_path can be scaled in order to align it back to the grid. These two options can be used to bring the cannon back to its original position after having fired with a physics simulation. An example of a non-player controlled cannon using these types of effects is included in the Sandbox level. Note that this sample shows only one possible setup, this may vary depending on the desired effect. Acceleration Pads (Push a player or character in a direction) ![]() The trigger_accpad object can be used to push or launch a player or AI character in a given direction. These are mainly left over from early versions of the game but may still be useful. They were used in Naglagard to force the enemy characters forward from their spawn areas, although similar results can also be accomplished using scripting. This is done by adding a 'Velocity' key to the trigger_accpad and specifying a direction in the format of x,y,z (e.g. '16,0,32' will bounce the player forward on the x axis and upwards). Use negative values for the opposite direction. Skies, Sunlight, & Distance Fog (Adding a sky, creating sunlight or ambient light, and using distance fog) ![]() Adding a sky, sunlight, and distance fog to a level is done using two objects, a sky_indoor and a light_sky. Note that a map file (Atmospheres.xmp) has been included with this documentation which contains preset skies, NH fog, distance fog, and sunlight taken from each level in the game. The name of any skies from ..\Enclave\Sbz1\skies can be entered into the 'Sky name' field found in the sky_indoors properties (alternately, check the list of skies included in this documentation). Any surface textured with the *SKY material will display the chosen sky and emit sunlight (if any). Distance fog in the level can also be controlled here, including the distance fog for when the player is underwater (note that if you experience issues with the fog culling geometry, try placing a positive number in the 'XR_FogCullOffset' field to offset the default culling distance). The light_sky object is used to create sunlight in a level, make it easy to quickly light outdoor spaces. The below image can be used as reference for the sunlight's direction. In the 'Direction' field there are three numbers; the first two correspond to the x / y position within the sky, while the third number acts as the sun's angle. ![]() Workspace Layers (Adding a 'group' to the Workspace for more a organized editor workflow) ![]() Placing a layer object in your level will add a new layer group to the Workspace. (The Workspace window can be found under the View menu in Ogier.) Sections of your level can be placed into these layers, making it easier to locate specific geometry / objects, or simple to hide / show entire areas of a map all at once. More information on the Workspace can be found in the official documentation. Note that if you don't see anything listed when you open the Workspace window, try selecting one of the View type radio buttons near the bottom (e.g. Tree View). Submaps (Specifying additional XMP files to be compiled together as one level.) ![]() The Submap field of the worldspawnobject allows listing additional XMP files which will be compiled into the final level. This can be useful for splitting up large levels into multiple files for easier editing and to limit the areas compiled while testing a level. And example of this is how the citadel of Ark Moor is one map, while the surrounding terrain is a submap. Submaps can also be useful as 'skyboxes', or geometry that will be rendered outside of the playable area behind the sky surfaces (again, similar to Ark Moor), or for collaboration such as allowing different artists to work on different areas of a level. Multiple XMP files can be specified separated using semicolons, e.g. 'SubMap1.xmp;SubMap2.xmp'. Once compiled all maps are treated as part of the same level, and scripting (e.g. triggers, messages) work across maps and their submaps. To access this property, select worldspawn from the top of the Workspace window. Submap visiblility can be toggled in Ogier from View > Show submaps. ![]() (In the image above the grey box is the primary map, while the orange and blue geometry are additional XMP files that are included as submaps during compile.) Particle Control (Turning particle systems on and off) ![]() As listed in examples above, the 'SetModelFlags' message can be used to enable or disable a particle system. A running particle system can be stopped with a 'Flags' of '0', and started with a 'Flags' of '1'. Intermission Cameras (Camera used when at the character select screen) ![]() The info_intermission object is a camera whose viewpoint is displayed when loading a level using the 'map' console command. This camera can be parented to an engine_path using the 'parent' field in order to animate it. Note that the info_intermission is only able to inherent the movement of the first path it is parented to (an exception is if it is parented to another object which is then itself parented to the path - this however may result in jerky movement). Orbs (Orb models used for magical shields) ![]() Orbs can be created using an engine_path or model object, with the string 'sphere' typed into the 'Model' field. (Similar to particle systems, there are lots of options to modify these.) These are used for the magic users' shields, breakable orbs in levels such as The Guardian, and the shields that must be destroyed in the Vatar level. Gold & Special Awards (Gold and special award items such as maps) ![]() The gold is simply a pickup_coin object, while the reward map is made using a pickup object along with an engine_script and narrator. The reward map is added by placing a pickup object with its 'Rpgobject' set to 'mapscroll'. When picked up, it sends an impulse to the engine_script above via its 'OnPickup' message. The engine_script then uses a 'Speak' message to have the narrator print text on the screen from a dialogue file, a 'PlaySound' message to emit the pickup sound, and a 'SpecialAward' message with a target of $game to activate award '0'. (Once activated, the award(s) specified in the Campaign.xrg will be given upon completion of the mission.) Refer to the Campaigns & Rewards section for information on how to link this to unlocking a special reward during a campaign, and also information about increasing a campaign's maximum gold if adding gold to a campaign level. Sounds (Ambient and random sounds) ![]() In a sound object, the sound fields are for single or looping sounds, while the RS (random sound) fields are for randomized sounds. If there should be a delay before the sound plays, place the number before the sound name, e.g. '1.3, door_mt03mv1' Sound objects can be used to place ambient or random sounds in a level. Placing an ambient sound is as simple as filling in the 'Sound0' and / or 'Sound1' fields. If you wish to have a sound play at random intervals, you can instead use the 'RS0 Sound' through 'RS2 Sound' fields. Adding min and max times for each will act as a range of when the sounds should be played. (E.g. A min time of '2' and max time of '5' means the random sound will be played every two to five seconds. Ambient sounds can be toggled off and on using the 'SetSound' message. Refer to the Toggling Sounds & Models section. Also see the Sound Browser section for more information on sound names. Fire (Flames to use with torches, braziers, etc.) ![]() Fire can also be placed in a level directly by using the cm_fire object. This object includes a number of settings that can be used to adjust the fire's dispersion, size, and color. If the fire needs to be moved, the cm_fire object can also be parented by adding a 'Parent' key. To give an effect of a fire appearing or disappearing (such as with the wagon at the beginning of Divided City where fire appears and then grows in height), the fire can be parented to an engine_path.
Although called cm_fire in Ogier, these objects are actually ext_model classes and use the proper key names (in brackets above) for their values outside of the editor. These proper names are what are seen when viewing a saved or compiled level, and can be referenced to find fire values used in the official levels. The proper names are also used when defining fire in a template file such as Templates.xrg (e.g. as part of a template for a light source such as a torch). Note that the ANIM0 and ANIM1 properties are unique in that they store both of their related integers as a single value. To do this, the first value is multiplied by 256 and then added to the second value. These can be restored to their original values by dividing the ANIM value by 256 and using the whole portion of the quotient as the first property and the remainder as the second property (e.g. an ANIM1 entry with a value of '2064' can be broken down as a Thick property of '8' (the whole of the result) and a Height property of '16' (the remainder). If adding fire in a template file such as Templates.xrg, the combined value can alternatively be specified in hexadecimal format (e.g. '2064' as '0x810'). Smoke (CM_Smoke) (Preset smoke emitter used in limited cases) ![]() The cm_smokeobject is a preset smoke effect that is used in certain instances such as for lava and chimneys in Outland Wastes and Kam-Zara. While this object can be used in some situations, in many cases it may be recommended to instead use a particle system for more versatility (plus the added benefit of it being shown in Ogier's preview modes). This object includes a number of settings that can be used to adjust the smoke’s size, speed, color, and etc. Due to the way some of the settings act and / or interact with one another, it can be best to test an initial set of values in-game and then adjust accordingly. From their initial position, particles increase in scale to ~300% of their initial size, rotate ~25 degrees counter clockwise, and fade to an alpha of 0 while ascending. If the smoke needs to be moved, the cm_smoke object can be parented by adding a 'Parent' key.
Similar to cm_fire, cm_smoke objects are actually ext_model classes and use proper key names (in brackets) for the above values outside of the editor. Also similar to cm_fire, any value with two properties is stored as a single value, with ANIM0 and ANIM1 being similar to those described in the Fire section, while COLORS1 and COLORS2 are again similar but with the first value being multiplied by 65536 instead of 256. Player Starts (Player starts and challenge mission spawns) ![]() Every level needs a start point for the player, and this is placed using an info_player_start object. If more than one info_player_start is placed, then one will be selected at random on level load to spawn the player at. There are also info_start_dark and info_start_light objects which are used as spawning locations for enemies in challenge levels (see the Challenge Map Spawns section for more information). Server Flags /
Spawn Flags
(Setting what objects appear in which game modes, e.g. Easy, Medium, and Hard) ![]() Server flags are used to set which game mode(s) an object will appear in, for example if it will be in Easy, Medium, or Hard difficulty. An example in Enclave are the checkpoints which only appear on Easy and Medium difficulties, but this can also be used to include enemies or gameplay challenges in one difficulty but not the others. Only the Main 1 and Main 2 flags have been observed in Enclave. The others may be left unused form earlier stages of development (these may have been for challenge or multiplayer game modes). The following flags can be set:
If an object doesn't have a space for server flags, you can add a new key for 'serverflags' with a value for the corresponding flags, e.g. 's2' or 's0+s2'. Another option is to use something such as an engine_script and have it only appear and trigger in certain game modes, spawning or destroying the desired objects. Checkpoints
(Player checkpoints which appear in Enclave's Easy and Medium difficulties) ![]() Checkpoints are created using a trigger_checkpoint which is linked to any related checkpoint effects (paths, particles, cameras, etc.). Each time a player enables a checkpoint, earlier checkpoints will be disabled (meaning the player will only ever respawn at the last checkpoint activated). When respawing, the player will spawn at the center of the trigger_checkpoint. If something is blocking the spawn area (e.g. an AI character or another object), then the character will not respawn and the mission will instead end in failure (a small brush with the *AI_OFFLIMITS surface applied can prevent enemies from standing in the spawn location). A trigger_checkpoint can also be activated without the player touching it by sending it an impulse of '1'. A number of options are available with a trigger_checkpoint:
Enclave uses two styles of checkpoint. The Sandbox level contains examples of both types (albeit with some scripting changes to streamline them). Regular Checkpoints
- Regular checkpoints act as optional
checkpoints where a
player may choose to activate them by stepping onto the
platform. These are available in Enclave as a prefab
(prefab_checkpoint).
Proximity Checkpoints - Proximity checkpoints act as forced checkpoints which activate when a player is nearby and include a wall alcove and optional activation cutscene. These are often placed before challenging areas, mainly in the Light campaign. This style of checkpoint was built directly into Enclave's levels rather than being included as a prefab due to having lightmaps, more variable positioning, activation trigger areas, and activation cutscenes. Note that if an activation cutscene is included with this style of checkpoint and any other checkpoint can be accessed at the same time, the other checkpoints should include triggers to correctly reset the activation cutscene (this is shown in the sample level). Examples of this situation are the Light side levels including Celadia Village or Sanctuary, while Divided City and Ark Moor are examples of the opposite, where no additional setup is needed as only one checkpoint is only accessible at a given time. Both types of checkpoints only appear on Easy and Medium difficulties in Enclave, to replicate this, uncheck the 'Main 2' flag on any objects related to the checkpoint (see the Server Flags / Spawn Flags section for more information). Note that if a player is killed during a cutscene while a checkpoint is activated (e.g. an enemy landing a final blow at the same time a cutscene is triggered, or being killed by an environmental hazard), there may be game or visual glitches. This is due to checkpoints ending any currently playing cutscene but not skipping them, resulting in any of the canceled cutscene's scripting still being active. It's worth considering this when working with checkpoints and including additional scripting logic to resolve the issue if needed. Optimization Tools Optimization
Introduction
(Optimizing a level to reduce the geometry being rendered and improve performance) A few different tools are available for optimizing rendering of a level, the most important elements being structure and user portals which should always be utilized. The console commands 'xr_drawmode 1' and 'xr_drawmode 0' can be used enable and disable wireframe view in-game which is useful to see what the engine is drawing at any given time. Also consider Spline Tessellation, simple / complex surfaces (see Surfaces & The Surface Editor), and hiding models (see Toggling Sounds & Models) as additional tools for optimization, although these do not affect modern systems as much. Structure (Structure brushes improve performance by helping the engine know what to render and when) ![]() Structure brushes are an important element of optimization and should be utilized for every level. The image above demonstrates why this is; the left shows a level with no structure brushes (all geometry and objects in the level are being rendered), and the right shows the same with structure brushes (only geometry and objects visible to the player are rendered). While this topic can be fairly in-depth, at its most basic it can be said that if a polygon is behind structure it generally won't be rendered. In more technical terms, a level is split up into nodes and leaves based on the placement of structure brushes and user portals. These leaves are used by the engine to determine what can be seen and rendered from any other leaf. The command 'wenable 1' can be used to show the boundaries of the leaf that the player is currently in (a black line will be seen along the leaf's edges). Structure should be built as primitively as possible with as few brushes as possible to avoid creating an excess of leaves. Where possible keep structure brushes following the grid lines and avoiding placing them at angles unless you understand how this will affect the level. Although the official documentation states that a level will need to be encased in structure brushes to compile, this is not the case (however it is recommended). At least one structure brush must be present in a level for it to load in-game. Pressing Crtl + R in Ogier toggles between showing only the structure brushes in the map and returning to the normal view. For a greater understanding of the effect of structure brushes and leaves, consider reading information on how other BSP based engines such as those used for the Quake or Half-Life games calculate visibility. Examples of how to use structure brushes can also be seen by looking at the sample levels included with the different GDKs (Enclave, KotT, and Riddick). To create a structure brush all that's needed is to set the 'Structure' flag in its properties. Commonly, the *NOOVERLAP material is applied on all sides (although this is not a requirement). ![]() (A structure brush with the 'Structure' flag set and *NOOVERLAP material applied.) ![]() (Pictured is an example of how a structure brush can be used to block visibility. In the left image, no structure brush is used, and it can be seen that the engine is rendering excess geometry and objects behind the wall. In the right image, a structure brush has been added inside the wall, blocking the visibility and hiding the excess geometry and objects.) Structure brushes can also occupy the same space as the level geometry. ![]() (In the above image the structure brush occupies the same space as the visible geometry. In this case you may wish to group and hide your structure brushes to avoid z-fighting and difficulty selecting the bush that makes up the wall in the editor.) Brushes with a Sky texture applied are special in that they can be used as structure brushes while still remaining visible in-game. ![]() (In the above image the brushes that make up the sky may be used as structure brushes.) Structure brushes with the *AIR material applied to all surfaces can be used to hint at areas that might not always be visible to the player by splitting them into their own leaves. In these cases, the structure brush can be placed surrounding the area or geometry. This is similar in concept to how 'hint brushes' are used in other CSG engines. ![]() (Pictured is a situation where an *AIR structure brush can be used to further optimize an area that should be hidden when out of view, in this case the area behind a low wall and gate. The addition of this brush splits the area behind the gate into its own leaf allowing the engine to better select when to render the (often out of view) geometry. Also note that a user portal was also placed in the position where the gate would be, ensuring that visibility is blocked when the gate is closed.) User Portals (Optimize a level by controlling what's rendered and when) ![]() An optimization tool to help control exactly when certain areas are rendered. These are most often placed in doorways between areas and can be used to force an area to no longer be rendered when unneeded. To create a user portal, texture one surface of a brush with the *USERPORTAL material, then convert the brush into a func_userportal.
User portals can also be linked to engine_doors and engine_paths using the 'Userportal' key (for engine_paths, the 'Userportal' key needs to be added using the 'New key' button). When one of these types of doors opens, the linked user portal will also open and, when closed, the linked user portal will also close. ![]() (An example of a door with a linked user portal. The portal is closed while the door is shut stopping the engine from rendering the geometry behind.) ![]() (An example of a window with a user portal which closes at a set distance. When the view is far enough away the portal closes and a 'fake' window appears to hide the portal.) Closed user portals display either as the level's sky, or as the void (e.g. either black or the color of a level's depth fog). If they're not already hidden from view while in their closed state, you may choose to use another object to cover the portal. Level of Detail (Objects which appear or vanish when at a set distance from the player) ![]() The func_lod object is used to make specific geometry be rendered only at a certain distance from the player. Simply set the 'MinDistance' and 'MaxDistance' fields for the range where the geometry should visible. Multiple func_lod objects can layered together to create varying detail levels for geometry depending on distance. This can be useful if there are finer geometry details which should only be rendered when the player is a certain distance from them. Another use for these objects is to hide user portals with lower detail geometry, the window example in the User Portals section uses a func_lod object for this. Splines Splines
Introduction
(Curved surfaces) ![]() Splines are created by holding down shift and pressing the number keys, and can be used to create a variety of smooth curved surfaces. Below are a few tips to keep in mind when working with these:
Spline
Tessellation
(Tessellation / subdivisions of splines.) ![]() By default, splines tessellate based on the Curved Surfaces LOD setting in the game's Graphics options (xr_splinetesslevel), and the size of the spline. This can be overridden with a specific number of subdivisions (i.e. making the spline always use a specific detail level) by selecting the relating edge point(s) and then using the + / - numpad keys. Note that tessellation can be set for each part of a spline separately. For example, one part of a spline may have subdivisions set manually, while another part can still retain dynamic tessellation. ![]() (Example showing a spline at different xr_splinetesslevel settings, with a default spline in the top row and one with a custom number of subdivisions set in the bottom row. Note how the tessellation changes on the default spline but always remains the same on the one that was manually set.) Due to the way dynamic tessellation works, splines in Enclave are often not flush with other geometry and use wedges to fill in the gap between the spline and surrounding brushes (a good example of this is with archways). If splines are desired to be truly flush with surrounding geometry, refer to the Aligning Splines section. ![]() (Example showing how a spline based archway might use wedge shaped brushes to connect it with surrounding geometry. This allows it to take advantage of dynamic tessellation while avoiding visible gaps between the spline and wall. The right of the image shows options for how the spline might be made to protrude, either with a visible lip / trim piece, or by being angled to meet the wall. This type of setup is common practice in Enclave's levels.) Aligning
Splines
(Aligning splines with one another.) ![]() Sometimes splines need to be aligned with one another, for example to have an arch which is truly flush with a wall, or having curved trim which is flush with the surfaces surrounding it. In these cases the Edge Tool can be used to bring two (or more) of the edge points together, thus aligning the splines. Note that if splines are aligned with one another in this way it's recommended to not rely on dynamic tessellation and instead set their subdivisions manually using the + / - on the keypad (if left to use dynamic tessellation the splines may not line up correctly in-game). Below are a few examples with the original shapes and edge points to be moved selected (in yellow) on the left, and the same shapes after moving the points together on the right. ![]() (An assortment of examples where splines have been lined up with one another. These might be used to create an archway that is fully flush with the wall, or trim details like those in Iellon Dungeon.) Spline Texture Mapping (Texture mapping types available for splines) ![]() Splines have three texture mapping types allowing textures to be mapped flat across a spline, follow the curve of the spline, or have only a select portion of the texture mapped. See the Texture Mapping Types section for more information on the different texture mapping types used for splines. Light & Shadow Dark
Zones
(Zone where player equipment such as staffs give off light, seen in Mansion of Dreams) ![]() The darkzone is a volume that causes dynamic lights attached to player equipment to glow when inside. This was used during the Mansion of Dreams sewer section in the game to allow for staffs that the player has equipped to emit a glow. (See the Dynamic Lights section for more information on lights that are used in these zones.) Statics & Smoothing (Objects that can help to create lighting effects or for minor optimization) ![]() Turning geometry into a static object can be useful in a few situations, including for changing the lighting type for the geometry, disable it's shadow or allow light to cast from within the geometry, having geometry which appears, disappears, or is parented, or stopping brushwork from cutting into surrounding geometry.
Lanterns like those that cast light in Ark Amar can be created using statics with shadows disabled. Disabling shadows allows a light object to be placed inside the geometry, and helps create detailed shadow effects such as those on lanterns. This is demonstrated in a couple of included examples. Also note that additional brushes with the *LIGHTBLOCK material applied can be added to create even more interesting shadows. Flares (Flares for light sources) ![]() Many light sources in Enclave use a flare effect, these are normally only displayed when running the game in OpenGL with XR_FLARES enabled. Flares are added using the light_flare object. A number of keys and flags are available for flares.
While flares can be parented to paths, their position doesn't update smoothly causing them to 'jerk' along. Parenting was used in a couple levels in Enclave to have flares follow along with a moving lantern. Dynamic Lights (Dynamic light effects) ![]() Dynamic light is used for effects such as staves giving off light in darkzones, fuses, and bombs. These light effects can also be placed directly in a level. Two types of dynamic light effects are available:
While
not as detailed as
lightmapped lighting, this type of dynamic light can be useful for
certain effects.
![]() (An example of a parented dynamic2 object being used to add dynamic light to a lightning effect.)
DynLight:LO=0
0 20,C0=0xFF80C0F0,C1=0xFFF0F000,CFS=1,R0=200,R1=300,RFS=1
A few properties can be defined in a dynamic light string. This type of light will transition between the given colors and ranges in a nonlinear way, i.e. shifting from one value to another with a variable / pulsing appearance. If no color or range transition is desired, set both values to be the same.
Light Preview Mode (Preview a level's lighting in Ogier) ![]() Selecting Preview lighting from Ogier's View menu will render lights and give an idea of how a level will look when compiled. Choosing Preview lighting while nothing is selected will render lights for the entire level, while doing so with a selection will only render lights for those objects (rendering lights for only a selected area is much faster than rendering a preview for the entire level). Light previews are rendered to LIGHT.XSC in the ..\Enclave\Sbz1\Worlds directory and do not affect the compiled XW file. Lighting Modes for Dynamics & Paths (Adjusting lighting styles on dynamic objects and engine_paths) ![]() Sometimes engine_paths and dynamics work best with their lighting mode adjusted in order to improve their visuals in-game. The three lighting modes which can be set (and also the 'Light minlevel' property) are described below. These modes can also be changed on static objects. When choosing a lighting mode consider what the object's initial lightmaps will look like, how the object will move in the environment, if it might require 'dynamic' light, and how the visual transition will look if using 'Auto'.
Works
well
for objects that should match
neighboring level geometry
or have more detailed lighting to begin with, but which also require
the lighting to change as they move. This is the default mode and is
useful for objects such as breakable stone where interior
surfaces
which would not normally receive light with lightmaps might become
visible later in the sequence.
This mode can cause an object's lighting to have an abrupt visual change when it switches between the more detailed lightmap style and the Gouraud style. In some situations 'Light minlevel' can be used to lessen the issue but this is generally unavoidable. Because of this it can be recommended to plan ahead and adjust the sequence or area lighting accordingly to limit or avoid visual issues as much as possible.
Good
for objects
that should match neighboring level geometry
or have more detailed lighting, and which do not need any further
visual changes to their
lighting as they move (surfaces obscured by shadow or highlighted by
light in the object's initial position will stay as such).
This mode is good for objects such as common doors.
Works
for objects that do
not need to match neighboring
geometry or have detailed lighting. This mode works well for objects
where the player may see initially unlit surfaces,
where there are lightmaps that would be visually jarring between the
object's initial and final positions, or where the object should appear
to be further smoothed (in addition to any smoothing applied by the
surface's smoothing groups / angle).
Note that the sample is done in relation to the level's Lightgrid from the object's origin (or attach point). The Lightgrid resolution will affect the result of the sample.
Can be
used to apply an addtional light value to an object which will remain
in lightmap mode but
where it is otherwise desired to be brighter than the lightmap would
normally be.
Can sometimes be used to help mask the visual change between between lighting modes by applying additional brightness and color to bring the lightmapped appearance of an object closer to that of the Gouraud appearance. This is generally only helpful in cases where the sampled light used for Gouraud mode is brighter than the lightmap. Simulating
Toggling Lights
(Simulating a light that toggles on or off) ![]() While later versions of the engine included the ability to have lights toggle between being enabled and disabled, this feature was not functional in earlier builds used for Enclave or KotT. Though not entirely straightforward, it is possible to simulate this effect by turning the geometry of the area where the light needs to toggle into an object, and then duplicating it to another part of the map (e.g. just below, not visible to the player) where it can be lit with alternative lights. The idea is to have different lighting rendered on each version of the geometry, and then swap the geometry instantaneously. While there are different ways to do this, one option is to use model_toggle objects, moving the second alternating version into the same location as the first when the level loads by parenting it to a stepped engine_path. Scripting can be set up to toggle between the model_toggle objects when the light needs to be changed. It can also be beneficial to use dynamic2 objects to simulate character lighting changes and (if applicable and by adjusting timing) a light flicker. These dynamic lights can be parented to stepped engine_pathsso that they may be moved into and out of the scene when the light is changed. An example of this type of setup is included in the Sandbox level; in this example the timing of the geometry change and dynamic light was left slightly out of sync to give the impression of a florescent light flicker. Compiler Light
Settings
(XWC settings relating to lighting quality) ![]() The option to adjust the Lightmap and Lightgrid resolutions and samples are available in XWC. While default or lower settings are great for testing a level, during the final compile you will want to increase these values.
Standard compile settings for Starbreeze's levels on PC use Lightmap Resolution 32 and Multisample 4x4. The Lightgrid Resolution can be left with a value of 64, although Starbreeze levels can sometimes use a larger value. ![]() (Example showing different Resolution and Multisample values. Notice how an increased Resolution results in sharper shadows (left to right), while an increased Multisample value (bottom row) results in softer smoother shadows.) Additional Path, Script, & Etc. Information Starting,
Stopping, Resetting,
Reversing, & Moving to the End Position of Paths
(Start, stop, and resume paths, and use negative impulses to reset, reverse, and move to the end position of paths) Engine_paths can be paused, re-started, reset, reversed, and moved to the path's end. Note that if a path is stopped using a Waitimpulse, these will have no effect until it has been resumed. Starting / Stopping a Path
- Starting paths is done by sending a positive impulse
value
to
them (the
impulse matches the sequence you want to begin), while an impulse of '0'
will stop them (they can then be resumed again with a positive impulse).
Sending a stop impulse to a path also allows you to start it on a
different sequence. If an engine_path has the
'NeverInterrupt'
flag set, it will only stop once it has completed its sequence (rather
than stopping immediately). The same
starting and stopping logic also applies to other objects such as engine_rotate.
While paths can be reset, reversed, or moved to their end position, this often causes issues if the path needs to be able to be re-triggered. A solution for each situation has been provided below. Resetting a Path -
Sending an impulse of '-1'
to a path resets it to the beginning position regardless of where it is
in its sequence. When resetting a path
which has timed messages that
you would like to trigger again, ensure that the path has the AutoReset
flag checked so that the timed messages are repeatable.
Unless
the path being reset reaches the end of its sequence or timed messages
(whichever is longer), any
messages that had occurred before being reset will not function the
next time the path is triggered (i.e. the timed messages will only
continue from where they left off). A solution which allows the timed
messages to be properly reset is to send the '-1' impulse to the
path, followed by an impulse for a non-existent sequence (e.g. '2'
if the second sequence is not in use),
and then another '-1'
impulse. When doing this you should not have any timed messages at time
0 on the path otherwise they will trigger when resetting it. If you do
have a message at time 0, add a slight delay such as 0.001 or similar.
Reversing a Path - An impulse of '-2' reverses a path but only if it has not yet reached the end of its sequence or timed messages (whichever is longer). Ensure that the AutoReset flag is checked otherwise the path will not stop at its beginning frame when reversing and will continue traveling along that axis. When reversing a path that has timed messages, no messages will be triggered while the path reverses. If a
path is reversed while at the beginning or end of its sequence or timed
messages, the next impulse of '1' to the path will
cause it to 'jitter',
starting and then immediately reversing and stopping again. A solution
to this is to send two '-2' impulses when
reversing the path, one after the other.
Moving to the End of a Path - An impulse of '-3' jumps the path to the end of its current sequence or timed messages (whichever is longer). When jumping to the end position of a path that has timed messages no messages will be triggered during the jump. Similar
to resetting a
path, any timed messages that had occurred before moving to the end of
the path will not function the next time the path is triggered. A
solution to this is when triggering the path to send
it an impulse for a non-existent sequence (e.g. '2'
if the second sequence is not in use),
followed by a '-1'
impulse to reset the path, and then the impulse to start the path.
Starting, Stopping, & Resetting Scripts (Start, stop, and resume scripts, and use negative impulses to reset scripts) Engine_scripts can be paused, re-started, and reset. Note that if a script is stopped using a Waitimpulse, these will have no effect until it has been resumed. Starting / Stopping a Script
-
Similar to paths, engine_script
objects can also be stopped, resumed, and reset. Starting
scripts is done by sending an impulse value
of '1'
to
them, while an impulse of '0'
will stop them (they can then be resumed again by once more sending an
impulse of '1').
Resetting a Script - Scripts can be reset using an impulse of '-1'. When resetting a script which has timed messages that you would like to trigger again, ensure that the script has the AutoReset flag checked so that the timed messages are repeatable. Unless
the script being reset reaches
the end of its timed messages, any
messages that had occurred before being reset will not function the
next time the script is triggered (i.e. the timed messages will only
continue from where they left off). A solution which allows the timed
messages to be properly reset is to send the '-1' impulse to the
script, followed by an impulse of '2', and then another '-1'
impulse. When doing this you should not have any timed messages at time
0 on the script otherwise they will trigger when resetting it. If you
do
have a message at time 0, add a slight delay such as 0.001 or similar.
Averaging Speed / Time of Paths (Average the time of a path between its keyframes) ![]() Ogier includes a feature to average the speed / time of a whole path (a very useful feature), however, access to this seems to have been left out of the GDK. To fix this, place the updated nodetype.txt file included with this documentation into the ...\Enclave\Sbz1\Dev directory. Alternatively, this feature can also be added manually by opening the existing nodetype.txt file located in ...\Enclave\Sbz1\Dev. Find the line "DESC" "Scale time". Add the following below the closing curly bracket ( } ): {
"CLASSNAME" "AVERAGESPEED" "TYPE" "Button" "DESC" "Average speed" } Either of these methods will add a button to average the speed of a path in Ogier, allowing the feature to be used. Minimum First Keyframe Time (Minimum length of the first keyframe of a path) Note that the first keyframe of an engine_path must be greater than 0.001. If 0.001 or less is used as the first keyframe time, the path will skip to the next keyframe. Destroy Time (Destroy a path at a set time) A delay in seconds before the engine_path will be destroyed / removed ('-1' for never). To add a destroy time to an engine_path, add a new key named 'destroytime' and enter a value. If the engine_path is stopped, reset, etc., then the destroy time is also stopped or reset. An alternative is to send a Destroy message to the engine_path either from itself (e.g. with a Target of '$this') or from another object. Wait Impulses (Pausing a path or script and waiting for a specific impulse) Wait impulses pause an engine_path or engine_script until the specified impulse is received. While paused, all others impulses are ignored (so, for example, a path or script cannot be reset or have its sequence changed while paused with a Waitimpulse). Wait impulses can only be applied to the same object which is sending the Waitimpulse message (i.e. '$this'). The Waitimpulse message is commonly used to create counters (see the Counters section for more information) and can also stop a path or script until a certain sequence of impulses are received (such as with the door puzzle in Deserted Temple). Additional Dynamic Settings (Additional options which can be used with dynamics) In many of this document's examples force is applied to dynamics simply by using an engine_path with 'Physics' enabled. Another option is to apply a velocity directly to the dynamic, while further settings that affect how a dynamic reacts are also available. These options do not function correctly with the definition file included with the base GDK. To fix this, place the updated nodetype.txt file included with this documentation into the ...\Enclave\Sbz1\Dev directory. Once the nodetype file has been updated, the following features can be applied to any dynamic:
In Enclave dynamics often involve stonework. The 'weight' of these dynamics can sometimes be better simulated by adjusting the 'Velocity', 'Friction', and 'Elasticity' fields in order to give an appearance of a heavier object. An additional trick for these effects is to convert the dynamics into engine_paths and then use the 'Scale time' button to slow down their animation speed (e.g. by applying a scale of 120%). ![]() (An example of a physics simulation using additional settings and scaling of the animation, versus the same simulation without these changes. Note how the added settings and scaling make for a more controlled sequence where the stones have a 'weightier' appearance.) Further information can be found under the Merged Solids, Lighting Modes for Dynamics & Paths, and Sound Tricks with Dynamics sections, as well as by referencing the examples that use dynamics. Message
Pipes
(Triggering targets sequentially or randomly) ![]() Messagepipes can forward messages sequentially, or at random to a list of targets within their Target field. These are entered separated by commas, such as: 'target1, target2, target3'. Selecting Sequential will alternate through this list one at a time each time the messagepipe is triggered (note that the first target in the list is not necessarily the first that will be triggered!), while Random will select one target at random each time the messagepipe is triggered. A Setstate message can be added to an object to prevent a pipe from triggering it (instead causing the pipe to skip to the next item in its sequence or select a new random choice). To do this, add a message to the object with the triggering pipe's Name in the Target field and set the State to 'Blocked' to stop the object from being triggered, or to 'Open' to re-enable it. This can be useful to either temporarily or permanently stop the object from being triggered by the pipe. In both cases the pipe will skip over the object and move on to the next one while the state is 'Blocked' and resume triggering the object when the state is set back to 'Open'. Note that if all targets of a pipe have their state set to 'Blocked' and no target has a queued 'Open' message, the last object that was triggered will continue to activate (i.e. a pipe will always trigger at least one target). An example of Setstate messages in use is in Highvalley where messagepipes are used to randomly select where enemies will appear next, and then Setstate messages temporarily disable that selection from being chosen again in order to prevent the same spawns being triggered back to back. Trigger_ext objects can also randomly trigger outputs by checking the Random flag. Message Branches (Send different messages depending on the received impulse) ![]() Message branches act similar to switch statements in programming, or as relays. They trigger different message outputs depending on the impulse received (e.g. if an impulse of '1' is received, trigger the message given in the OnImpulse 1 field). Note that sending an impulse of '0' to a messagebranch does not trigger it, so use an impulse of '1' upwards. Objanim Objects ![]() (An object that cycles through a list of actions) The objanim object can be used to cycle through a simple list of scripting actions. The actions begin when the level is loaded and can be made to repeat by using the action reset. Additional actions (e.g. Action5, Action6) can be added using the New Key button. Actions are entered in the form of a text string and may include:
The same functionality and more can be achieved by using an engine_script or engine_path. It's likely that the objanim object is deprecated and it is recommended to use those instead. Merged Solids ![]() (A group of objects where the parent relays messages to its child objects) Sometimes there may be multiple objects which are desired to all be targeted at once. Rather than give each of the objects the same Name, all the objects can be grouped together and then the group changed to a node_mergedsolid object. Any child objects will automatically receive a linked Parent key to the parent merged solid, and sending a message to the merged solid will relay it to all children. Objects that are part of the merged solid can still be targeted individually allowing finer control. Merged solids allow for previewing and removing sequences of their child objects, and also updating their LightingMode. An example of a case where this can be useful is having a breakable wall made up of multiple dynamics and engine_paths. These related objects can be grouped into one node_mergedsolid, which when triggered, will then in turn trigger all the dynamics and paths. This is useful to more easily manage large groups of objects. Trigger Ext Objects (Additional features of trigger_ext objects) ![]() While various features of trigger_ext objects are already covered in other sections of this document, it is also worth noting that they can be activated by sending the trigger an impulse of '1'. (This is in addition to an object such as a player entering its volume. If a trigger_ext is desired to only be triggered by an impulse, disable any other intersection flags, i.e. 'Player', 'Character', 'Projectile', and 'Use'.) Trigger_ext objects can also be used to randomly trigger one of their outputs each trigger by checking the Random flag. Another option for randomly triggering effects is to use Message Pipes. Logic Gates (Logic gates allow for setting and testing 'variables') While scripted variables weren't truly added until later versions of the engine, logic gates can still be created either through a system of starting, stopping, and resetting paths / scripts, or with a game-space test using triggers, paths, parenting, filtering, and other objects to mimic logic gate functionality. ![]() (An example of a test setup tracking the number of enemies killed and allowing a test of that value to to see if it matches dynamic criteria.) There are many ways to implement these types of setups, and while no example is specifically covered here, the scripting information in this document provides everything needed to create these systems. Logic gate style arrangements can be useful for cases such as adding puzzles, setting up scripted sequences with multiple outcomes, or creating minigame style challenge levels. Filtering by Character Class (Enabling a trigger for only certain character classes) ![]() (An example of how a trigger could be used to display a class specific tutorial message.) Events can be triggered based on the player character class, although this requires the addition of a *targetname value in the TplCharacters.xrg file for each of the classes(s) to be tested for. After adding the targetname(s), simply use the Intersect Objects field on a trigger to restrict it to only that character type. File Editing File Editing
Introduction
(Modifying or adding text based files to change or add content to the game) While one aspect of custom Enclave content is creating brand new new art assets, another is working with the various plain text files that make up the game's common elements. While a new level or item can be created for the game, these background files are what define how that level will be loaded and what kind of mission it is, what art assets the item uses and how it functions, and other such values. These files are almost all have the extension of XRG (string tables instead use TXT). Examples of what these files can be used for in Enclave include:
While the sections in the document often refer to modifying the game files directly, when creating new content it may be preferable to separate additions into their own files where able in order to make them easier to organize and distribute. Many types of game files are entirely independent and only need to be placed in a folder to be used (such as dialogue files), while string tables and template files need to be specifically set to be loaded when the editor and game are launched. These latter types of files can be added to P3.xrg and Sv.xrg under their respective headings to do this. Custom string tables can to be added to the *STRINGTABLES line in P3.xrg. (Note that custom tables must go before the main game string table to load properly. Different string tables should be separated using a semicolon.) Adding a new string table to the game may look like the below: *STRINGTABLES
"Registry\\StringTable_Sandbox.txt;Registry\\StringTable_Eng.txt"
Custom templates can be added to their related section in Sv.xrg to be used by both the game as well as Ogier. Adding another prefab template to the game may look like this: *templates
{
*include TplPrefabs.xrg *include TplPrefabsSandbox.xrg // This custom prefab XRG has been added so that it can be used in Ogier and Enclave. } When editing files, additional things to keep in mind are:
Dialogues & Subtitles (Add text or subtitles to the screen) ![]() Dialogue files have a few uses in Enclave; adding spoken lines to characters, adding subtitles, or displaying text messages such as for a locked door. These can be added using dialogue XRG files placed within the ..\Enclave\Sbz1\Dialogues directory. There are two ways to display these in-game. When making a character speak, the name of the dialogue file being used should be entered into the 'Dialogue' field of the character's properties. For anything else, you can use a narrator object and similarly place the dialogue file name into the 'Dialogue' field in its properties. In either of these cases, you can then send a 'Speak' message to the character or narrator with the 'Dialogue' value being the number of a specific line within the specified dialogue file. Each dialogue entry has an ID number which is used to reference it. At the simplest a dialogue entry might only reference a sound, however they can be expanded to include the following properties: '*SOUND'
- The name of a sound that will be played when the dialogue is
triggered.
If the dialogue is being used with a character that supports it, and
the
sound is set up as a WaveStream sound, the
character will automatically lip
synch to it.
'*TEXT' - The text that will be displayed. Using '|' in the text will act as a line break. Text can also include specially named variables such as '§LTUTORIAL_JUMP'. Note that text will only display within a certain radius of either the character or narrator object, with the text beginning to fade at 384 units from the camera, and vanishing entirely at 512 units (if needed this can be worked around by parenting a narrator to an engine_path). '*SUBTITLEDURATION' - The duration (in seconds) that the text will remain on the screen for. If no duration is given, the default duration of 3 will be used. A duration of 3 is commonly used for most subtitles or game messages. '*PLACEMENT' - Changes the location of the text, '*PLACEMENT 1' will display the text in the centre of the screen, '2' will use the top centre. If no placement is specified, the default of '0' (the bottom center of the screen) will be used. During cutscenes text that is at the bottom or top of the screen will overlap with the black letterbox. '*COLOR' - The color of the text that will be displayed (in hex notation, e.g. '0xa0d0ff'). If no color value is included, the default white color will be used. '*FLAGS' - Sets if this text is a subtitle, game message, or tutorial message. '*FLAGS 2' means that the text will display even if subtitles are disabled (useful for item pickups or tutorial messages), while using '3' seems to indicate that the text is a tutorial message (there may have previously a game option to disable tutorials, this does not appear to be included in the release version). If no flags are specified, the default of '1' (subtitle) is used. Below are some examples of what one might find in dialogue files. *29 f4_death
This one is dialogue 29, and simply plays a sound when called. This is often used for character sounds which are not subtitled. *100
{ *TEXT "Help!" *SUBTITLEDURATION 3 *SOUND ge_halfling021 } This is dialogue 100 in a different file, it prints a subtitle for three seconds while also playing a sound. This is generally used when making a character talk. Characters will automatically lip synch to any WaveStream sounds specified (see the Importing Custom Sounds section). *1
{ *TEXT "Welcome to the Sandbox|This is the next line" *SUBTITLEDURATION 3 *PLACEMENT 1 *COLOR 0xa0d0ff *SOUND
*FLAGS 2
}This final example is of dialogue '1' and prints a different colored text in the center of the screen which will always be displayed even with subtitles disabled. This style of message is used for gameplay messages, such as with locked doors or item pickups. Note, if using Cyrillic alphabet characters, the text should be converted to Windows-1251 / cp1251 encoding before being entered into files such as dialogues or the string table. Custom Targets (Custom target information shown on the bottom of the screen) ![]() Custom health bars for objects can be added and displayed using the 'SetNPCBar' message. (Refer to the Custom Targets & Cannon / Ballista Targets example above for implementing this in-game.) To add the custom text entry, you may edit the the StringTable file found in ..\Enclave\Sbz1\registry. Find the section under the '// Targets' heading and simply add an entry like below: *TARGET_L_MSB
"Text Target"
If you're looking to have a AI Character with a custom name, you'll need to edit (or more preferably add) an entry from Tpl_AICharacters.xrg instead. Both of these can be done using a separate file as mentioned under the File Editing header as well (rather than editing the base games files). Creating Prefabs (Create new prefabs to use in your levels) ![]() Prefabs are useful when creating instances (i.e. many variations of the same object, which all inherit their properties from a single source object), or objects which will be commonly reused, with the caveat that they can't be lit using lightmaps from a level itself. First you'll want to create your prefab in a new map file. Note that all elements of a prefab must be an object in order to display in-game, so ensure that any brushes have been converted or added to an object. Next, compile the map into an XW and place it into ..\Enclave\Sbz1\Worlds\Prefab (compiling the navgrid is not necessary, however lighting can be enabled if the prefab is desired to have baked lighting, see below). Prefabs can use baked lighting, Gouraud shading, or both. If baked lighting is desired ensure any related objects are set to 'Auto' or 'Lightmap' and then render lighting. Baked lighting will not affected by lights in the level that the prefab is being placed into, and may also cause a possible editor crash when using the world or physics simulation modes in Ogier with the prefab in view (an issue with particular surface types). Now, we need to add the prefab to Ogier's object browser. Open the TplPrefabs.xrg file in the ..\Enclave\Sbz1\registry directory and add a new entry as in the following example: *prefab_boat
{ *classname template_prefab *prefab Prefab\boatprefab.xw } This is the simplest form of a prefab. *prefab_boat defines what will appear in the object browser within Ogier (in this case the 'prefab' group will contain the object 'boat'), while *classname specifies what object this prefab should be a subcass of. The *prefab line is the path to the compiled XW file which actually contains the geometry / objects. Once added, the prefab will be available for use in Ogier under 'prefab' within the Create object window. Note that the prefab XW and modified XRG files need to be included when you distribute your level. Prefabs can also have an object defined as a main entity by adding the *mainentity key followed by an object name (e.g. '*mainentity main'). When messages are sent to the prefab they are passed on to this object. This is useful to trigger scripts within a prefab, or to add variations to a prefab based on messages it receives. Examples might be triggering an engine_path or engine_script within a prefab in order to spawn its related objects (this is how Mordessa's and Vatar's teleporters are implemented), or setting up a prefab to have different effects depending on an impulse value that it receives. Prefabs are not able to send messages to objects outside of themselves, i.e. in the main level, however a bridge can be created to pass messages using elements such as an emitter which affects a trigger that is placed in the main level. Prefabs can be added using a separate XRG file as mentioned under the File Editing Introduction section as well (rather than editing the base games files). Changing Prefab Keys & Flags (Modify a prefab's keys or flags from the XRG file) Main entities in prefabs can have their keys and flags further modified in an XRG file. This is another option to create multiple versions of the same prefab that have slight differences. An object within the prefab first needs to be specified by adding *mainentity followed by the object name. After this, a key on that object can be changed using *mainentity_ followed by the key's name and new value, or any flag by using *mainentity_ followed by the flag type and name (separate multiple flags using a + sign). For examples of this in use, look into the siege prefabs which are included in the TplPrefabs.xrg file in the ..\Enclave\Sbz1\registry directory. The names of additional flag types for other game objects can be found in nodetype.txt located in the ..Enclave\Sbz1\Dev directory. Creating Templates (Creating templates for commonly used groups of objects) Templates are a different form of prefab, usually meant for models or groups of objects that will be commonly used. Some properties of objects within a template are can be modified on each template instance in Ogier, e.g. the light brightness and light color of a torch. Templates are specified in the Templates.xrg file, refer to this file for further examples. See the External Geometry / Shadow Casting / Collision section for additional information on using XW files for geometry, shadows, and collision with templates. Campaigns & Rewards (Define and place a mission on the map or create custom campaigns) ![]() New levels can be added to campaigns, or entirely new campaigns can be created, mainly by editing the Campaign.xrg and StringTable found in ..\Enclave\Sbz1\registry. The campaign file serves to add locations to the map, specify playable characters and rewards, add music to levels, and so on. The StringTable contains all mission related text, such as titles, story, objectives, and reward or failure text. Examples of both files are included showing the Sandbox mission added to the Light Campaign with comments marking where each section has been added (just search for '//This' within the files and you'll find each of these changes). First, let's look at the additions to Campaign.xrg: *Sandbox //This entry has been
added
{ *position 400,100 *iconsurface GUI_Ic2_Challenge } These lines have been added under the *locations heading in Campaign.xrg and set the x / y location of the location on the map, as well as the icon which identifies it. All the possible standard location icons can be found in the GUI surface file but new ones can also be added (see the Importing Custom Textures and Surfaces & The Surface Editor sections). *l_msb //This entry has been
added
{ *location Sandbox *type mission *music_atmosphere dark_03_a *music_battle dark_03_b *picmips 0,0,0,0,0,0,0,0 *character paladin+archer+druid+boarrider+engineer+wizard+9320+golem { *map Sandbox *award gold:5,item:paladin:weapon_sword_mordessa *specialaward_0 challenge:l_c1_1 } } Further down under the *challenges heading you'll find a set of entries which set the actual XW file to use for the mission as well as the music, usable characters, awards for completion, etc. In this example, *location Sandbox matches with the above defined Sandbox map location, *type mission specifies that it is a regular mission map rather than a survival challenge or cutscene, and the *character line defines which characters can be selected during the equip screen. Within the { } section below, *map specifies the WX file for the mission, *award lists the different bonuses given for completing the mission, and *specialaward unlocks bonuses if the related event has been triggered in the level (e.g. finding a map to an unlockable challenge level). For a complete list of the different settings that can be used for a level in the Campaign.xrg, see the below Campaign Challenge Settings section. *award
challenge:l_c1_2,challenge:l_msb,gold:100 //This was added to
show a mission being unlocked as a reward
Next you'll find a modification to the Forbidden Atgard level's awards showing how to unlock one mission from another. In this case, 'challenge:l_msb' has been added which corresponds to the Sandbox level's name under the *challenges heading. *l_msb //This has been added to
enable the sandbox mission from a new
campaign start
Finally is a line added to the *newgame_light section, showing how to add a new level to be already unlocked when the player begins a campaign. Next we'll look in the StringTable file to see how to add mission related text: *LOCATION_SANDBOX
"Mission Location" //This has been added
This has been added under the Locations header and corresponds to the *Sandbox map location entry in Campaign.xrg. This is the name of the selectable location on the map. *CHALLENGE_L_MSB
"Mission Title"
//This set of entries has been added
*BRIEFING_L_MSB "Text Story" *STORY_L_MSB "Text Objectives" *AWARD_GOLD_L_MSB "Text Reward" *GAME_CAMP_SANDBOX "Mission Loss" This set of lines has been added under the Challenges header and contains all other text information related to the mission. It corresponds to the l_msb entry in Campaign.xrg. *CHALLENGE is the name of the actual mission, *BRIEFING and *STORY are the story text and objectives listed on the loading screen, and *AWARD_GOLD is text which is displayed alongside any gold reward when the mission is completed. *GAME_CAMP_SANDBOX would normally be placed under the Campaign header, but it was put here to keep the entries together. This adds a line which can be set to display on mission failure. (Note that the name and location of the award and loss entries in the StringTable file don't matter as they are chosen from within the Editor.) Using '|' in any of these will act as a linebreak. Campaign Challenge Settings (Settings that can be applied to a level through Campaign.xrg) A number of settings can be used for each level specified in the *challenges section of the Campaign.xrg file. Main Settings (Settings that are applied for most levels.)
Other Optional Settings (Additional settings which may only be applied for some levels.)
Cutscene Specific Settings (Settings which may be applied for entries with a mission type of 'cutscene'.)
Cutscene Tip: When
making an in-game cutscene level, the cutscene can be made to be
skippable or non-skippable.
To make a skippable cutscene, use '*cutscene_spawncharacter 1' and an engine_path with a BeginCutscene message in the level. Start the engine_path using either the AutoStart flag or a trigger placed in the same location as the player's position. This format is how the cutscenes in Enclave were set up. To make an unskippable cutscene, use '*cutscene_cameratarget' and no BeginCutscene message. Also do not use '*cutscene_spawncharacter'. With this setup the cutscene will only end when the length is met. Other Optional Map Block Settings (Settings that may be used within the 'map block' of the entry.)
Challenge Map Spawns (Additional information about challenge level spawns) Challenge levels can spawn a preset list of enemy waves at info_start_dark and info_start_light objects in a level. These enemies are spawned out of sight of the player (if possible), and can be based on any defined AI types from the XRG files. Within the Campaign.xrg entry for a challenge level *type Survival should be set. Following this, *survival_enemies can be specified, with each enemy separated using + and each group of enemies separated using a comma. *survival_enemies
Ai_engineer_L1+Ai_boarrider_L1,Ai_huntress_L2+Ai_huntress_L2
In the above example, two waves will be spawned. The first will consist of Ai_engineer_L1 and Ai_boarrider_L1, while the second will be Ai_huntress_L2 and Ai_huntress_L2. The game will wait for all enemies from one wave to be defeated before spawning the next. *survival_timelimit can be added but is optional, this key may be left over from an earlier version of Enclave. For more reference on how a survival map can be set up, look at one of the official entires in Campaign.xrg. Adding Pickups (Adding pickup items that can be used in missions) ![]() ![]() Various types of pickups exist in Enclave, however one that can be especially useful in new levels are mission pickups. These can be items such as keys used to access new areas, or objects to be collected and used in goals (such as Marcus' account book, the dark flag in Iellon, or even Princess Jasindra). Pickups commonly consist of the following elements:
The model that a pickup uses, image displayed on the GUI, sound played or text shown when collected, and how the pickup acts is defined within a XRG file. An example XRG entry for a ring of keys that can be collected by the player and then used for multiple doors (i.e. doesn't dissapear from the player's inventory after use) follows. *pickup_key_ring
{ *classname template_pickup *model world\stuff\key_ring *iconsurface gui_icon_key_ring *dontdestroy 1
}*itemtype 0x19B *sound_pickup EQ_MISC7 *pickupmsg DialogSandbox:80 In this example the *dontdestroy flag is used so that the pickup is not removed from the player's inventory when used. The *itemtype value gives the pickup a unique identifier - only one of any identifier can be carried at a given time. The other fields set the model, icon, sound, and text relating to the pickup. A full list of that can be used in a XRG file for a pickup item are below. All of these are optional, although at the very least an itemtype should be set.
Message List Below
is a list of the
various messages that can be sent, and the values representing
each which appear in level files. These are
useful for deconstructing how
elements in the official levels were scripted, see the two examples
below.
'0.5;0x31;;0;door_wd02opcl' '0.5' is the delay, meaning this is a timed message, '0x31' is the message type which represents 'Play Sound'. There is no target entry which would normally be between ';;', meaning that this message is using the default of $this as its target. In this case the '0' has no function, and 'door_wd02opcl' is the sound to be played. (This entry plays a door sound from the object 0.5 seconds after being activated.) '0x111;gob_4_ch;0' '0x111' represents an AI message with the target being 'gob_4_ch'. The '0' references the 'Release' state. (This entry releases a goblin AI character when triggered.) 0x110; - Impulse
0x111; - AIImpulse (See list Below) 0x1008; - Begin Cutscene 0x1009; - End Cutscene 0x100b; - Spawn 0x100c; - Speak 0x128; - End Round 0x12a; - Fade Screen 0x129; - Special Award 0x1; - Wait Impulse 0x31; - Play Sound 0x33; - Set Sound 0x35; - Set Model 0x1017; - PlayAnim 0x30; - Destroy 0x100d; - Immune 0x100e; - AI Control 0x100f; - Siege Control 0x1010; - Switch Character 0x1011; - Shake Camera 0x101a; - Rumble 0x1012; - Set Model Flags 0x1013; - Air Craft 0x1014; - Add Gold 0x1015; - Add Health 0x1018; - Set Fade (Range between 0 and 255) 0x1019; - Set NPC Bar 0x5000; - Set State 0x1016; - Destroy Item 0x5001; - Teleport Object AI Impulse List
Color Format Color values for objects are stored in hexadecimal format outside of the editor. This format can be broken into five parts with the first two being a prefix and alpha value, and the last six characters being the red, green, and blue color values. Values are defined between 255 and 0 with 'ff' representing '255', and '00' being '0'.
As an example, the hexadecimal format color '0xffffcc80' can be broken down into the parts following the prefix of 'ff', 'ff', 'cc', and '80', which translates to an alpha of 255, red of 255, green of 204, and blue of 128. Below
is a list of all
available skies included
in
the game. Some skies may display visual glitches when paired with
certain depth fog settings (causing flickering). If you see this, try
tweaking the depth fog in your level, or by using one of the presets
included in Atmospheres.xmp.
Sky_ELM8
and Sky_ELM8b
are useful when
creating endless fog as they inherit the depth fog's color
(this
is used in Ark Amar).
Skies can be modified or added through the ..\Sbz1\skies directory, see the Custom Skies section for more information. Atmospheres.xmp which is included with this documentation contains presets from Enclave's official levels. Each level's sky, depthfog, sunlight, and NH fog values are included. (Note that the NH fog density might not match those of the official maps, you may need to tweak this.) ![]() ![]() Terrain & Organic Shapes Starbreeze
Engine games
use brushes to make up organic shapes; stones, rock walls, valleys,
plateaus, caverns, and other such features.
![]() (An example of terrain on the left and the brushes which make up the scene in wireframe on the right. Methods used to create each part of this terrain are described below. This sample is included in the Sandbox example map.) When determining how to build organic shapes that fit with the game's style, it's great to reference existing levels for inspiration. Some of Enclave's terrain geometry includes a 'carved' appearance (evident in levels such as the Underworld and Mines of Ungard missions), some a 'spiky' appearance (such as Outland Wastes and Kam-Zara), and others a more traditional terrain style. Often using combination of methods like those below works well depending on the desired look. Just as important as the geometry is its texturing. Enclave includes a variety of terrain textures, often with trims and variations. Applying these different materials in a thoughtful way is key to making terrain interesting. Note that Enclave's terrain textures tend to be scaled to double in size (0.5 in both directions), scaling textures this way will assist in building terrain to a similar size as the main game. If creating an expansive area, it may also be useful to scale the textures even larger for surfaces further away from the player (used in areas with large-scale terrain such as Ark-Moor and the chasm in Mines of Ungard - note how surfaces near the player use the standard 0.5 scaling, while areas further away use a larger scale).
![]() (An example of an area made up of wedges that have had their height adjusted by moving the verticies. This is a common way to create terrain, examples include the ground in Ancestors, Mansion of Dreams, and others.)
These
shapes also make it easy to achieve the 'carved' or 'spiky'
appearances seen in some game levels such as the rocks of Kam-Zara or
caverns of the underworld or Mines of Ungard levels.
![]() (Examples of terrain created using primarily spike cubes, as well as the odd spike and spike wedge.)
![]() (An example of geometry modified using an alternative editor before being imported into Ogier. In this case the shape was blocked out very simply before being exported, modified in an external application, and then reimported and textured.) Importing Brushes Convex shapes can be imported into Ogier from 3D modeling software as brushes using MAP format (note that Ogier is able to both load and save files in MAP format even though it's not listed in the Open dialogue). ![]() (Example of the same geometry in Blender, TrenchBroom, and Ogier.) You may need to select all surfaces on the imported brushes and use the Reset button in the Texture tool to fix any stretched textures (note that tools generally support the export or conversion of UV information, but Ogier does not support the v220 MAP format meaning cases such as sheared textures will not import correctly). It may be best to merge geometry exported using some methods to get cleaner brushes once in MAP format (using Selection > Merge in Ogier, or Edit > CSG > Convex Merge in TrenchBroom). Some options include:
Surfaces, Textures, Models, Sounds, & Animations XTX
files are text
based files used for compiling textures or models to a format
usable by the game, and to define how textures are displayed in the
game with surfaces. These files
come in two main types / formats:
XTX Files for Compiling Files
- XTX
files are used to define properties for assets such as textures and
models which are then compiled using XWC into a format usable by the
game.
This type of file is formatted with each class or key prefixed with a '*' followed by its value. This style of file can be seen in the KotT examples files and also the sample files provided with this download. *SURFACES
{ *SURFACE { *NAME "MySurface" *TLAYER { *TEXTURE MyTexture *FLAGS Lighting } } } XTX files of this type can either contain information for only a single type of content (e.g. a XTX might contain only information for compiling a model's mesh), or may contain multiple sections (e.g. a XTX might be made to contain information for compiling a model's mesh, its textures, and its surfaces all in one - in this case the textures would be compiled into a seprate file and the surfaces combined with the model). Included multiple sections in this type of XTX is done by starting the file using '*MULTIXTX' and then specifying a section for each type of item to compile or include, e.g. '*XMD' (models), '*TEXTURES', and '*SURFACES'. XTX Files for Defining Surfaces - XTX files are used to define surfaces that can be applied in-game. Surfaces include information about how textures should be displayed. All textures must have a related surface to be used, and can be applied in a level, on a model, shown as part of the GUI, and etc. XTX and XSU files used for surfaces can be placed anywhere within the Sbz1 directory in order to be used in the game, however if surfaces need to be visible within Ogier's Surface Browser, this must be done by placing the related XTX into the ..\Sbz1\Surfaces directory. When a level is compiled, information from the surface XTX files used to texture level geometry is included in the XW - this means that those XTX files are not required when distributing a map (unless you want others to be able to load and use the textures in Ogier). Similarly, when compiling models, related surface XTX information can optionally be included within the model file. This type of file
is formatted with both the class or
key and its value in quotations.
This style of file can be seen in the game's official surface files and
also the sample files provided with this download.
{
"CLASSNAME" "SURFACES" { "CLASSNAME" "SURFACE" "NAME" "MySurface" { "CLASSNAME" "TLAYER" "TEXTURE" "MyTexture" "FLAGS" "lighting" } } } Some additional points about these files:
(Creating
or modifying surfaces)
![]() Surfaces are used to define how a texture is displayed and can include features such as layers, effects, and animations. All textures must have a relating surface in order to be used. A surface can be as simple as something to implement a standard texture in the game, or can include elements to add complex effects, e.g. glowing runes on a wall, or a cube mapped reflection on metal trim. It is recommended to choose unique names for your surfaces except in special cases such as 'simple' surfaces. Surfaces are stored in text based XTX files and can either be distributed in that format, compiled into models, or be packaged together as a XSU (a collection of surface files). Surfaces used in levels are included in the map's XW when they are compiled - so there's no need to include the XTX or XSU files for these types of surfaces in releases. Similarly, if surfaces are compiled into a model, they do not need to be distributed separately. XTX and XSU files used for surfaces can be placed anywhere within the Sbz1 directory in order to be used in the game, however if surfaces need to be visible within Ogier's Surface Browser, this must be done by placing the related XTX into the ..\Sbz1\Surfaces directory. While surface XTX files can be modified in any text editor, Ogier also includes a complete surface editor (pictured above) which can be used to change and preview surfaces. This is a great way to see what a surface may look like, while editing a XTX file directly is still an easy way to add or apply settings to a large amount of surfaces quickly. Many of the below settings are described as they are found in Ogier, but these can be changed just as easily when editing the file directly (try modifying a file in Ogier and then view it with a text editor to get an idea of how different flags or features are written out in text format). The Surface Editor
The
surface editor won't
be documented in detail as there's a lot to cover, but it's pretty
intuitive. Here you can create new surfaces, animate them, add effects,
and modify settings. Certain effects (such as applying cube or
environment maps) require
texture
operators to be entered. Some additional
information (though not much) can be
found under the Surface
Editor section in the official documentation.
To
access the Surface
Editor, open a XTX
file in Ogier. If the
textures don't load (i.e. they show up as grey images), try creating a
new
map in Ogier first to load the world surfaces, then re-open the XTX
file. When modifying surfaces you'll want to
have both the Workspace
(set to Tree View)
and the Node Bar
open which will
allow you to set additional properties of the surface file, surfaces,
and texture layers.
Surface Package & Surface Names To give a surface package an in-editor name and order (i.e. the order that the surface package will appear in Ogier's Surface Browser), select the topmost level group in the Workspace and provide an 'Ogr_name' and 'Ogr_order' key. (Note that if the name is left blank the surface will use the name of the XTX file, if the order if left blank the package will be shown following any ordered ones.) You can also add an 'Xr_parse' key with a value of '0', setting this will exclude a surface package from being included in a compiled XSU file. Generally, any surfaces that will be compiled into a level or model can have a 'Xr_parse' value of '0', while surfaces that are not (such as GUI textures) would have a value of '1' (this is the default). ![]() To give
a specific
surface an in-editor name, select the surface in the Workspace and then
fill in the 'Name'
key (the 'Name'
key will be located towards the
bottom of the Node Bar,
this is different from the object name found near the top of the Node Bar).
![]() Layers
Surfaces can be made up of multiple layers, this can be used to create complex effects such as reflective surfaces, lit up windows, burning embers, or magical energy coursing through rocks. Layers can be added by clicking the New Layer button in the surface area (a small page with a folded corner). They can also be moved up, down, and deleted using the arrows and other buttons. A surface's base layer is shown as the top most element of the list with each additional layer being shown below. The final element in the list is the surface (the product of all layers). Animations ![]() ![]() Surface properties can also be animated, for example the color of a layer can be blended between different values (used to make symbols glow in levels like Kam-Zara), or the offset can be shifted between different positions. The play and stop buttons below the viewport can be used to preview animated surfaces. To add a keyframe in the Surface Editor, click the New Keyframe button in the top right (a small page with a folded corner). Each keyframe will show as a tab above the layers, select a desired keyframe and then change one of the surface properties. An A➞ will appear next to the property to show that it is now being animated. To remove the property from being animated, the A➞ can be clicked, or the keyframe can be deleted. The duration of each keyframe can be changed using the Duration value, and the Loop option can be selected to loop the animation. Other types of animation can be added through operators (see Surface Operators below). This can be used for scrolling and rotating textures, or applying frame animation where multiple textures are used as consecutive animation frames. An example of a surface using both animated layer properties (for fading in and out) and an operator (for rotation) is the symbol shown above. Any type of surface animation can be started and stopped by applying the surface to an engine_path. When the engine_path is triggered, this surface will begin animating, and when it is stopped, the surface will also stop its animation. Surface Operators Surface
operators can be added by selecting a 'tlayer' in
the Workspace,
then clicking 'New
Key' on the Node
Bar and adding the
fields 'Operator00',
'Operator01',
and so on. Operators are not shown in the Surface Editor, but
only on the Node Bar.
Operators that can be used are listed below.
Basic Operators
These operators use values which are in texture units; this is based on a the normalized dimensions of the texture, meaning that '1.0' is equal to 100% of the texture's dimensions, or '1.5' is equal to 150% of the texture's dimensions. Values can be less than 0.0 or higher than 1.0.
Reflection & Fresnel
Operators
Surfaces where rendered environment / cube maps are applied use a special surface operator, and an alternate version of this as well as a Fresnel effect can also be added, often for water surface. More information about the rendered maps for these effects can be found in the Environment Maps / Cube Maps section. These operators will not be previewed in Ogier's Surface Editor or 3D view normally, but will be displayed when the XW or Preview lighting view modes are enabled. Surfaces that use the NV20 operators include an alternate version for use with renderers that don't support these effects (such as OpenGL). An example of this is Enclave's water where there are two versions of the surface, one with the NV20 Fresnel and GenEnv effects, and another without.
Other Operators
Additional operators include ones used for frame animation and applying a wave effect to a surface.
Amplitude
affects the
height and depth of the crests and valleys of the wavelength
in Ogier units, while Speed is the time in seconds that it
takes
one wavelength to pass (i.e. the from the crest of one wave to the
next). The X-Length, Y-Length, and Z-Length
values determine the frequency and direction of the wave on each world
axis. These length values are
measured as 0.15625 per Ogier unit - a value of 10 equates 64 units,
and 20 is 128 units. Negative
numbers reverse the wave's
the direction. (E.g.
'Wave
x+y+z, 8, 0.2, 20, -10, 0'.)
Values
can be given for
each axis independently, e.g. a value for the X axis alone will make a
wave move along the world's X axis, while also providing a value for
the Y axis will give the effect of a diagonal wave (a combination of
waves moving along both the X and Y axes). Using values for all three
axes together can create a 'warping' effect,
and
multiple wave operators can also be layered together - both techniques
were used for the pulsing surfaces in the Vatar level as well as the
pit in the Mordessa cutscene map.
![]() (An example of a wave operator being used with a surface.) Additional notes relating to the wave operator include:
Flags There are a number of flags which can be set either in the Surface Editor or in the XTX file.
Simplified versions of surfaces can be included by giving adding a second entry which uses the same name as the primary surface and including the option 'simple0' in the XTX file (e.g. "OPTIONS" "simple0"). These alternate surfaces will be shown in-game if Complex Surfaces are disabled in the Graphics options (xr_surfoptions) and are commonly used to define simplified materials (e.g. ones without reflections). Ogier's Surface Browser will display the normal version of the texture and not the simple version, the simple version will remain hidden. Simple surfaces can be previewed in Ogier using the View > Simple surfaces option while XW or Preview lighting view modes are enabled, or tested in-game with the xr_surfoptions command. Bump Mapping Flag One option that isn't available in the surface editor is the flag used for bump mapping. To enable this on a texture, add 'bump' as one of the flags in the XTX file. Note that under the Direct3D8 renderer, textures using bump maps may have issues with dynamic lighting (e.g. torchs and equipped staves within a darkzone). In Enclave, only the sewer textures in Iellon Dungeon use this bump map flag. Precidence In-game, surfaces that are compiled into files (e.g. levels, models, XSU packages) take precedence over any external XTX files. Note that if two or more surfaces are created using the same name but follow each other directly in a surface file, only the first surface will be displayed in Ogier's Surface Browser. If two or more surfaces are created using the same name but are specified in different parts of a file, or different files, the last surface loaded is the one that will display in Ogier, while the first surface loaded is the one that will be displayed in-game (with the special case being simple surfaces, see above). Outside of simple surfaces, it is best to give all surfaces a unique name to avoid issues. XSU Files XSU files are a compiled version of surface information and may contain the contents of multiple XTX files. These are sometimes used for distributing surface information without the original XTX files, best used when packing surfaces that aren't normally compiled into other formats such as with GUI graphics. This format doesn't seem to have been utilized heavily in the games, with surface information generally being compiled into levels and models, or the original XTX files simply being distributed with the game. (Importing
image files as
textures)
![]() Textures
for Enclave come
in two parts, compiled XTC
packages which contain the texture images, and XTX (or XSU) files that
include surface information which tell the editor and game how to
display the texture.
Opening an XTC in Ogier will load the relating XTX (providing the path of the XTX file is the same as when the XTC was compiled, or has been updated to the new location by changing the 'Path' key). Making changes and then saving will update the XTX file, which must then be recompiled for the XTC to be updated and the changes take effect. When working with textures it's important to remember that the Workspace and Node Bar can be used. The Workspace will display individual textures in a package while in Tree View, and the Node Bar will display additional options that can be set. Texture Formats
Although Enclave may have at some time supported a few image formats for textures (TGA, JPG, PCX, and single frame GIF), it is recommended to use TGA, and this has been the format that was used by developers.
Creating XTC Files XTC files contain the image information for textures. Once compiled into an XTC, the images can then be referenced in surfaces and used in-game. Images and texture properties are listed in a XTX file, and then compiled to XTC. These files can be created through a couple different methods: Creating a XTC / XTX With Ogier
One way
to create a XTC
package is simply
doing it through
Ogier. First, place any images you plan to import into a single
directory, then open Ogier and select New
texturecontainer under the File menu. This
will bring up a
dialogue where you can select the desired images. From here, you can
select any of the individual textures and set a number of
properties. Once done, type a name into the Destination field
near the bottom,
followed by '.xtc'
(example: 'test.xtc'),
and click the Compile
XTC
button to the right (this looks like a stack with an arrow pointing
downwards). This will compile and place the resulting XTC file in ..\Enclave\Sbz1.
Note that you can save your texture container as a XTX file and reopen or modify it later. Creating a XTC With XWC / Manually Modifying a XTX The second method is a bit more hands on, but offers more control, especially if you plan to tweak and recompile the texture package often. This involves creating your own XTX file (or modifying one generated using Ogier or XWC), an example of which is included with this documentation (TextureExample.xtx). If you would like a starting point for an XTX without creating one from scratch, you can use the New texturecontainer option mentioned above and then save it as a XTX, or generate one by dragging a directory with images onto the XWC window (this will generate two files; a XTX file used to compile the textures, and a basic XTX surface file). Below is an explanation of the example XTX: *DESTINATION
"Example.xtc"
*NAME Example These first lines specify the output destination, file name, and internal name of the XTC. By default, the compiled file will be placed in ..\Enclave\Sbz1, but a more specific directory can be pointed to instead, e.g. 'Textures\\Example.xtc'. The option '*THUMBNAILS 1' can also be set is this section, this will generate a low resolution T_ version of the XTC when compiled which is specifically used as a thumbnail in Ogier (for when the Thumbs tickbox is selected). Without a thumbnail version, the first layer of a texture will be used as the thumbnail when Thumbs are enabled. This option can be useful to add custom reference thumbnails for materials when using Ogier. *TEXTURE
{ *PATH "texture01.tga" *PICMIP 1 *FLAGS clampu } *TEXTURE { *PATH "moretextures\\texture02.tga" } From here we get into the actual textures. The first is for 'texture01.tga' in the same directory as the XTX file and has a couple options set, including a picmip value and a flag. The second entry is for 'texture02.tga' which is located in the 'moretextures' directory and has no additional settings. Values for PICMIP, PICMIPOFFSET, and MIPMAPLODBIAS can be set, as well as any additional FLAGS. These can also be set from within Ogier. At any time a XTX can be opened in Ogier, modified, and re-saved. The PICMIP option sets what picmip group a texture will be included in (0 to 15 with each representing a different group, e.g. World or Character textures). This is used by the game to allow control over texture detail for each category type (e.g. changing the sliders for World Textures and Character Textures in the game options will result in a change of quality for any textures in the associated groups). Picmip categories and quality can be previewed in Ogier using View > Set Picmips, or in-game using the 'r_picmip' console command (picmpips use a value between 0 and 10, with '0' being high detail and '10' being the lowest detail). The PICMIPOFFSET option for textures was also added in KotT. The MIPMAPLODBIAS option (also called LodBias in Ogier) is an offset for the level of detail for mipmaps. Mipmapping utilizes smaller versions of textures which are in-part rendered on objects further away from the camera. A value from 0 to 255 can be used, and although presumably this is intended to decrease the distance where mipmaps are swapped out, it hasn't been observed to result in a difference in-game. FLAGS can be any associated texture flags. A list of available options can be seen within Ogier. XTX files used for texture packages can be compiled in two different ways; by opening the XTX in Ogier and clicking the 'Compile XTC' button next to the Destination field, by simply dragging the XTX file into the XWC application's window, or by dragging the entire directory into the XWC window. Once the XTC has been compiled with your texture images inside, the textures can be used (with an accompanying surfaces XTX file) in Ogier or in-game. Precidence It is recommended to choose unique names for your textures. If two or more textures are created using the same name, the last texture will take precedence. This can be useful as it means creating an XTC that's loaded later (i.e. with a alphabetized name that comes after the game's compiled textures) will actually act as a replacement texture package. The Surface Editor Above we touched generating or creating an XTX file using the New texturecontainer option in Ogier or creating one manually using a text editor. Ogier also includes a visual surface editor which allows XTX files to be opened and a number of options to be set before re-saving the XTX. This is a great tool and you may find it easiest to generate a basic XTX using the New texturecontainer method, then applying further options through the surface editor. See the Surfaces & The Surface Editor section for more information on the surface editor. Environment Maps / Cube Maps (Simulating
reflective surfaces)
![]() Environment maps (also called cube maps) are used to simulate reflective surfaces such as metals or water. Maps are made up of six images which form a cube, this result can then be projected onto a surface. Generating Environment / Cube Maps
The cl_envboxsnapshot
console
command will generate a set of six images from the game camera's
current position which can be used as an environment / cube map.
It's recommended to do this while in noclip mode or using a camera as
doing so will
prevent
the player character from appearing in the images. Images
will be saved in TGA
format under ..\Enclave\ScreenShots, each
suffixed with '_0'
through '_5'.
The resolution the environment maps are generated at is
based on your game's resolution (a higher game resolution will result
in higher resolution environment maps).
Note that environment / cube maps are not generated in the correct order or orientation for use with surfaces in-game. To align the images correctly the following changes need to be made:
![]() (Pictured above is an example of environment map images generated using the cl_envboxsnapshot console command, followed by the same images after orientation changes have been made so that they will display correctly in-game.) Additional
tips for generating environment maps include:
Compiling a Environment / Cube Map The six
images for an environment / cube map must be compiled into a XTC file, ensuring
that the Cubemapchain
flag is enabled on the first '_0'
texture so that the game loads all six
images together. In order to apply the map to geometry, a surface must
also be created which references the '_0' texture
and includes either the genreflection
or nv20_genenv
operator (see the Surfaces & The Surface
Editor
section).
Surfaces with environment / cube maps can be previewed in Ogier while either the XW or Preview lighting view modes are enabled. Environment / Cube Map Resolutions & Alternate Surfaces Environment / cube maps are often unique to level areas of a level due to how they represent reflections of the room or area where the effect is used. Enclave's environment / cube maps were greatly reduced in resolution, often with each panel being between 32 x 32 (usually for water) and 128 x 128 (usually for reflective surfaces). This results in less detailed 'reflections' which in part hides the problem of them not lining up with the world geometry fully, but also lessens the need for unique environment maps and surfaces. ![]() (An example of a environment / cube map applied to a test sphere using the nv20_genenv operator. The same map is applied to the water surface below. This example uses a much higher resolution than those normally used in Enclave.) Many
reflective surfaces in Enclave exist as both an environment mapped
version as well as an alternate one which uses a generic Env material.
The second
version is not known to be used but may have originally been
included for specific
graphics renderers or detail settings. Also included for each
environment maped surface is a simple
version with no
reflection, this version is used if Complex Surfaces
are disabled in the Graphics
options (see more information in the Surfaces & The Surface
Editor
section).
Water in Enclave uses a different type of effect for its reflections, in this case a second simplified surface is also created. If the reflection (and Fresnel) effects are unsupported, for example when using the OpenGL renderer, the game falls back to using the basic animated water surface. Texture Mapping Types (Different types of texture mapping available for brushes and splines) ![]() Different texture mapping styles are avialable for both brush and spline surfaces. When using the Texture tool a selected object's surfaces will be tinted a different color in the 3D view for each mapping type, while the currently active mapping type will be displayed in the bottom left corner of Ogier. Brushes
Brushes have two texture mapping types. The majority of brushes will use the default Box-Mapping, however Plane-Mapping is important for some special situations.
![]() (Example showing a rotated cube using Box-Mapping, followed by the same cube using Plane-Mapping. Note how Box-Mapping results in inaccurate texture projection in this situation while Plane-Mapping allows for correctly alligned textures.) Splines Splines have three texture mapping types. All are useful in different situations. Note that flipping a texture on a spline may sometimes involve unorthodox procedures, and shifting may need to be done using the Texture tool in certain instances.
![]() (Example showing Box-Mapping and ST-Mapping on the outside and interior faces of a curve. Note how with ST-Mapping the texture follows the shape of the spline and doesn't stretch as the interior face curves onto a different axis.) (Importing
new models)
![]() This section is still incomplete, but referring to the information on XTX files, surfaces, and textures above and the notes below should provide the basics. General Information
Collision Meshes
![]() (Example of a model with different zones for the collision mesh indicated on the left, and different material types for the collision mesh shown in the center. The right image shows the how a specified zone and material are shown in game when that part of the mesh is targeted.)
Skeletons & Animation
An example of the default skeleton including the joint names, bone numbers, and hierarchy is below. This
is the basic bipedal skeleton used for most characters, although more
unique ones such as the wraiths or Vatar in Enclave use their own
skeletons.
![]() (The list of joints, bone numbers, and the hierarchy of the default skeleton. Items in grey are used in KotT but not Enclave.) Icon Surfaces for Pickups (Graphics displayed for mission and equipment pickups) ![]() Icon surfaces are used to display UI graphics for mission pickups (e.g. keys or other usable items) and equipment pickups (weapons, shields, arrows, etc.). These images are specified using '*iconsurface' or '*shield_iconsurface' in the related XRG file. Icon graphics should:
Additional details on each type of icon surface are below. Note that information on positioning (e.g. offsets or padding) is based on the scale of the original 128 x 256 image - UI images are then scaled depending on the game's display resolution. Graphics are also not restricted to the suggested safe areas or padding amounts, but keep in mind how larger graphics might overlap other pickup images or UI elements. Also note that when Enclave's resolution is increased the GUI elements will increase in scale and the status display and coin count will move further downwards from the top of the screen. The game however does not correctly adjust the vertical position for pickup graphics to match. Because of this, the higher the vertical resolution, the less space there is between the coin count and first pickup icon, potentially causing the two to overlap. This means that even images that are within their suggested padding may still overlap with the coin count when the game is at a higher resolution. Keep this in mind when making larger graphics. Mission Pickups (&
Potions)
Mission pickup images are shown on the right side of the screen when the related pickup is collected, and on the left of the screen below the health bar when the player is a position where the pickup can be used. Potions appear on the right side of the screen and are always positioned directly below the coin count.
The
following template can be used as a reference when creating pickup and
potion graphics.
![]() (The left image shows suggested padding for mission pickup and potion images. The right image shows how these images appear one under the other - shifted horizontally for visibility, each offset downwards from the previous. This template shows image position in relation to the coin count only for standard resolutions.) Equipment Pickups (Right & Left Slots) Equipment pickup images are displayed on the left side of the screen below the health bar to show what items the player has equipped, and also appear on the right side of the screen briefly when the related pickup is collected (if placed in a level).
There are two types of equipment pickup graphics, ones used with the right slot (e.g. weapons), and ones for the left slot (e.g. shields, arrows, staff abilities, and the torch). Each slot has slightly different positioning, with right slot graphics generally being taller and positioned higher due to the way the UI is laid out. Right Slot
The
following templates can be used as a reference when creating and lining
up equipment pickup graphics.
![]() (The images on either side show suggested padding for equipment pickup images for cases where they will be displayed on the right of the screen. The center image shows the positions where the pickup images will be overlaid on the GUI_HUDBAR03_01 texture - note that there is a 1 pixel difference in the vertical position between the two graphics.) (Modifying
or creating new skies)
![]() Skies are defined in an XRG file which describes the elements of the sky and their properties, and must have a XTX file which uses the same name prefixed with 'Surf_' where all surfaces used for the sky are defined (e.g. MySky.xrg and Surf_MySky.xtx). Both files should be placed in the ..\Sbz1\skies directory. For more information about surface files and textures see the relating topics in the Surfaces, Textures, Models, Sounds, & Animations section. Each XRG file defines a '*skytrack' which contains (often multiple) '*skylayer' elements. Each sky layer has a '*type' followed by any related keys or values, including what surface to use from the sky's relating XTX. Multiples of any layer type can be used with different priorities or positions in order to layer elements over one another (e.g. to create a starry sky with layers of clouds and a moon). All sky elements are fullbright, any lighting in the sky is simulated through the textures and surfaces used. As always, it can be recommended to look at the files that ship with the games for reference of how skies and the related textures and surfaces are set up. Layer Types
There are three types of layers used for skies in Enclave and KotT: envbox, box, and sky. ![]() (Example showing different types of layers that might be used: An envbox - in this case a solid color which surrounds the sky, a box - which uses textures with transparency for hills and trees, and sky layers - which make up the clouds and sun. The point in the center is the point of view - a level's sky will be displayed as if viewed from this point. The right shows what the resulting sky might look like.)
The cl_envboxsnapshotconsole
command can be used to generate a set of six images from the game
camera's
current position which can then be used as a set of box textures. This
can be useful if
creating terrain and geometry in Ogier, or importing terrain from
external modeling software to further detail in Ogier, both of which
can then
be captured to use as part of a sky.
Layer Properties A number of properties can be set for each layer type in XRG files, some are optional while others do not have appear to have an effect for skies in Enclave. Properties that are available for in Enclave and KotT include:
The
third value is how many times to repeat
the surface on the plane. The last ('f')
value applies a scrolling
animation to the surface (this was left unused in Enclave
and KotT in favor of using the scroll operator or animations on the
surfaces themselves).
Depth Fog & Skies Depth fog doesn't affect box layers, but does affect envbox and sky layers. For box layers Enclave sometimes uses haze painted onto the textures to simulate the appearance of depth fog on the distant terrain and cloud layers (a good example of this is the Light side Celadia Village sky, shown below). For a further understanding of how fog is suggested on a sky's box layers, it's recommended to look at Enclave's sky textures and surfaces. ![]() (On the left is a box layer texture from the Light side Celadia Village sky. Note how depth fog has been painted onto the texture, and additional haze added above the hills to help blend the box layer with the clouds. The right image shows how this works in-game with the level's depth fog to bring the fog effect of the sky together.) Any part of the sky where there is no sky element (i.e. the void can be seen) will show the depth fog color behind it. A sky like the one for Ark Amar contains no sky elements and simply shows the depth fog color as the sky.
(Viewing sounds in the editor)
![]() One issue exists with editing for Enclave using Ogier is the lack of support for Enclave's version of XWC sound files. Luckily, a set of fixed audio files are available to solve this. The sound fix includes a set of recompiled XWC files which can be read by the released versions of Ogier. Note that these files will crash Enclave if left in the game directory. For this reason, it's recommended that you either create a copy of the Enclave directory to use with the editor, or temporarily remove the fixed XWC files before launching the game. (Note a bug exists where sounds that are set to objects, such as fire sounds for torches or the wraith's ambient sound, play at 0,0,0 in the editor instead of their respective locations.) If using the sound fix, download the SoundBrowser fix archive and place the updated XWC files into ..\Enclave\Sbz1\Waves. If not using the sound fix, there are still at least three other workarounds that can be used to locate sound names from the game to use:
Sound Prefixes & Suffixes Sounds in Enclave exist as a large collection of 'complex sound' presets, each raw sound file can have entries with different volumes, pitches, and radii. For example, while 'lock_40.ogg' might be the name of the physical sound file, 'lock_40a' is the name of the basic sound in-game, and 'lock_40c' is another version with a decreased pitch. This complex sound information is stored within the games XWC files. The Below are common prefixes and suffixes added to the raw sound name. Common prefix Changes
Suffix Changes There will often be sounds suffixed with 'a', 'b', 'c', etc. with different pitches, volumes, or radii. (E.g. 'lock_40.ogg' can be played as 'lock_40a'. 'lock_40c' is another version with a decreased pitch.) Not all sounds will follow this naming scheme, an example is the randomized bush rustling sound using ft_ rather than rn_ as a prefix. Sound Tricks with Dynamics Detailed dynamic sounds can take time to set up as they may consist of sounds at a number of points during the sequence. Perhaps
the best way to do this is by changing the dynamic to an engine_path
and advancing the frame to each point where a sound should play, in
each case setting the sound time to roughly the value shown in the 'Time'
field. (Note that the engine_path
can always be changed back into a dynamic
after if desired.)
Also of assistance is the bottom left corner of Ogier where the time value in seconds is shown when running a simulation (if not, turn on the Status Bar from the View menu). Using this, time values of when certain events are happening in the dynamic's sequence can be noted. When using the sound fix mentioned in the Sound Browser section, real time audio in the editor will also be enabled for some of the simulate and preview modes. This can be very useful to preview sound timing. (Note that sounds in the 'Timedsound' fields might not play when using dynamics and paths in Ogier. If you're having this issue, try using 'Play Sound' messages instead for experimenting with finding the correct sound timing. These messages can be removed after if desired). Complex
Sounds & Waves
Sounds can be specified in two different forms, as a 'complex' sound which already has a set of attributes applied, or as a 'wave' sound where some of these attributes can be managed directly following the sound name. Note that only complex sounds seem to work in Enclave, so the option to call sounds as waves may have been added after the games release. While complex sounds are specified within a XWC, wave sounds instead simply point to an audio files name. Wave sounds must be preceded with a $, and can be followed by up to four additional values specifiying volume, pitch, and range. Below are two examples of wave sounds. Commas are used to separate values. (Default values for waves are 100, 100, 32, 512.) '$v_demon1_atks02:150,200,64,128' Volume of 150, pitch of 200, range near of 64, range far of 128. '$v_demon1_atks02:,200' Pitch of 200. (Importing
your own sounds)
![]() Sounds
are stored in XWC
files, which contain both the raw audio, and also preset 'complex'
sounds which have attributes (such
as pitch,
volume, or radius) applied.
In order to create a XWC file, you must have the audio files you
wish to include (in wav format), and a MMP file containing
all written
sound
information. An example MMP
file is included with this documentation (SoundExample.mmp).
Inside a MMP file will be two main sections. These are described below. The first where the actual audio files are imported: XWC_AddWave("guidark",
"WAVE\\guidark.wav");
The first quotations contain the name that will be
used to
refer to
this wave from the game or any complex sounds, while the second
quotations contain the path from the MMP to the WAV file being
imported. In this example, the WAV
'guidark.wav'
is being imported as 'guidark'.'XWC_AddWave' can be used for most sounds, however if you would like a character to lip sync to the audio then 'XWC_AddWaveStream' should be used instead. Lip sync in Enclave is based on the waveform of the sound file with higher peaks meaning that the character's mouth is opened wider. Note that the released versions of Ogier do not appear to load or display WaveStream sounds correctly, the editor will either crash or the sounds will not appear in the sound browser (for this reason you may wish to compile a version of the XWC to use for editing, and one to use for release). The second is where 'complex' sounds are specified: XWC_AddSFXDesc("guidarksound",
"guidark", 0, 100, 0.0, 1.0, 0.0, 1024, 64);
Now that a WAV has been set to be imported, a 'complex' sound can be specified which uses it. The first quotations contain the name the complex sound can be called by in-game. The second quotations contain the name of any waves this 'complex' sound references. Following this is a string of values separated by commas, each which affects the playback of this sound (explained below). In this example, a 'complex' sound called 'guidarksound' is created and will play the wave 'guidark'. Another example of a 'complex' sound, this time one which plays a random wave: XWC_AddSFXDesc("gui_random",
"guidark;guilight", 0, 80, 0.0, 0.8, 0.0, 512, 32);
Sounds can also reference a number of waves separated by semicolons to play by random selection. In this example, the 'complex' sound called 'gui_random' will play either 'guidark' or 'guilight' with a 50% chance. A blank wav named 'SILENCE' can be used if you wish to have a random sound with a chance not to play at all, such as was done with a number of AI characters in the game. The following are the values that can follow a 'complex' sound: 'Prior'
- Currently uncertain what
this affects. Maximum value is 255.
'Pitch' - The pitch of a sound. 'RndAmp(Pitch)' - Applies a random pitch modifier to the sound. Total between Pitch and RndAmp(Pitch) should not exceed a value of 790. 'Volume' - The volume of a sound. Value between 0.0 and 1.0. 'RndAmp(Volume)' - Applies a random volume modifier to the sound. Total between Volume and RndAmp(Volume) should add up to a maximum value of 1.0. 'Max/Min Distance' - The maximum distance of which the sound can be heard, and the minimum distance where sound falloff should begin. (Value in units.) Finally, near the bottom of the file is the line 'XWC_End("Waves_example.xwc");'. This denotes what the compiled file should be saved as. It will be created in the same directory as the MMP by default. To compile a MMP into a XWC file, just drag it to the XWC window. Custom XWC files should be placed into ..Enclave\sbz1\Waves. Note that due to a compatibility issue, audio files compiled using Enclave's version of XWC will not load in the editor if more than one 'complex' sound is present. (However, the sounds still work fine in-game.) If custom sounds are needed to work in-editor, it is recommended that a second version is compiled using the Knights of the Temple version of XWC as well. (These files will work with the editor, but not Enclave.) (Preview
and select
animations)
![]() Ogier 102 contains a working model and animation browser for Enclave. To open it, simply press the folder icon next to any animation property field. ![]() Animations can be specified as 'path\ + animation file name: + animation number', or in the above example, as 'Gameplay\elm_5:11'. The value following the animation number in the browser is the animations length in seconds (in this case 2.22 seconds). This is helpful for setting up timing in scripted sequences. Animations can also be examined in depth or previewed in-place using the animation tool accessed through File > New animation, this feature also works in Ogier 101. With the animation tool open, select File > Import animation to load an animation file, then in the Video bar, select either a model by clicking the folder next to the Model field, or a template by clicking the folder next to the Tpl field. To preview an animation in-place, click the folder next to the Arena field and select a level file. When doing this, a selected model will appear at the origin of the level by default, but if arenaposition objects have been placed then the model will appear there instead. If multiple positions are placed they can be toggled between using the arrow button next to the Arena field, or from the Edit menu. Importing,
Modifying, & Exporting
Custom Animations
(Importing, modifying, & exporting animations) ![]() The Ogier editor contains an animation tool which can be used for importing, modifying, saving, and exporting custom animations. To access this tool go to File > New animation. To be used in-game, animations must first be exported to a XSA file. This can be done using File > Export animation or File > Export animation uncompressed. Animations which have been saved in an uncompressed format can also be compressed by dragging the XSA file to the XWC window (the file will be compressed in place, i.e. no copy will be made). Note that animations which ship with Enclave utilize an earlier format of CompressedAnimationSet, while the publicly released versions of Ogier export to the CompressedAnimationSet2 and newer uncompressed formats used in Knights of the Temple and Riddick. Due to this there is currently no known way to export an animation for use with Enclave. See the Animation Browser section for information about previewing animations in-place using arenaposition objects. It is recommended to examine the contents of the ..\Enclave\Sbz1\Anim directory for further reference of how animations are prepared. Importing Custom Fonts (Importing your own fonts) ![]() Fonts are stored as XFC files in the ..\Enclave\Sbz1\Fonts folder and are compiled using XWC. To compile a XFC the following are required:
An example set of files are included with this documentation (Gothic.ttf, FontExample.cfg, & FontExample.mpp). Knights of
the Temple
Editing Introduction
Knights of the Temple was released by Starbreeze in 2004 using a variation of the engine employed for Enclave. As these two games were developed so closely together, much of the information in this document can also be applied to KotT, although a number of objects and messages have been added or removed (including some very handy new features). Some issues have come up when editing for KotT on certain systems, the following are workarounds for common problems. An error resulting in a broken 3D
view is
received when simulating the world within the editor:
This can be solved by unchecking Show animation within Ogier's View menu, or by renaming the Anim folder in ..\Knights Of The Temple\Sbz1. (The error seems to be related to the editor loading certain animations.) Some models have invisible surfaces (or are completely invisible!) in Ogier: This issue seems to be related to an alpha surface rendering problem. To temporarily fix this, open the models .xmd in Ogier (found in \Knights Of The Temple\Sbz1\Models), select the model in the Workspace, and delete the 'Readonly' key. Close the model without saving changes. As long as Ogier is open, the model will now display in the 3D view (minus alpha). Not all objects show in the 'Create object' window: Some objects will not show in the object browser when using the Insert key (most notably, engine_paths and engine_scripts). This appears to be due to the objects being classed as 'solid' rather than 'entity' in the games nodetype file. These objects still show up in the browser when a brush is selected to be made into an object, and can also be placed on their own by entering their name into the 'Classname' field, and then clicking 'Create'. (I plan to include a corrected nodetype file with this documentation in the future.) The error 'Unknown version of engine-path data' comes up when opening the sample levels in Ogier: These files can be opened using Ogier 102 instead. Alternatively, you can keep pressing 'ok' and the map will load, minus the keyframe data for objects like engine_paths and dynamics. Templar Camera System One of the biggest changes in Knights of the Temple is the introduction of a camera system where the view of each scene is pre-defined by the level designer. The intention of including this section is to provide a more comprehensive and up to date description of the different camera options available. Each camera is represented by a camerapos object in Ogier. To activate a camera, a message with a value of '1' should be sent to it. That camera will then remain active until another camera is triggered. Most commonly, trigger_ext objects are used to trigger camera changes. In cases where the triggers for two cameras overlap, the new camera will not activate until the currently active camera's trigger has been completely exited. ![]() (Pictured is an example of how triggers might be used to switch between cameras. When the player walks through a trigger, the related camera will be activated.) Often, cameras will come paired with a rail (also represented by a camerapos object in Ogier). Rails allow greater control over a cameras movement, defining the exact area or a vector where the camera will move along its own spline. Every
level must have a camera named 'StartCam',
this is the camera that is active when the level completes loading. It
is
also good practice to set up a trigger which activates the starting
camera and place it at the players start position.
For a better understanding of the how cameras are used in a level, I would recommend looking at the two example levels included with the Knights of the Temple GDK (the_watermill_a & holycity_b), and comparing the camera / trigger setups with how the camera acts when played in-game. (Note, if you receive an pathing error when opening these sample levels, try loading them using Ogier 102 instead.) Camera Types (There are three main types of cameras that can be used.) Point Camera (No mapping)
The most basic type of camera, this is a camera with no keyframes or spline. By default, point cameras are fixed in place and will keep focus on the player. If given a 'SafeRadius' value, the camera will shift out of the way when the player enters that radius. This can be useful in situations where the player may be able to get close to, or move underneath the point camera. (See the below section on camera attributes for more information about using a safe radius.) ![]() (An example of a point camera. This camera has a safe radius set, causing it to shift out of the way when the player enters the orange area.) Spline Camera (Camera Mapping) A camera that has a spline, but no rail. This type of camera will follow the spline as the player moves, always attempting to be a point on the spline closest to the player. When transitioned to, the camera will start in a position along the spline which is nearest to the player. A value can be entered into the cameras 'Rail. Distance Max' field, this will make the camera tolerant up to that distance. This is distance in units that the player can move away from the camera before it starts moving along its spline. (It will be like a string where the player pulls the camera along its spline, with the camera only moving when the string is stretched.) ![]() (An example of a camera moving along its spline to follow the player. This camera has a rail distance set, causing it to to be 'pulled' along the spline only when the player has moved a certain distance away from it. The orange area represents the camera spline.) Rail Cameras Cameras with rails offer more control over the cameras movement, and are the most used camera type in Knights of the Temple. Rails are represented in Ogier by a camerapos object, and a rail can be linked to a camera by placing the corresponding rail name into the camera's 'Rail' field. Cameras can move independently from their rail, allowing (for example) a camera to be moved one direction, while the player is moving another. Rail cameras can be broken down further into three main types. Rail Camera (Rail Mapping)
When both the camera and the rail have a spline, the cameras position along its spline is based on the players position in relation to the rail splines start and end points. With this style of rail, the camera will be mapped to the same percentage of the camera spline as the player is along the rail spline. When the player is closest to the start of the rail spline, the camera will be at the start of the camera spline. When the player is closest to the end of the rail spline, the camera will be at the end of the camera spline. (Moving perpendicular from the rail will not affect the cameras position.) ![]() ![]() (Examples of cameras moving along their spline based on the players position in relation to a rail. The orange areas represent the rail splines.) Rail Dimension (Camera Mapping With Dimension) If a rail has the 'Rail. Dimension' option checked, the camera will act similarly to a regular spline camera, but with the players movement only translating to camera movement when they're traveling in the direction defined by the rail. (Moving perpendicular to the rail will not affect the cameras position.) In these cases the rail spline defines the vector the player should be moving along (the rail only needs a short spline to define the vector, e.g. 32 units). Using a rail with dimension can be useful to prevent undesired camera movement when you have cameras with curved splines (one example of this is shown below). ![]() ![]() (In the above example, if the player moves away from the cameras spline, the camera will attempt to move to a point on the spline closest to the player and may overshoot the desired position. This issue can be corrected by using a rail with dimension, causing the camera to only take into account the players movement in the rails direction when calculating its position.) The cameras 'Rail. Distance Max' can also be set to a higher value to achieve the drag effect as with a regular spline camera. Circular Mapping & Rail Distance Mapping If a rail does not have a spline, it will act as a radius where the camera will be at the start of its spline when the player is within the 'Rail. Distance Min' distance from the rail, and at the end of the spline when the player is at the 'Rail. Distance Max' or further from the rail. (Note, the official documentation states that this relationship can be reversed by entering a negative distance, however this does not appear to be functional.) ![]() ![]() (In the above example, the camera moves along its spline when the player enters the orange radius.) In the situation that a rail does have a spline and uses the rail distance fields, the camera will act similarly to the above circular mapping example, only the 'Rail. Distance Min' and 'Rail. Distance Max' will be applied to the entire length of the rails spline. ![]() By default, these mapping types will act as a cylinder along the rail with an indefinite top and bottom. Checking the 'Rail. Heightmap' option will change this to spherical mapping, which allows it to also take into account players vertical distance above or below it. Transition Types (There are three types of transitions between cameras that can be used. Note that all of the transition types can be made 'one way'. For example, two cameras can have an interpolation transition in one direction, and a snap transition in the other.) Interpolation
Interpolation is the default and most widely used transition type between cameras. This causes the view to dynamically move between the previous camera and the next camera. If something is in the way of the interpolation, the camera will perform a snap instead. When 'InterpolateAll' is checked on a camera, any transition to or from that camera will be preformed as an interpolation (this is the default setting). If unchecked, any transition to or from the camera will be preformed as a snap. In either of these cases, the type of transition can be overrode be entering names of other cameras into the 'Interpolation' field (e.g. 'cam001, cam002'). If this camera has 'InterpolateAll' checked, this list cancels interpolations to the entered cameras and uses a snap transition instead. If this camera does not have 'InterpolateAll' checked, this list enables interpolations to the entered cameras. The time it takes for the interpolation, and the sensitivity (how quickly the camera focuses on the player during the interpolation) can be set with the 'InterpolTime' and 'InterpolSens' fields. In both cases, the transition will use the greater of the values between the previous camera and the new camera. The sensitivity can also be set manually if the destination camera has been entered into the 'Interpolation' field. This can be done by following the camera name with a semicolon and a number value. For example, 'cam001;70' will make the interpolation to cam001 have a sensitivity of 70. ![]() (An interpolation between two cameras.) Snap If an interpolation is not used, a snap will be performed. The camera will be instantly transported to the new position, and aligned toward the player. This type of transition is preferred in narrow passages where there is no room for the camera to move around. ![]() (A snap between two cameras.) Transition Spline If two cameras share a common transition spline (entered in the 'Trans. Spline' field), that spline will be used to make the transition. Having a transition spline will override the use of an interpolation or snap. (Note that transitions splines were never actually used in the games levels. I'm including this transition type as it could still be useful in custom maps.) A transition spline is represented by a camerapos object and defines the path that must be taken between two cameras. The part of the transition that is not defined by the spline is performed like an interpolation, which means that you don't need to and generally should not make the spline go all the way to the cameras unless they are fixed in place. If you expect the angle between the transition spline and the interpolation to be somewhat large, you can check the 'Trans. Smooth' option on the transition spline to smooth the way the camera enters and leaves the spline. Transition splines can also be made one way by checking the 'Trans. OneWay' option. When this option is enabled, the transition spline will only be used from the camera closest to the start of the spline, while transitions in the other direction will instead interpolate or snap. The time it takes for the transition to complete will either be equal to the 'Trans. Time' value of the transition spline (if it is not zero), otherwise it will be the total length of the spline (the time of the last keyframe) plus the time for the interpolations to and from the spline (the length of these interpolations will vary depending on the distance, but will have the same velocity as the spline at its ends). If basing the transition time off the length of the spline, note that the transition speed will match the keyframe times of the spline. For this reason, it may be best to average the time of all keyframes on the transition spline. The sensitivity (speed that the camera focuses on the player) during the interpolation will be the 'Sensitivity' value entered on the transition spline. A pair of cameras can also share multiple transition splines between them (by default, the transition spline used will be the one in the first 'Trans .Spline' field). To indicate which one of the transitions will be used, send an Impulse with a value of '0' to the desired transition spline first (this activates it), followed by an impulse with a value of '1' to the destination camera. ![]() (A transition spline being used between two cameras.) Camera / Rail Attributes (This is a list of all options that can be changed on camerapos objects which are used for cameras and rails. Unless otherwise mentioned, these values should be set on the camera.)
Knights of the Temple Sky Listing (Below is a list of all available skies included in Knights of the Temple.) ![]() |
||||