Enclave Examples & Additional Documentation
Version 1.14, Updated March 2024
Document & Examples by Shawn Davison






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.


Contents
Files Included With This Document

Additional Ogier Tips

Common Editor Troubleshooting

Useful Console Commands

Example Map Documentation

Additional Path, Script, & Etc. Information
File Editing
Message List

Color Format

Sky Listing & Atmospheres

Terrain & Organic Shapes

Importing Brushes

Surfaces, Textures, Models, Sounds, & Animations

Knights of the Temple Editing

Files Included With This Document


There are a number of files included with this documentation, the following are for the main examples:
Sandbox.xmp - The source file for the example map. This can be opened in Ogier.
Sandbox.xrs - Paths (animations / simulations) for the example map. Place in the same directory as Sandbox.xmp.
Sandbox.XW - A compiled version of the examples map. This can be played in-game. (Place in ..\Enclave\Sbz1\Worlds)
Dialogue_Sandbox.xrg - Example dialogue file used in the Sandbox level. (Place in ..\Enclave\Sbz1\Dialogues)

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:
BoatPrefab.XW - Part of the example for creating custom prefabs. (Goes in ..\Enclave\Sbz1\Worlds\Prefab)
Campaign.xrg - Example for adding a level to the campaign map. (Goes in ..\Enclave\Sbz1\registry)
StringTable_Eng.txt - Example for creating custom targets and adding mission text. (Goes in ..\Enclave\Sbz1\registry)
StringTable_Sandbox.txt - Example for creating custom targets and adding mission text separately. (Goes in ..\Enclave\Sbz1\registry)
TplPrefabs.xrg - Example for creating custom prefabs. (Goes in ..\Enclave\Sbz1\registry)
TplPrefabsSandbox.xrg - Example for creating custom prefabs separately. (Goes in ..\Enclave\Sbz1\registry)

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.
  • Any object with a model field (such as an engine_path) can have any combination of up to three models or special functions. To do this, add a new key for 'model1' or 'model2' and place any additional particle string, dynamic light string, speed trail string, model, or other special string into it.
  • Many objects can be parented or attached to others to inherit their movement. See the Parenting & Attaching section example for more information on this.
  • You can create a cone, cylinder, or sphere brush with additional or fewer sides by creating a new object and selecting the desired shape under the 'primitive' group. Use the 'Creation params' to specify the number of sides, etc. (e.g. 'Param0' for the number of sides, and 'Param1' for the number of stacks in a sphere.)
  • The editor will attempt to re-align brushes and objects to the grid after rotating, this can cause them to snap to a position away from their origin. To rotate while maintaining the origin, press 'M' while using the Rotate Tool to bring up the Rotate degrees dialogue.
  • Never create a brush as thin as the smallest grid size. Always use one grid size up from it to prevent brush errors.
  • Ogier will generate a XRS file when you save your map. The XRS contains the pathing information (for engine_paths and dynamics as an example). This file is only needed for working on a level in Ogier or compiling, and not for running the final compiled map.
  • Utilize groups, the Workspace and Workspace Layers in Ogier. These help you organize your level and quickly toggle visibility of brushes and objects. Submaps and prefabs are other tools that can be used to help split up and organize levels.
  • If you need to apply complex rotations to an object while keeping textures aligned (for example, if you would like to have a crate at an odd angle), change the texture mapping type to Plane-mapping. When you rotate the object with Texture Lock on, the textures will remain correctly aligned.
  • You can view sounds, particles, distance fog, classes, triggers, etc. by opening a XW using a text or hex editor (such as Notepad or HxD) and searching. The objects are listed towards the bottom. (This is useful for finding values used in official maps.)
  • It is helpful to install multiple versions of Ogier as some features do not work fully in certain builds. 101 seems to be the most functional for Enclave editing, while 102 is good to have for recording dynamic simulations and using the animation browser (both of which do not seem to work entirely in 101).
  • When you do a final compile, be sure to increase the multisamples for lightmaps. This will take longer, but look much better! Standard compile settings for Starbreeze's PC levels 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. See the official documentation or the Compiler Light Settings section for more information.
  • By default, the XW-Compiler (XWC) creates logs at the root of the C: drive, this can cause issues if the C drive is used for Windows. If logging is desired the drive where logs can be created can be changed by modifying the XWC application using a hex editor and updating the three instances of 'C:\SBZ'.
  • Structure brushes are important for level optimization, see the Structure section for more information. A level will crash on load if at least one structure brush isn't present.
  • Levels can be saved in MAP format by choosing File > Save As then adding the extension '.map'. This format can also be opened by Ogier. This can be useful for using Ogier to create levels for different games, or to modify brush work in another editor before re-importing.
  • PlaySound messages function inconsistently (e.g. there may be no sound) if there isn't an AI character placed in a map.
  • When it comes to 'clipping' areas, the *PHYSICAL material can be used to block characters and projectiles while the *PLAYERPHYSICAL texture can be used to block only characters (note that all characters are considered to be 'players' in the case of this material, *PLAYERPHYSICAL acts similar to the traditional clip texture in other games). *AI_OFFLIMITS or *AI_SOLID can both be used to prevent AI characters from pathing into or through an area (as no navigation grid will be created in their volume), however these will not act as a solid brush and the AI character can still be pushed or forced into the space that the brush occupies.

Common Editor Troubleshooting

Below are tips regarding issues which may be experienced with Ogier.
  • If Ogier is having issues refreshing the 2D views properly (resulting in ghosting), try changing the Renderer or enable the Always clear view option from File > Preferences.
  • If texture color appears to be off in Ogier (e.g. a noticeable blue or yellow tone), try changing the Renderer from File > Preferences.
  • If no sounds are listed in the Sound Browser, download the Sound Browser fix. See the Sound Browser section for more information.
  • If Ogier crashes when launching the animation browser, or you find that physics simulations cannot be recorded, try using Ogier 102 for those features instead.
  • Ogier may crash when selecting a texture in the Surface browser, at this time a solution is unknown but this only happens with certain hardware configurations. This is possibly related to certain models of integrated video cards.
  • For some Knights of the Temple specific issues, see the Knights of the Temple Editing Introduction section.

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 u
sing Page Up and Page Down to scroll.
help - Displays the list of console commands. Use Page Up and Page Down to scroll.
bind - Bind a command to a key(s) or button(s) using 'bind "key", "command"'. Also see the other bind commands, e.g. bind2 (different commands on press and release) and others. Multiple commands can be assigned within the same bind. This is very useful for assigning commonly used commands to different keys.
map - Loads a level using 'map mapname'. Whichever music is currently playing (if any) will continue playing once loaded. When a level is loaded using the map command, it is set to Normal difficulty.
challengequick - Loads a level using its campaign challenge name and that campaign's default character. Any settings specified for the challenge (such as music) are used.
cmd noclip- Enables and disables noclip mode. The speed of the camera while in noclip is based on the selected character's speed (so select the halfling or goblin if you would like faster movement).
cmd giveall - Enables and disables godmode.
cmd kill - Kills the player character.
cmd selfsummon- Spawns a copy of the player character at the location of the crosshair (up to a certain distance away). The spawned character will be of the same class (i.e. armor level) as the player, but will have the default items equipped (as set in TplCharacters.xrg).
capturescreen - Takes a screenshot (saved as TGA in ..\Enclave\ScreenShots).
loadgame - Loads a save file 'loadgame savename'.
record - Records a demo 'record demoname'.
stop - Stops recording a demo.
play (or) demo - Plays back a saved demo with 'play demoname' or 'demo demoname'. Separating demos with a semicolon will play them one after another (e.g. 'play demo1;demo2').
timedemo - Quickly plays back a saved demo with 'timedemo demoname' to test performance. When the demo completes, the frames played, elapsed time, and average FPS are displayed.
debugimpulse - Sends an impulse of a given value to a specified object (e.g. 'debugimpulse myscript,1'). This can be used to test scripting in levels. Negative values can be entered as well. (Tip, you can set up debugging scripts in a level and activate, pause, or reset them using this command.)
pause - Pauses the game with 'pause 1', unpauses with 'pause 0'.
exec - Runs an external script file in MPP format. Can be useful to load configurations with different binds for testing, etc.
cl_timescale - Changes the speed of the game, e.g. 'cl_timescale 0.5'. Only works when playing back a saved demo. Default is '1'.
sv_set "timescale" - Changes the speed of the game, e.g. 'sv_set "timescale","0.5"'. Default is '1'. Lower values cause issues with the player animations and camera and a value of '0' will cause the game to crash (you may wish to record a demo and then use 'cl_timescale' for these cases instead).
sv_physrender - Enables rendering of physics collisions, the navgraph for AI characters that are moving, and other AI features with 'sv_physrender 1', resets with 'sv_physrender 0'. Note that this mode only displays correctly under OpenGL.
cg_menu cheatmenu - Opens a cheatmenu which also allows you to instantly complete a mission.
cg_playsound - Plays a sound using 'cg_playsound soundname'. Useful for testing sounds. (Note, if playing a file which contains multiple randomized sounds, only the first will play. This also seems to ignore any modified pitch settings on sounds.)
cl_envboxsnapshot - Generates a set of images which can be used as an environment or cube map (see the Environment Map section), or as a skybox (see the Custom Skies section).
setposition - Use 'setposition x,y,z' to set your current position to the specified coordinates.
xr_drawmode - Turns on wireframe with 'xr_drawmode 1', shows wireframe only with 'xr_drawmode 3', and turns it off with 'xr_drawmode 0'.
xr_nhfog - Turns off Non Homogeneous Fog with 'xr_nhfog 0', turns it on with 'xr_nhfog 1'.
xr_zfog - Turns off Depth Fog with 'xr_zfog 0', turns it on with 'xr_zfog 1'.
xr_fogculloffset - Sets the offset for distance fog culling, can be used to test culling offset values for sky_indoor objects, e.g. 'xr_fogculloffset 512'. Default is '0'.
xr_worldonly - Displays only world geometry with 'xr_worldonly 1', resets with 'xr_worldonly 0'.
xr_objectsonly - Displays only objects with 'xr_objectsonly 1', resets with 'xr_objectsonly 0'.
xr_sky - Disables the sky with 'xr_sky 0', resets with 'xr_sky 1'.
xr_showbounding - Displays visible object bounding boxes with 'xr_showbounding 1', resets with 'xr_showbounding 0'. Note that this only displays correctly under OpenGL.
xr_lodoffset - Sets the offset for model level of detail (LOD), use higher numbers to test different distances for LOD display, e.g. 'xr_lodoffset 100'. Default is '0'.
xr_splinetesslevel - Sets the tessellation level for splines as a value between 0 and 1, with '0' being low detail and '1' being high detail (see the Spline Tessellation section for examples of the different tessellation levels).
xr_surfoptions - Displays simple surfaces using any odd number, and complex surfaces using any even number, e.g. 'xr_surfoptions 1' (see the Surfaces & The Surface Editor section).
xr_debugflags - Displays character and equipment hit boxes / collision meshes with 'xr_debugflags 1' (only when within small radius of the character), resets with 'xr_debugflags 0'. Each unique collision area and material type is represented by a different color.
xr_wallmarks - Hides wallmarks and character shadows with 'xr_wallmarks 0', re-enables them with 'xr_wallmarks 1'.
xr_flaresDisplays light flares with 'xr_flares 1', disables them with 'xr_flares 0'. Flares are only displayed when running the game in OpenGL.
xr_dlight - Displays dynamic light with 'xr_dlight 1', disable it with 'xr_dlight 0'. Dynamic light is used for effects such as staves giving off light in darkzones, fuses, and bombs.
r_picmip - Allows picmip levels to be changed by giving the picmip group ID first (a value between 0 and 15) followed by the picmip level (a value between 0 and 10, with '0' being high detail and '10' being the lowest detail) (e.g. 'r_picmip 0,1'). Each picmip group affects a is used for a different type of texture (e.g. World or Character textures, see View > Set Picmips in Ogier for a full list).
r_enable / r_disableTurns on wireframe with texture and lightmap information with 'r_enable 1', and turns it off with 'r_disable 1'.
rs_resources - Displays currently used resources. This is useful for finding sound names used in levels.
wenable - Displays the boundaries of the node that the player is currently in with 'wenable 1'. Nodes are the result of structure brushes placed in the level (see the Structure section).
quit - Exits the game. Useful to quit the game quickly, or exit if the menus are disabled (e.g. after loading a level with the map command).
cmd 101 - Displays pathfinding route from the player's position to the position being aimed at. Only displays the result if sv_physrender is enabled.
cmd2 106,6 - Toggles rendering of AI FOV and hearing range. Must also use cmd2 106,12 and enable sv_physrender for this to display.

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.
  • 'Attach' - The position (x,y,z,name) of the joint where this object will connect to another.

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.
  • 'Attach' - The position (x,y,z,name) of the joint where this object will connect to another.
  • 'Attach_target' - A position (x,y,z or x,y,z,name). The hook will rotate to align itself between the joint and this second connection point.
  • 'Helpaxis' - Help axis, see below.

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.
  • 'Attach' - The position (x,y,z,name) of the joint where this object will connect to another.
  • 'Attach_line0' - A point (x,y,z) defining one end of a line, and where this object should attach to it from.
  • 'Attach_line1' - A point (x,y,z) defining the other end of the line
  • 'Helpaxis' - Help axis, see below.

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.
  • 'Attach' - The position (x,y,z,name) of the joint where this object will connect to another.
  • 'Attach_circle_origin' - The center point of the circle or sphere.
  • 'Attach_circle0' - A point on the circle or spheres outer radius. Together with the origin, this represents a circle, or a 3D sphere.
  • 'Helpaxis' - Help axis, see below.

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.
  • 'Attach' - Doesn't seem to be used for this type of hook, no affect.
  • 'Releasetime' - A delay in seconds before the object begins moving.
  • 'Destroytime' - A delay in seconds before the object will be destroyed / removed ('-1' for never).
  • 'Direction' - The direction (x,y,z) that the object should move.
  • 'Speed' - The speed that the object should move at.
  • 'Gravity' - The gravity that should be applied to the object. (The object will either be drawn downwards or upwards.)

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 p
layer 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.
  • 'Target' - Unknown, never used in the game.
  • 'Camera' - The name of a hook object to use as a camera when the siege object is activated.
  • 'Emitter' - The name of the emitter which should trigger when the siege object fires.
  • 'Engines' - The name of objects (such as engine_paths and hooks) that should animate with the siege object when it is charged and released. Separate multiple names using a comma.
  • 'chargeduration' - The time it takes to fully charge the siege object.
  • 'releaseduration' - The time it takes to release the siege object from a full charge.
  • 'reloadduration' - The time before the siege object is able to be charged again.
  • 'limitx' & 'limity' - The distance that the player can rotate the siege object on the horizontal or vertical axis. Each is specified as two angles separated with a comma (with 0 being the center). e.g. '-45,45'.
  • 'minemittervelocity' & 'maxemittervelocity' - The minimum and maximum velocity of the emitter set in the 'Emitter' field when the siege object is fired from no charge vs a full chage (this is used with the controlledcharge flag).
  • 'controlledcharge' - Allows the player to hold down the attack button to charge an attack, and release at any time. (Like the catapult in Iellon Outpost, this allows the player to change the firing power.)
  • 'accelleratedrelease' - Causes any attached siege engines to gain velocity after being charged and released. (Like the catapult in Iellon Outpost, this simulates the weight pulling the catapults arm down.)
  • 'lockplayer' - The player may not exit from the siege object after using it. (Used for the cannon and ballista in Naglagard and Highvalley.)
  • 'autocharge' - Always charges the siege object to full, then waits for the player to press the button to release. (Used for the ballistas in Enclave which always charge themselves automatically after firing.)

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.
  • prefab_cannon01 - Cannon used for Iellon Outpost (Light mission).
  • prefab_cannon02 - Cannon used for Naglagard. Allows for firing quickly and the player cannot exit the cannon view once used.
  • prefab_cannon03 - Cannon used for Ark Amar. This cannon has an increased projectile velocity versus the Iellon cannon.
  • prefab_cannon03_spawn - A spawnable version of the cannon used in Ark Amar.

Effects used generally consist of particle effects, fuses
, cannon projectiles, explosions, and dynamics.
  • Particle Effects - May include a smoke effect from the cannon muzzle when it fires, trailing smoke effect on the cannon ball, or impact effects such as dust and water splashes.
  • Fuses - May include a fuse leading to the cannon, or a simple fuse particle effect (in the latter case a flickering dynamic light can also be used to further add to the effect).
  • Cannon Projectiles - Either an emitter which spawns a physics based projectile, or an engine_path or dynamic with a predefined projectile path (these options work well for precisely scripted sequences). If a projectile needs to be visible inside the cannon barrel when using an emitter, a model or engine_path object can be used as a false projectile which is removed when the cannon fires.
  • Explosions - May include explosion effects at the cannon muzzle and (sometimes) the site of impact.
  • Dynamics - May include damage to geometry / objects at the site of impact, or even to the cannon itself (such as in Divided City).

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.
  • Length/Width (ANIM0) - The length and width in Ogier units where fire will be distributed around the cm_fire object. Flames will be dispersed within this area. For example, a value of '40' in each field would mean that flames would appear within a 40 x 40 box surrounding the cm_fire object - useful in a case such as when adding flames to a fireplace. Note that the center point of the flames are used when distributing them, this means that they can overlap this area by half their width. If flames are wished to be contained entirely within the desired area, subtract half of the Thick value from the Length/Width values.
  • Thick/Height (ANIM1) - The flame's thickness (or width) at its base and flame's height. These values should be half of the desired size in Ogier units (e.g. enter '8' and '16' for a flame 16 units wide and 32 units tall). Each flame will fluctuate, growing shorter and taller from the given height by approximately 40% as it animates.
  • Flames (ANIMATTR0) - The number of flames that will be used for the fire. Each flame is made up of two quads.
  • Seed (ANIMATTR1) - No noticeable effect and only set in very few cases in Enclave. May be deprecated.
  • Base col (COLORS0) / Mid col (COLORS1) / Top col (COLORS2)- Used to adjust the alpha and add a color tint to the base, mid, or top portion of the flames. This can be used to make the flames appear fainter, or to adjust the tone (e.g. a deeper red at the base, or a magical green tone).

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.
  • Max/Min Particles (ANIM0) - Limits the number of how many smoke particles can exist at one time.
  • Size/Distortion (ANIM1)- The size of particles in Ogier units (width and height) when they spawn, particles will increase in size by approximately 300% by their end position. Distortion affects how far particles will drift outwards from the the cm_smoke object in the direction it's pointing after being spawned (particles also will drift leftwards), this drift occurs in an arc.
  • Color (COLORS0)Used to adjust the alpha and add a color tint to the smoke particles.
  • Height/Pressure (COLORS1) - Controls the vertical height in Ogier units that the particles will reach before vanishing as the Height. Pressure acts as how hard (if at all) to 'push' the particles in the direction the cm_smoke object is facing - this acts as the name implies, forcing the particles out at a greater speed which dissipates as they travel upwards in an arc (particles will also drift leftwards, but less so than with Distortion). Both Height and Pressure also affect the speed of the smoke. If the Pressure is pushing in the same direction as the Height, then the vertical amount that particles travel will also be affected.
  • Spline Dist/Freq (COLORS2) - Applies a fluctuating movement on the x and y axis as the particles rise with Distance, it's recommended to try a low value between '4' or '16' to start with. Frequency increases how often these movements occur (again, try starting with a low value, such as '4'). Note that these movements always happen within the same travel distance, so increasing either value also increases the speed of the movements (meaning higher values make the particles more erratic).
  • Speed (COLORS3) - The overall speed of the particles.

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:
  • No Flags Selected (0) - If no flags are selected the object will not appear in-game or in Ogier's views.
  • 'Main 1' (S0) - When a level is played on Easy or Medium, it uses Main 1. This applies to Missions, Cutscenes, and Challenges. When a level is loaded using the map command, it uses Main 1 and Normal difficulty.
  • 'Main 2' (s2) - When a level is played on Hard, it uses Main 2. This applies to Missions, Cutscenes, and Challenges.
  • 'Cutscene' (s1) - Unknown. Neither Begin Cutscene nor loading a map set as a Cutscene in Campaign.xrg use this.
  • 'Challenge 1' (s3) - Unknown. Unsure when this or the other Challenge flags might be used. Loading a map set as Challenge in Campaign.xrg does not use this.
  • 'Challenge' (Challenge 2) (s4) - Unknown.
  • 'Challenge 3' (s5) - Unknown.
  • 'Othe 1' (Other 1) (s6) - Unknown.
  • 'Other 2' (s7) - Unknown.

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:
  • 'Cost' - The gold cost to respawn at the checkpoint. The checkpoint can only be activated if the player has enough gold.
  • 'Reactivedelay' - The time in seconds until the checkpoint can be activated again after respawning at it.
  • 'Msg_activate' - A message to send when the checkpoint is activated.
  • 'Msg_deactivate' - A message to send when the checkpoint is deactivated from activating another checkpoint. Respawing does not count as deactivating the checkpoint.
  • 'Msg_nogold' - A message to send if the player does not have enough gold to activate the checkpoint.
  • 'Msg_spawn' - A message to send when the player respawns at the 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.
  • 'Portalstate' - The state of the portal, either open or closed (this is a value of '1' for open and '0' for closed).
  • 'Portalcloseddistance' - Distance in game units from the portal when it will automatically close. This is useful when portals should be closed when the player or view is a certain distance away (e.g. a window or a section of level that should be hidden at a particular distance).
Sending an impulse to a user portal will open it with an impulse of '1' or close it with an impulse of '0'.

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:
  • Unless modified from the default number of sides, splines will change tessellation based on the Curved Surface LOD slider in the game's Graphics options. (To change the default subdivisions, select the relating edge point(s) and then use the + / - numpad keys.)
  • Right click and drag vertex points of a spline to retain the angles of the vertex.
  • Press the m key to change the texture mapping style of a spline surface when using the Texture Tool. See the Texture Mapping Types section for more information on the different texture mapping types.
  • An object (such as an engine_path, dynamic, or static) cannot be made up entirety of splines. There must be at minimum one standard brush included.
  • Splines sometimes don't fully block projectiles or the players aiming reticle, allowing the player to aim and possibly shoot through them. If this is an issue, brushes with the *PHYSICAL texture can be used to ensure the spline has proper collision.
  • Splines which are a part of objects (e.g. engine_paths, dynamics, parented objects, etc.) will either be missing collision, or may have issues with collision if animated. Brushes with the *PHYSICAL texture can be used to ensure the spline has proper collision (these brushes can be made to be part of the object in cases where the spline will be animated, e.g. a door).
  • Splines which can be walked on can cause issues with player movement (such as with the bridges in Enclave's Underworld levels). This can often be improved by creating brushes with the *PLAYERPHYSICAL (or similar) texture for the player to walk on which are slightly above the spline's surface. An example of this is practice is shown on the Outland Wastes bridge in the Sandbox level.

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.
  • The lighting mode of a static can be set, including to 'Gouraud' which applies smooth shading across its surface using a light value sampled from the object's origin. This option can also be set on engine_path and dynamic objects, more information can be found in the Lighting Modes for Dynamics & Paths section.
  • Shadows can be disabled on statics by setting the 'light_flags' to '0' (while '1' will enable shadows). This also allows lights placed inside the static object to pass through.
  • Statics can be spawned by using the 'Waitspawn' flag, this can be used to simply make a piece of geometry appear. Statics can also be removed by sending a destroy impulse. Statics can be parented.
  • Statics don't cut adjacent geometry, this can be used as an optimization if it's needed to be ensured that something doesn't split a neighboring face into additional polygons.
Examples of objects such as barrels with the lighting mode set to 'Gouraud' for a smoother appearance are included.

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.
  • 'Light_flare' - How transparent the flare is, lower values mean more transparent while higher mean more opaque.
  • 'Light_flarerange' - The distance the flare will be visible from.
  • 'Light_flaresize' - The size of the flare.
  • 'Light_flaredepthoffset' - The distance that the flare will be visible through geometry from (i.e. geometry within this distance will not block the flare from rendering). If placing the flare inside an object such as a lantern, this value may need to be increased so that it displays correctly.
  • 'Light_flaresize2' - Unknown, may be unused.
  • 'Light_flaredirectional' - If the flare should be fully visible only from the direction the light_flare is pointing. The flare will gradually disappear and be completely invisible when 90 degrees from the direction that the flare points.
  • 'Light_flareabsolute' - Unknown, it does however make the flare less transparent when enabled.

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:
  • Dynamic Light Objects - A dynamic light which can be placed in the level using a dynamic2 object. This object has fields which are similar to a regular light, but rather than being baked into the light map it can be moved around the level by being parented to another object such as an engine_path.
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.)
  • Dynamic Light Strings - Much like particle systems, dynamic lights can also be defined in an object's Model field(s) or in a XRG file using a dynamic light string. This form of dynamic light has controls which allow it to have a 'pulsing' effect, transitioning between different colors and ranges. In Enclave this is notably applied to staves while in darkzones, while a variation is also used for fuses and bombs. An example of a dynamic light string follows:
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.
  • 'LO' - An offset in the X Y Z format of where the dynamic light should be positioned relative to the object which has the dynamic light string (e.g. '0 0 20', values are separated by spaces only).
  • 'C0' / 'C1' - Colors (in hex notation) that the light will transition between.
  • 'CFS' - Affects how quickly the light transitions between colors. Higher numbers result in a faster transition.
  • 'R0' / 'R1' - Ranges that the light will transition between. If glowing or pulsing is wanted these values should differ. Higher range gives the light a brighter appearance towards its center.
  • 'RFS' - Affects how quickly the light transitions between ranges. Higher numbers result in a faster transition.
Note that this style of dynamic light may visibly cull while still in view in certain situations.

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'.
  • 'Auto' - This is the default setting and changes an object from 'Lightmap' to 'Gouraud' when it's activated or begins moving.
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.
  • 'Lightmap' - The object will use only lightmaps. The lighting will remain the same as in the starting position even if the object moves.
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.
  • 'Gouraud' - The object will have an overall smooth light value, the brightness and color of which is sampled from its origin (or attach point). This light value updates as the object moves, effectively offering simplistic dynamic lighting.
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.
  • 'Light minlevel' - Applies a minimum light level which may include an increase in brightness and color to the object while it's in lightmap mode (including when the object is in its initial position when the lighting mode is set to 'Auto').
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.
  • Lightmap Resolution - The number of game units that each pixel on a lightmap (luxel) represents. A lower resolution means a higher detail lightmap and sharper shadows. (Note that using lower resolutions can result in lightmap artifacts with sky light casting and light 'bleed' around splits in geometry or intersecting surfaces.)
  • Lightmap Multisample - The number of times that lightmaps should be sampled. Higher values result in smoother lightmap shadows.
  • Lightgrid Resolution - The size of each node or 'lightgrid' area used for calculating lighting for models (and certain dynamic objects). Lower Lightgrid resolutions mean smaller nodes resulting in higher accuracy for lit models (such as the player character).

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. T
hese 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:
  • 'Velocity'Velocity to be applied to the dynamic in world coordinates (using the X,Y,Z format) when it begins moving. Useful to apply force to a dynamic without using an engine_path. (Note that if using the Velocity field and no other physics objects, ensure that Unstable is also enabled so that the dynamic begins animating when a simulation is run.
  • 'Friction' - The amount of friction that the dynamic will have. A higher value results in more friction making the dynamic less 'slidy'. A value between 0 and 1 (default '0.7').
  • 'Elasticity' - The elasticity of the dynamic. A higher value results in more 'bounce' when the dynamic collides with another object. A value between 0 and 256 (default '0.6').
  • 'Shrink' - Shrinks the dynamic's collision by a set amount in units (default '0.1'). This is used to create a small gap around the dynamic to assist in situations such as having enough enough space between bricks which make up a wall so that they are able to collapse. Number is in Ogier units and cannot be larger than the dynamic's radius.
  • 'NoCollGroup' - Dynamic which have the same name listed in the 'Nocolgroup' field will not collide with one another.
  • 'Unstable' - If enabled, the dynamic will begin moving as soon as the physics simulation is started. If disabled, the dynamic will only begin moving when another object (e.g. another dynamic or an engine_path) with 'Physics' enabled collides with it.
The following features are enabled but do not function correctly:
  • 'Density' - The density (weight) of the dynamic. Note that this field does not appear to function.
The following features work without updating the nodetype file:
  • 'Destorytime' - A delay in seconds before the object will be destroyed / removed ('-1' for never). Useful to remove dynamics which are no longer needed (e.g. remove debris once they are no longer visible to the player).
Sometimes it's useful to record a simulation using dynamics, and then convert them to engine_paths. This can be used to preserve the animation of the dynamics while also applying additional options only available to paths. Paths can always be coverted back into dynamics.

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.

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:
  • 'wait impulse' - Applies a wait impulse to the objanim (e.g. 'wait impulse 1').
  • 'impulse' - Send an impulse to a target object (e.g. 'impulse myTarget 2').
  • 'wait time' - Waits a specified number of seconds (e.g. 'wait time 4.5').
  • 'sound' - Meant to play a sound (e.g. 'sound wd_creak01a'). Doesn't appear to work.
  • 'reset' - Resets the objanim and begins cycling through the list of actions again (e.g. 'reset').

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:
  • Defining the campaign, mission settings, characters, weapons, pickups, effects, prefabs, pre-set objects, etc. (registry templates).
  • Adding text to the menus, briefings, pickups, and adding subtitles or other on-screen messages (string tables and dialogue files).
  • Defining what animations a model should use in different states (animation lists).
  • Setting audio and subtitles to use with video cutscenes (storybook videos).
  • Defining on-screen windows and buttons (windows).
  • Defining sky elements (skies).

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:
  • Comments can be added to any file by prefixing the text with '//'. Blocks of text can be commented using '/*' and '*/'.
  • File paths can go up a directory with a double period '..' and down a directory as normal (if using quotations around a file path, use '\' as an escape character, e.g. to enter a backslash use '\\'). This allows for a path to be given for a different part of the game directory (e.g. if starting in ..\Enclave\Sbz1\Registry, '..\\Models' could be used to move up to the Sbz1 folder and then down into the Models directory).
  • Files can reference established classes from other files. E.g. the *template_pickup class defined in the RpgPickups.xrg file can be referenced from another file, for example, from your own pickups template. The order that the files are given in Sv.xrg doesn't matter (i.e. a file does not need to be listed in any particular position to take advantage of classes specified in a different file).

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.)
  • '*location' - The location entry (i.e. the position on the campaign map) that this scenario is tied to. If no location is given then the level won't show on the map screen (the '*hidefrommap' option may also be used to achieve this).
  • '*type' - Specifies the type of mission that this scenario is. Can be 'mission' (a standard playable level), 'survival' (a survival level where the player faces waves of enemies), or 'cutscene' (a video or in-engine cutscene).
  • '*music_atmosphere' - The sound name of the music that will play in the level. Leaving this blank or omitting it will result in no music being used, or if only one of the two tracks is preferred (atmosphere or battle) then reference a blank sound.
  • '*music_battle' - The sound name of the music that will play when enemies have sight of and are within a certain range of the player.
  • '*character' - Specifies which characters can be selected during the equip screen. Separate characters with the '+' sign. If using the '*noequip' option then only one character should be specified (this will be the character that the player is forced to play as).
  • '*map' - Specifies the WX file used for the level. This is the name of the map file from ..\Enclave\Sbz1\Worlds. Unless an entry is using '*type cutscene', the map setting must be included in its own 'map block' surrounded with curly brackets ( { } ).

Other Optional Settings (Additional settings which may only be
applied for some levels.)
  • '*picmips' - Doesn't appear to have an effect in Enclave's PC version but was likely intended to fine-tune picmips / texture quality on a per-level basis. In the released version picmips are controlled by the game's Graphics settings only.
  • '*backplane' - Increases the draw distance for larger levels (e.g. '*backplane 12000' is used to increase the clip-plane for Ark Moor).
  • '*cutscene_select' - Specifies '*type cutscene' challenge entries which will be loaded before the level. Separate multiple entries with commas to have them play one after another. Cutscenes are unlocked on the map once played unless the cutscene uses *hidefrommap. Note that video based (storybook) cutscenes only play once per campaign when using the select option.
  • '*cutscene_win'Specifies '*type cutscene' challenge entries which will be loaded when successfully completing a level. Separate multiple entries with commas to have them play one after another. Cutscenes are unlocked on the map once played unless the cutscene uses *hidefrommap.
  • '*forcemaxgold' - Specifies a maximum gold that can be collected during the mission (e.g. '*forcemaxgold 100' will limit gold collected to # / 100). This can be used if a map doesn't have gold placed directly but gold can still be earned such as in Highvalley and Naglagard.
  • '*noequip 1' - When enabled the character selection and equipment screens are skipped, taking the player straight into the level when it's selected.
  • '*hidefrommap 1' - When enabled the map won't be displayed on the map screen under its given location. This is often used for cutscenes.
  • '*enemycount 1' - When enabled, a count of killed characters (allies included) is displayed on the screen for levels which use '*type mission'. This setting was used for Highvalley and Naglagard.
  • '*neverfail 1' - When enabled along with '*enemycount', a special mission end message showing a total count of killed characters is displayed. Used for Highvalley and Naglagard.

Cutscene Specific Settings (Settings which may be applied for entries with a mission type of 'cutscene'.)
  • '*cutscene_length' - Specifies the length of the cutscene in seconds.
  • '*cutscene_fadeoutdurration' - Specifies the length of the fade out (fade to black) in seconds which will occur before reaching the end of the '*cutscene_length'.
  • '*cutscene_cameratarget' - Specifies the name of an object to use as a camera when the level loads, usually an engine_path. This object will also be sent an impulse of '1'. Only works if '*cutscene_spawncharacter' is not used. Cutscenes which use this option will be unskippable in-game.
  • '*cutscene_storybookid' - Specifies a storybook XRG file in ..\Enclave\Sbz1\Videos to be used. Storybooks are defined by a XRG file and are used to play a video with subtitles and etc. (such as Enclave's storybook scenes or credits).
  • '*cutscene_spawncharacter 1' - When enabled the character will be spawned (i.e. appear in the world) when the cutscene begins. This can be useful as it allows using the character and equipment that the player has selected for the mission to be used in the 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.)
  • '*award' - Specifies bonuses given for completing the mission. Separate awards using commas, and preface awards using the related type ('challenge:', 'character:', 'gold:', 'item:', or 'special:'). When using 'item:' the character that the item will be awarded to should also be given by including the character name (e.g. 'item:paladin:'). Note that for an item model to display during the awards screen it must exist somewhere within the map. The 'special:' award type can be used to unlock a campaign or exit to the menu using 'quittomenu'.
  • '*specialaward_0' -Specifies bonuses given in relation to 'SpecialAward' messages triggered during the mission. List awards similarly as with the above '*award' option. Not that although different award numbers can be used, Enclave only appears to support a single special award entry.
  • '*survival_enemies' - Specifies a selection of preset enemies to be spawned at info_start_light, and info_start_dark objects. Use with '*type survival' entries. Separate enemies with the '+' sign, and waves using commas. See the Challenge Map Spawns section for more information.
  • '*survival_timelimit' - No known effect, this setting may be left over from an earlier version of Enclave.

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:
  • Pickup Definition (XRG) - Pickup's are defined within a XRG file where additional settings can also be specified. Enclave's pickups are defined in the RpgPickups.xrg file (note that each pickup in this file is based on the *template_pickup class which is in turn based on the *rpgclass pickup class).
  • Model & Related Surfaces (XMD) - A model for the pickup and its related surfaces are stored in a XMD. Some pickups might not require a model, e.g. if they will be given directly to the player at the level's start or are the result of combining other pickups.
  • Textures For Model & GUI (XTC) - Textures for the pickup model as well as for the GUI icon are stored in a XTC.
  • Surfaces For GUI (XTX) - Surfaces for the GUI icon are stored in a XTX. XTX files are also used when compiling the model and textures for the pickup.

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.
  • '*model' - A path to a XMD model to use for the pickup.
  • '*iconsurface'- The name of a surface that will be displayed on the right side of the screen when the pickup is collected by the player, and also over the left side of the interface when using the pickup. Sample surface and texture files can be found in the game, these are prefixed with 'GUI_ICON' (e.g. 'GUI_ICON_KEYRUSTY'). See the Icon Surfaces for Pickups section for more information on creating graphics for pickups.
  • '*itemtype' - An number in hexadecimal format to identify the pickup. More than one pickup with the same itemtype cannot be carried at the same time, if this happens one pickup will be dropped and the other collected. This may be useful if such an interaction is desired.
  • '*sound_pickup' - The name of a sound to be played when the pickup is collected by the player.
  • '*pickupmsg' - A dialogue line to display when the pickup is collected by the player. This is in the format of a dialogue file's name followed by a number, e.g. 'dm02:1' for the first dialogue in the dm02.xrg file.
  • '*dontdestroy 1'- When enabled, the pickup will not be removed from the player's inventory when used (allowing it to be used multiple times). Can be used in a case such as having a single key that unlocks multiple doors.
  • '*combineto'- Used to provide a name of a pickup that this pickup is a component for (e.g. the different bomb parts in Mines of Ungard). Provide the full name of the pickup, e.g. '*combineto pickup_gp_full'.
  • '*combinefrom' - Used to provide a list of itemtype numbers that will be combined to create this pickup. When used in combination with the combineto property, once all required pickups have been collected they will be removed from the player's inventory and replaced with the new item instead (e.g. the bomb in Mines of Ungard). The last pickup collected will not play its related sound or dialogue, and instead the sound and dialogue for the combined pickup will be triggered. Provide the itemtype numbers separated by commas, e.g. '*combinefrom 0x192,0x193,0x194'.
  • '*MSG_ONPICKUP_DONTUSE' - Sends a message when the pickup is collected by the player in the format of "0x110;example;1;". It's generally more versatile to set an OnPickup message on the pickup object in Ogier instead.

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
0 - Release
1 - Follow Me
2 - Pause
3 - Force Follow Me
4 - Death Animation
5 - Animation
6 - Anim Torso
7 - Damage
8 - Fly Follow Me
9 - Force FM Relative
10 - Speak
11 - Spot Character
12 - Add Friend
13 - Remove Friend
14 - Push
15 - Ghost Mode
16 - Teleport Follow Me
17 - Follow Path
18 - Fly FM True
20 - Vector Move
21 - Vector Look
22 - Crouch
23 - Jump
24 - Switch Weapon
25 - Switch Item
26 - Use Weapon
27 - Use Item
28 - Move To Object
29 - Look At Object
30 - Smart Look
31 - Attack
32 - Aim
33 - Force Use Weapon
34 - Force Use Item
35 - Force Shoot
36 - Aggressive
37 - Unspot All
40 - Team
41 - Rank
42 - Awareness
43 - Sight Range
44 - FOV
45 - Sight
46 - Hearing
47 - Reasoning
48 - Skill
49 - Reaction Time
50 - Activation Range
53 - Hearing Range
54 - Idle Max Speed
55 - Health
64 - Survive
65 - Patrol
66 - Guard
67 - Follow
68 - Explore
69 - Hold
70 - Escape
71 - Ambush
72 - Engage
73 - Avoid
74 - Lead
96 - Normal
97 - Coward
98 - Berserker
99   - Sneaker
100 - Passive
110 - Hold Attacks
111 - Release Attacks
112 - Charge
113 - Flank
114 - Riposte
115 - Dodge
116 - Parry
117 - Wait
120 - Special


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'.
  • Hexadecimal Prefix - The prefix of '0x' indicates that the color values are in hexadecimal format.
  • Alpha Value - The alpha or transparency value (only used for objects which support transparency). One or two character value between 'ff' (255) for fully opaque, and '00' (0) for fully transparent.
  • Red Value - The red value of the color. Two character value between 'ff' (255) and '00' (0).
  • Greed Value - The green value of the color. Two character value between 'ff' (255) and '00' (0).
  • Blue Value - The blue value of the color. Two character value between 'ff' (255) and '00' (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.


Sky Listing & Atmospheres

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).
  • Wedges (Triangle Method) - This is a very common method for quickly adding variation to sections of ground, walls, and so on using wedges (the 2 key in Ogier). This is a simple way to add height difference to areas such as an outdoor field, a grassy planter, or a section of wall that has given way to reveal stone underneath. This method is also useful when creating larger terrain expanses that mostly follow a single facing, such as a larger open land area or sea bed.

(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.)
  • Spike Cubes, Spike Wedges, & Spikes  - Commonly used in Enclave are spike cubes (the 8 key in Ogier) complemented by wedges, spikes, and spike wedges (the 2, 3, and 4 keys in Ogier). A rough shape can be built using these brushes which can then have their vertices adjusted to create interesting geometry. A benefit of using spike shapes is that no issues with the resulting brushes becoming concave are present. Spikes and spike wedges can be useful to fill in gaps or connect existing shapes with odd angles. After finalizing the terrain, it may be recommended to merge the brushes using Selection > Merge as this can sometimes reduce and clean up the brushes.
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.)
  • Alternative Editors & 3D Modeling Packages - Some 3rd party editors have additional features that allow for easily shaping brushes into more organic forms, and terrain can also be created using external 3D packages and then exported as brushesThese methods can be very useful for creating advanced or complex shapes. Developing a unique piece of terrain like the Plateau in Enclave is the perfect situation to utilize these types of tools. See the Importing Brushes section for additional information.

(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:

  • From Blender using using io_export_qmap. It may be best to merge geometry exported using these methods to get cleaner brushes once in MAP format. Geometry from Ogier can also be imported to Blender using io_mesh_qmap. Each unit in Blender is equal to one unit in Ogier.
  • From various additional 3D packages such as Maya using OBJ-2-MAP. In this case shapes can be exported to OBJ format from the 3D software and then converted to MAP format. Geometry from Ogier can also be exported to formats which can be loaded into other 3D software using third-party tools.
  • From Sketchup using Valve's VMF Sketchup Tools, and Crafty. Use the Valve VMF Sketchup Tools to export your object(s) from Sketchup, then import them into Crafty where they can then be exported to MAP format. Each inch in Sketchup is equal to one unit in Ogier.
  • From other Quake engine editors which are able to save in MAP format. A useful editor for creating organic shapes such as rock formations is the TrenchBroom editor for Quake. This editor allows for easy sculpting of brushes which can then be exported to MAP format. If you would like to export a level from Ogier to work with in one of these editors, choose File > Save As and then add the extension '.map'.

Surfaces, Textures, Models, Sounds, & Animations

XTX File Introduction
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:
  • XTX files are often easiest to modify simply using a text editor, although Ogier can also load them (however it's possible that some properties might not display in Ogier).
  • Flags keys can be defined by writing out the flag names with multiple flags separated with a '+' (e.g. 'Lighting+Alphacompare'), but you may also see cases where they are listed as a numeric value rather than the flag names (e.g. a value of '2' actually refers to the 'Lighting' flag).
  • Simple XTX files for textures and surfaces can be created by dragging a directory containing TGA files into XWC (the directory may also include subfolders). Two files will be generated, one for compiling any TGA image files in the directory into a XTC (texture) file, and a basic surface file including each of the textures.
  • Comments can be added to any file by prefixing the text with '//'. Blocks of text can be commented using '/*' and '*/'.
  • File paths can go up a directory with a double period '..' and down a directory as normal (if using quotations around a file path, use '\' as an escape character, e.g. to enter a backslash use '\\').

Surfaces & The Surface Editor
(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.
  • 'Offset U+V' (X Offset, Y Offset) - Sets a X / Y offset for the texture in texture units (e.g 'offset u+v, 0, 0.5' can be used to offset the texture by 50% on the Y axis). This is in addition to the surface's Offset property.
  • 'Scale U+V' (X Scale, Y Scale) - Sets a X / Y scale for the texture in texture units, with larger numbers resulting in a smaller scale (e.g. 'scale u+v, 1, 2' results in the the texture being normal on the X axis, but scaled so that 200% of or double of the texture is shown on the Y axis). This is in addition to the surface's Scale property.
  • 'Scroll U+V' (X Velocity, Y Velocity) - Used to scroll a texture on the X / Y axisVelocity is based on texture units per second, meaning that a value of '1.0' would cause a layer to scroll by 100% of the texture's dimension per second (e.g. 'scroll u+v, 1.0, 0'). Use negative numbers to reverse the direction.
  • 'Rotate U+V' (Velocity, Unused, X Origin, Y Origin) - Used to rotate a texture around an origin point (e.g. 'rotate u+v, -0.3, 0, 0.5, 0.5' can be used to rotate a texture counterclockwise from its center-point)Use negative numbers to reverse the rotation's direction, or move the origin to the left of or above the texture. Velocity is based on complete rotations per second, meaning that a value of '1.0' would cause a layer to rotate by 360º per second. The second value's effect is unknown (unused). The rotation's default origin is in the top left of the texture (at 0,0), while this position can be changed using the two origin values to control the X and Y position of the origin. These values are in texture units starting from the top left corner; '0.5, 0.5' is the texture center, while '1, 0.5' would put the origin at 100% the texture's scale on the X axis (i.e. along its right side), and in the middle of the texture on the Y axis.
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.
  • 'GenReflection U+V+W'(No Values) - Used to apply rendered environment / cube maps as reflections to surfaces. Frequently used to provide a simulated reflction to surfaces such as metals or glass. No values are supplied for this operator (e.g. 'GenReflection U+V+W').
  • 'NV20_Fresnel X+Y+Z' (Transparency With Distance, Base Transparency) - Used to simulate a Fresnel effect where reflectivity is increased based on viewing angle (as the viewpoint becomes closer to a surface it becomes brighter, or in the case of reflections more mirror like). This operator is used with Enclave's water surfaces to make the reflection become stronger the closer the camera is to the water's surface. The first value is the change in transparency when the viewpoint moves perpendicularly away from a surface. The higher the value the more transparent the effect becomes when the viewpoint moves away (this value used should generally be 1 or higher, Enclave uses values of 1 to 2.8). The second value acts as an constant overall (additional) transparency between 0 and 1, with 0 being fully opaque and 1 being fully transparent (Enclave uses values of 0 to 0.5). (E.g. 'nv20_fresnel x+y+z, 1.5, 0.25'.)
  • 'NV20_GenEnv X+Y+Z' (Bump Map Strength) - Used in place of GenReflectionfor water surfaces and allows the reflection to be affected by a bump map. The bump map's strength is adjusted with a value between 0 and 1, with 0 being disabled, and 1 being full strength (default is 0.1). This operator can also be used to apply an environment / cube map to non-world geometry in cases where the GenReflection might not display the map's orientation correctly.
Other Operators
Additional operators include ones used for frame animation and applying a wave effect to a surface.
  • 'Textureanim Attrib'(Frames, Time) - Used to animate through texture frames. The first value is the number of frames used for the animation, and the second is the time in seconds it takes for the animation to complete one loop (e.g. in an animation of 16 frames with a time of '16', each frame will be shown for 1 second - lowering the time to '8' means that each frame would be shown of 0.5 seconds). Using a negative number for the time will reverse the animation (note that only positive values will preview in Ogier). Textures should have be suffixed using an underscore followed by the frame number, e.g. '_01', '_02', etc. This operator is used with Enclave's water to animate between 64 frames used for the water's surface, and between 32 frames for the insects in the Mordessa cutscene level.
  • 'GenColorViewN R+G+B' (U/N) - Found only on the Trail_Sword01 surface in Enclave and appears to have been disabled. No known effect and may be depricated. Not used in KotT either.
  • 'Wave X+Y+Z' (Amplitude, Speed, X-Length, Y-Length, Z-Length) - Used to give the appearance of moving surfaces by applying deformation to the vertices using a waveform. Surfaces using the wave operator don't actually move, but only have the appearance of moving.
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:
    • Surfaces with this operator do not display correctly in Ogier, the best way to see an accurate preview is in-game. For quickly testing a single value, moving the camera to point directly along the X, Y, or Z axis in 3D view will display a serviceable preview.
    • Waves rely on the tessellation of the geometry they've been applied to; for the best effect surfaces with this operator should be applied to splines. Spline tessellation will affect the appearance of the wave as wave.
    • Waves are world orientated, this means that rotating geometry using a surface with the operator will not change the wave's orientation. This also means that waves can match across the seams of geometry, e.g. a wave can travel across multiple brushes or splines which use the same surface.
    • While Enclave exclusively uses watertile objects for rippling water and lava, the wave operator can also be used.

Flags

There are a number of flags which can be set either in the Surface Editor or in the XTX file.
  • Each surface file can have BRUSHFLAGS set, these flags will apply to all surfaces in the file.
  • Each surface can have BRUSHFLAGS, MEDIUM_FLAGS, and FLAGS, these flags will apply only to that surface.
  • Each texture layer can have its own FLAGS, these flags will apply only to that layer.
Simple Surfaces
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 Custom Textures
(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.
  • XTC - Compiled texture package, contains the actual images / textures. XTC files can be placed anywhere within the Sbz1 directory.
  • XTX- Texture source and surface (material) information. XTX files come in two types, ones that contain details about the source texture images and their properties which are then compiled into a XTC file, and ones which define surface information and tell the editor and game how to display the texture (see the XTX File Introduction section for more information). When distributing modifications, XTX files used to compile textures, define surfaces in levels, and (optionally) define surfaces in models do not need to be included as their contents are compiled into the related filetypes.

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.
  • Textures should be sized in powers of 2, e.g. 32 x 32, 64 x 64, 128 x 128 pixels and so on. Textures don't need to be square, e.g. a 128 x 512 pixel texture is also acceptable. The maximum texture size in Enclave is 2048 x 2048.
  • TGA files without an alpha channel can be saved as 24 bit files, while TGA files containing an alpha channel must be saved as 32 bit files.
  • Textures use an alpha channel for transparency (provided it is enabled as part of the surface). The darkness of the alpha channel determines the transparency of the corresponding portion of the texture, with black being fully transparent and white being fully opaque. Grey shades can be used can create varying degrees of transparency.

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.

Compiling XTC Files
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\ScreenShotseach 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:
  • _0 - Flip horizontally, then rotate 90' left / counter clockwise.
  • _1 - Flip horizontally, then rename '_3'.
  • _2 - Flip horizontally, rotate 90' right / clockwise, then rename '_1'.
  • _3 - Flip horizontally, rotate 180', then rename '_2'.
  • _4 - Flip horizontally, then rotate 90' left / counter clockwise.
  • _5 - Flip horizontally, then rotate 90' left / counter clockwise.


(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:
  • A camera can be set up to move between locations in a level where environment maps will be generated from, this is useful if generating environment maps multiple times during a level's creation. As a cutscene's letterbox will show in the resulting environment map, it's recommended to instead use an info_intermission parented to a engine_path with the character selection screen hidden.
  • Animated surfaces, skies, or anything which doesn't remain still may not line up between the rendered images. It is recommended to enable 'pause 1' from the console while capturing the environment box snapshot to avoid this issue.
  • A slight artifact may appear along the edges of rendered environment map images. This can be corrected by touching up the image afterwards, but is generally only an issue for high resolution environment / cube maps.

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.
  • Box-Mapping (Red Tint) - The texture is projected along the global x, y, or z axis (whichever is closest to the face's orientation). This is the default mapping type for brushes. While this is the most common mapping type, it results in stretching on angled surfaces or skewing on surfaces which are at odd angles (these are not necessarily bad things, in some case it is not desired however).
  • Plane-Mapping (Green Tint) - The texture's projection at the time of enabling planar mapping will be retained while altering the shape, rather than being based on the closest axis as with Box-Mapping. This can be useful when wanting a texture correctly projected on an angled or rotated surface, however note that the texture's alignment cannot be manually changed after. To ensure a texture is kept correctly oriented while rotating a shape, faces need to be changed to Plane-Mapping and then texture lock used during the rotation.

(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.
  • Box-Mapping (Red Tint) - Similar to Box-Mapping on brushes where the texture is projected along the global x, y, or z axis (whichever is closest to the face's orientation). If applied to a spline face which bends between different axes (e.g. an archway), then this will result in visible texture stretching.
  • Fixed ST-Mapping (Green Tint) - Emulates how Box-Mapping works, but follows the shape of the spline (e.g. will bend to follow the shape of the face, such as a curving arch). The texture will be compressed or stretched in areas where the spline's segments differ in length.
  • ST-Mapping (Blue Tint) - Similar to Fixed ST-Mapping but allows for setting how many pixels of the texture will be drawn on the spline surface. (E.g. with a 512 x 512 texture applied to the surface entering '512' for both the X and Y scale in the Texture tool will have the face completely covered by the texture regardless of its shape.) This can be useful for situations where a spline needs an exact portion of a texture mapped, e.g. in cases where a texture should align perfectly when wrapping around a wheel or arch.

(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 Custom Models
(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
  • Much like surfaces and textures, models are compiled using a XTX file. The difference here is that a model XTX file will often contain the surfaces, mesh(s), and textures all in one (this is done by defining the XTX as a *MULTIXTX). Compiling a model using an XTX in this way also allows surfaces to be compiled into models much like with levels.
  • Supported formats for importing meshes for Enclave include ASE (3D Studio Max ASCII Export file) and LWO (LightWave Object file). The Starbreeze XRG model format was added after Enclave's release and is used by Knights of the Temple and later games. Compiled models are saved in XMD format.
  • Enclave's models were mainly created using 3D Studio Max, while later games utilized the xrgExport plugin for Maya in addition. The released versions of the xrgExport plugin will export to version 2 (plain text) of the XRG format which was used for KotT, and version 3 which was used for Riddick. The KotT GDK includes model examples from that game.
  • If a static model requires collisions, or if it is expected to be re-used often and include elements such as a lightmapped shadow, light sources, etc., then a template entry can be created for it. Templates are often used in Enclave for objects such as sconces, torches, and trees. (See the Creating Templates section and Templates.xrg for examples.)
  • Each unit in Blender is equal to one unit in Ogier.
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.)
  • Enclave uses additional geometry tied to the model's joints as collision meshes for both characters and wieldable pickups (e.g. weapons and shields). KotT uses a similar system for characters only but with simplified collision meshes. To view a collision mesh, open a model in Ogier and select the Solids tickbox, or use the xr_debugflags command in-game. Each individual shape which is part of the collision mesh represents a different area which may be tied to any zone (e.g head, body, arms, etc. - each zone is represented by a color if using the Solids tickbox), and material type (e.g. skin, leather, plate, etc. - each unique zone and material type is represented by a color if using the xr_debugflags command).
  • Weapons and shields in Enclave also include a simple skeleton and collision mesh (such as the sword shown in the header of this section). This mesh is used for collisions when attacking with a weapon, when defending with a shield, and when a held item is targeted by the player or an enemy. Projectiles (such as arrows) do not use collision meshes.
  • Models in Enclave which have a collision mesh are compiled from two ASE files - one containing the model's mesh, and the other containing a skeleton and the collision solids. The skeleton / collision ASE file is specified using *SOURCE_SKELETON in the XMD section of the XTX file (rather than using *SOURCE_MODEL which is for the model mesh). XMD files compiled using this method will include SKELETON and SOURCE_SKELETON keys when viewed with a hex editor.
  • KotT uses simplified collision meshes for characters which are exported as part of a XRG using the xrgExport plugin (both the character and collision mesh are included together in the same exported XRG). These models only need to use the *SOURCE_MODEL key pointing to the XRG file (*SOURCE_SKELETON is not needed).
  • Zones and materials are assigned by naming the relating collision geometry to match the desired type, e.g. 'phystype1' or 'phystype12'.
  • Different zones and materials which can be assigned are found in the game's StringTable file as *SURFACETYPE entries. These are listed with a number value followed by the text that displays when that type is targeted (e.g. '*SURFACETYPE_40 "Body (Plate)"').
Skeletons & Animation
  • Models in Enclave which have a skeleton are compiled from two ASE files. See the note on how these are specified in the collision mesh section above. Also as above, KotT uses xrgExport rather than a separate ASE files.
  • Bows and crossbows in Enclave use vertex animation with a sequence that is 1 second in length (resting position to full draw).
  • Skeletal animation in Enclave uses envelopes. Later games, such as KotT and Riddick changed to using the xrgExport plugin for Maya to export to the proprietary XRG format which also supports vertex weights.
  • With KotT and Riddick, a joint conversion table (found in in the Dev folder within the game's content directory, e.g. ..\Knights Of The Temple\Sbz1\Dev\jointconversion.xrg) is used to assign values to named joints in the model for animated characters.
  • The majority of Enclave's characters utilize a basic bipedal skeleton, often with up to joint 20 used (for simple characters, e.g. those with covered faces or no facial animation), and up to joint 25 used where blinking and jaw movement are needed. More unique characters use a different skeleton (e.g. Vatar, Wraiths, etc.). KotT's basic skeleton added up to joint 37, these additional joints are used for attachment points and more detailed hand and face animation.
  • More detailed characters in Enclave have joints for their eyes, eyelids, and jaw. The eyelids and jaw are controlled automatically, with characters having an automatic blinking animation and jaw movement that matches preprocessed sound files. Blinking can be disabled if required by giving the character a flag of 'noblink'.
  • The ROT value of a joint is the bone number minus one, this value is often used with the *attachrottrack property for weapons, shields, and items. For Enclave common ROT values would be '15' for r_hand, '19' for l_hand, or '18' for l_elbow (used for shields).
  • To be recognized as having a skeleton, an ASE must contain at least one object with a *NODE_PARENT (i.e. two bones).
  • Skeletons are hierarchical with one root joint and all other joints being children of the root.
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:
  • Have a size of 128 pixels wide and 256 pixels high.
  • Have a black background and an alpha channel for transparency.
  • May have a drop shadow to help make them stand out (see Enclave's icons for examples of how drop shadows were used).
  • Should have a surface with the Lighting flag enabled, the Raster Mode set to 'Alphablend', and the Z-Func set to 'Always' (see Surf_GUI.xtx installed with the GDK for examples).

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. G
raphics 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.
  • Graphics for potions and mission pickups always remain at the right side of the screen until used. Potions will always be displayed first below the coin count, followed by any mission pickups.
  • The suggested safe usable area of the image for mission pickups and potions is 98 pixels high with 79 pixels of padding on both the top and the bottom (this allows each graphic to display one below the other without overlapping). Any potion or mission pickup graphic that might be displayed directly below the coin count should include this padding so that it doesn't overlap it (note that at higher resolutions the minimum padding for graphics displayed under the coin count decreases - see details above).
  • When multiple mission pickups are collected, each icon graphic will be shifted 79 pixels downwards from the previous.
  • If creating a larger graphic (such as the dark flag used in Iellon Outpost), keep in mind what other pickups can be collected in the level so that overlap with other graphics can be avoided. Invisible / silent pickups can be used to pad oversized mission pickup images if necessary.

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).
  • If an equipment pickup is collected up by the player, the graphic will briefly appear on the right side of the screen below any potions and mission pickups. Only one of this type of pickup graphic will be displayed at a time, if a second equipment pickup is collected right after, the graphic will be replaced with the more recent one.
  • There are also '*shield_iconsurface' graphics which are not displayed when equipment is picked up, but which are instead shown in the left slot while the item is equipped (this is used with the secondary attack for staves).
  • Equipment pickup graphics sometimes have extra transparency added to portions so that the image appears to go behind the main UI graphic (see Enclave's various GUI_ICON images for examples).

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 suggested top padding for right slot pickups is 49 pixels. Graphics for items that may be collected in a level (i.e. where they will display on the right side of the screen) should include this padding so that they don't overlap the coin count (note that at higher resolutions the minimum padding for graphics displayed under the coin count decreases - see details above).
  • If collected in a level, right slot pickup graphics are shown on the right side of the screen and are shifted 118 pixels downwards from any potion or mission pickups.
Left Slot
  • The suggested top padding for left slot pickups is 98 pixels. Graphics for items that may be collected in a level (i.e. where they will display on the right side of the screen) should include this padding so that they don't overlap the coin count (note that at higher resolutions the minimum padding for graphics displayed under the coin count decreases - see details above).
  • If collected in a level, left slot pickup graphics are shown on the right side of the screen and are shifted 68 pixels downwards from any potion or mission pickups.
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.)

Custom Skies
(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.)
  • '*envbox' - Used to add one or more backgrounds for the sky. An envbox is a large box with a single texture applied to all sides and is most often used as a solid color for the sky's background. An envbox can be configured to only display for the upper half of a sky, allowing for a different image for the top and bottom of the sky (e.g. a starry backdrop for the top half and a solid color for the bottom half).
  • '*box' - Used to add a box within the sky that uses different textures for each of its faces. Textures applied to these layers often have transparency and can be used to show hills, mountains, trees, structures, or other artwork. Often the top texture of the box is left unused as clouds or other graphics are displayed instead, and many skies also have no bottom texture for the box as the player usually never sees the bottom of the sky.
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.
  • '*sky'- Used to add horizontal planes within the sky which can be used for elements such as clouds. Additional sky layers can be used for to add elements such as multi-layered clouds or a moon at different heights, or to blend additional effects surfaces over top of the main sky as with the lightning effects in the Kam-Zara.

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:
  • '*surface' The surface to use for the layer. The surface should exist in the sky's matching XTX file in the skies directory.
  • '*priority' The draw order for the layer. Higher values mean that the layer will be drawn over top of layers with lower priority (e.g. a layer with a priority of '1' will be drawn over any layer that has a priority of '0'). Negative values and decimal values can also be used. If a priority isn't given for a layer then the default of '0' will be used.
  • '*duration' - No known function for Enclave skies, although almost all Enclave and KotT skies use a value of '20'.
  • '*depthfogscale' - No known function for Enclave skies, although many Enclave and KotT sky layers use a value of '0.001'. This may have been intended as a modifier for how depth fog would affect the layer.
  • '*flags' - Can be used with envbox layers. Used to change if an envbox is rendered only for the top half of the sky versus the whole sky.
    • Envbox - For envbox layers a value of '*flags 0' (the default) means that the envbox is will be rendered for the whole sky. A value of '*flags 1' changes this so the envbox will be rendered for the top half of the sky only. An example of this in use is having a sky with stars displayed in only the upper half. If a background for the lower half is also needed, a second envbox can be added with a flags value of '0' and a priority less than the upper half (this results in the second envbox being rendered behind the first upper one).
    • Box - Flag values with box layers do not have a known effect for Enclave skies.
    • Sky - Flag values with sky layers do not have a known effect for Enclave skies, however in the game a value of '1' was given to invisible 'fog' sky layers which do not appear to have an effect in the final game (these layers may be deprecated).
  • '*params' Required for envbox layers and sky layers. Used to change the surface's tiling, or to change the height or apply scrolling to a sky layer.
    • Envbox - When used with envbox layers the first value controls the number of times the surface will be tiled on each side envbox side, while the second value does not have a known use and is optional (however every sky in enclave includes a value of '100000' for the second parameter, e.g. '*params 3, 100000').
    • Box - Params have no known effect for box layers in Enclave skies (however almost every envbox layer in Enclave includes '*params 3, 500000').
    • Sky - For sky layers the first value controls the vertical position of the plane, with positive numbers resulting in the plane being in the top half of the sky, and negative numbers in the bottom half (negative values can be used in cases where where clouds or other effects are needed in the lower half of the sky, e.g. Hagastrom or The Guardian). The second value also relates to the vertical position of the plane, however all height changes can simply be made by changing the first value instead and using '100000' as the second value. Making the second value negative will flip the plane on the X and Y axis (effectively rotating it 180 degrees). Almost every sky layer in Enclave uses '2000, 100000' for the first two values and this is a good set of values to use as a default.
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.

Sound Browser
(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:
  • Opening up a compiled XW file found in ..\Enclave\Sbz1\Worlds using either notepad or a hex editor. You'll be able to see the sounds used in plain text.
  • Extracting the Waves_1.xwc file using Dragon UnPACKer. This will give you the raw sound files used in the game. (But often not the complete sound names used to call them by. Refer to the Prefixes & Suffixes section below for more on this, or open up the compiled XWC files found in ..\Enclave\Sbz1\ using a hex editor and search for the oggs name to see which 'complex sound' uses it.)
  • Loading a level in-game, and then using the 'rs_resources' command to list all currently in use resources. The sounds used in a level will be listed near the top of the resource list. (Use Page Up to scroll up the list. If the list ends, just type 'rs_resources' again to load the next portion.)
In all cases, the command 'cg_playsound soundname' can be used in the console to play a sound. Note that volume and pitch differences are ignored when using this command. Also, if you play a random sound grouping using this, only the first sound in the list will be heard.

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
  • 'lop_soundname' - A looping sound (e.g. 'Stream02.ogg' will be called as 'lop_stream02d')
  • 'rn_soundname' - A randomized sound (e.g. 'rn_birds01a' will play a random sound from 'birds01.ogg' to 'birds04.ogg')
  • 'amb_soundname' - An ambient sound (e.g. 'lop_battle03.ogg' will be played as 'amb_battle03d')

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 Custom Sounds
(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.)


Animation Browser
(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:
  • TTF - A TrueType font file.
  • CFG - A configuration file defining the font settings such as size, style, spacing, etc.
  • MPP - A script for XWC which tells the compiler to load the CFG and TTF, and export the compiled font.
Once all three files have been prepared, drag the MPP file onto XWC. Images of each character in the font will be displayed and a compiled XFC created.

An example set of files are included with this documentation (Gothic.ttf, FontExample.cfg, & FontExample.mpp).


Knights of the Temple Editing

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.)
  • 'SafeRadius' - The radius (in units) that the camera is allowed to move within to avoid the player being directly under the camera. (When the player enters the safe radius the camera is displaced the same distance in the opposite direction.) Some collision detection is done to avoid the camera going through walls, but a good rule of thumb is that the safe radius should not include anything that the camera might collide with.
  • 'Combat.SafeRad' - A safe radius value that takes effect only when the player is in combat.
  • 'SR Sens.Add' - An amount to increase the sensitivity of the camera by when the player is within the Safe Radius. (When the Safe Radius is displacing the camera, it can be good to have an increased sensitivity as the player will most likely be running around close to the camera.)
  • 'FOV' - The field of view of the camera (in degrees). It is recommended that the value does not exceed 140 degrees or go below 20. A value higher than the default makes it appear that the camera is further away than it actually is, while a value lower than default creates a zoom effect and makes it look like the camera is closer than it actually is.
  • 'Combat Offset' - Affects the cameras field of view when the player is in combat (value between 0 and 255, with 0 being the most zoomed in, and 255 being the least). Note that this is not a FOV value, but rather a modifier. All cameras in the games levels use the default value of 64.
  • 'Sensitivity' - The speed that the camera focuses on the player. The higher the value, the faster it will be (maximum value is 255). You may wish to increase this if you know that the player will be moving quickly past, or if the camera is moving. This can also be used on transition splines. Some commonly used values in the games levels are: lower sensitivity 50, 70, 80 | default sensitivity 100 | higher sensitivity 120, 150, 200.
  • 'Freelook LR' - Degrees that the player will be able to free look in the left-right direction (maximum is 180).
  • 'Freelook UD' - Degrees that the player will be able to free look in the up-down direction (maximum is 180).
  • 'LockedYaw' - If checked, the camera will be fixed in the left-right direction that it has in Ogier (it will not be able to focus left or right in-game).
  • 'LockedPitch' - If checked, the camera will be fixed in the up-down direction that it has in Ogier (it will not be able to focus upwards or downwards in-game).
  • 'Trigger' - No functionality, intended to be a place where the related trigger_ext name can be entered as a visual aid for the level designer. (If the camerapos object is not already linked to the trigger, Ogier will draw a line in the 3D view between the camera or rail to the trigger named in this field).
  • 'InterpolateAll' - When checked, any transition to or from this camera will be preformed as an interpolation. If unchecked, any transition to or from this camera will be preformed as a snap. In both cases, this can be overridden by a transition spline or camera names entered in the 'Interpolation' field.
  • 'InterpolTime' - Time (in seconds) for the interpolation. When interpolating between cameras, the time used is the largest 'InterpolTime' value between the previous camera and the new camera.
  • 'InterpolSens' - Sensitivity during the interpolation (maximum is 255). When interpolating between cameras, the sensitivity used is the largest 'InterpolSens' value between the previous camera and the new camera.
  • 'Interpolation' - Target list, takes names of other cameras (e.g. 'cam001'). If this camera has 'InterpolateAll' checked, this list cancels interpolations to these cameras (and uses a snap transition instead). If this camera does not have 'InterpolateAll' checked, this list enables interpolations to these cameras.
  • 'FadeSnap' - Takes the name of another camera that would be changed to using a snap transition. Adds a fade out / in effect to the transition. (This was never used in the game, it may not work properly.)
  • 'Trans. Spline' - Target list, takes names of transition cameras (e.g. 'trans001'). This is a list of cameras to use as transition splines. Note that the camera being transitioned to will also need to have the transition spline in its 'Trans. Spline' field.
  • 'Trans. OneWay' - If checked on a transition spline, then that transition spline is only used in the direction starting with time zero (the beginning of the spline). This means that the transition spline will only be used one way.
  • 'Trans. Time' - This can be set on a transition spline, and is the time (in seconds) for the transition, including the time it takes to interpolate between the cameras and the transition spline (this overrides the splines keyframe length which is used by default).
  • 'Trans. Smooth'This can be set on a transition spline, and will smooth the way the camera enters and leaves that spline. This is best used if the angle or position between the previous, next, and transition spline camera(s) is somewhat large.
  • 'Rail' - The name of a rail to use with this camera (e.g. 'rail001').
  • 'Rail. Heightmap' - On a rail which uses circular mapping or distance mapping, this can be checked to have it also take into account the players vertical distance above or below the rail.
  • 'Rail. Distance Max' - Can be set as a distance (in units) on a camera to set a threshold or tolerance before the camera begins to move along its spline. (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.) This field can also be used on rails with circular or distance mapping. In these cases, value entered is the player distance from the rail (outer radius) where the camera will be at the end of its spline.
  • 'Rail. Distance Min' - Can be set as a distance (in units) on rails with circular or distance mapping. The value entered is the player distance from the rail (inner radius) where the camera will be at the beginning of its spline.
  • 'Rail. Distance' - This key (also shown as 'Rail_Distance') appears to have been used in an older version of the game, later being replaced with the Max and Min fields for Rail Distance. Functions the same as if entering a value into 'Rail. Distance Max'.
  • 'Rail. Dimension' - When checked on a rail, only player movement in the direction of the rail spline will be taken into account. (Any player movement perpendicular to the rail will be ignored.)
  • 'Rail. Speed' - Sets the speed with which a camera will move along its spline (maximum is 255). This has an effect on any camera that uses a spline, with or without a rail.
  • 'Choose focus' - When enabled, causes the camera to focus on the named object entered in the 'Focus' field instead of on the player.


Knights of the Temple Sky Listing
(Below is a list of all available skies included in Knights of the Temple.)