File List
File Link | Description |
---|---|
Multiple Skies Example Blend | A blend file showcasing how to use multiple skies in a scene. |
Portals Example Blend | A blend file showcasing how to use the special +portal material in a level. |
Instance Geometry Example Blend | A blend file showcasing how to use the instance geometry in a level. |
Water Visual Example Blend | A blend file showcasing how to create water in a level. |
Water Physical Example Blend | A blend file showcasing how to create water in a structure-design file. |
Design Surfaces Example Blend | A blend file showcasing how to create barriers in a structure-design file. |
Seams Example Blend | A compilation of blend files showcasing how to create seams to connect bsps. |
Multiple skies
It's possible to use multiple skies in your level by adding a digit to the end of your +sky
material. If we wanted three skies in our level for example we would have the following:
+sky0
+sky1
+sky2
It's important that the digit at the end of the material starts at zero. The digit will be used as an index by the cluster to get a sky tag reference from the scenario skies tag block. You'll also have to make sure that a cluster does not use more than one sky or you will get an error on import.
If you were not aware, a cluster is a section of a level divided by a portal. In the case of the provided blend file above there are 7 clusters. If a map has no portals then there is one cluster. Be sure to also prevent multiple skies from being able to be seen by the player at once, or else the player will see a sudden transition between them when moving between clusters. Tool will output a warning if a sky can see another sky.
Avoid using trailing digits on non-sky material names, or you'll get tool warnings about duplicate shaders, and avoid numbers in shader tag names. Use letters instead if you need to make variants.
Weather polyhedra
You may be aware of weather polyhedra from previous games. This was a feature that allowed map designers to prevent weather effects from appearing in a certain section of level. I regret to inform you that this is not a feature in Halo 3. It seems to have been deprecated during the switch from weather tags to atmosphere parameters.
Multiple BSPs
It is common for singleplayer maps to have multiple BSPs. This helps manage game resources and avoid BSP limits for long missions. To accomplish this, place multiple ASS
files in the same structure
folder for the level. Each ASS will be compiled into it's own unique BSP tag for your scenario to use. Do not attempt to use multiple BSPs in an MP scenario.
Object Symbols
Object symbols are characters that go at the start of the object name.
Symbol | Description |
---|---|
# | Marker object prefix. Used to tell the JMS exporter that this object is to be treated as a marker. If used in an ASS file then tool will use the object for direction in structure-design files. |
! | World node object prefix. Used to tell the JMI exporter that this object is to be treated as a world node. |
% | Instanced object prefix. Used to tell the ASS exporter that this object is to be treated as instance geo. |
@ | Collision object prefix. Used to tell the JMI exporter that the object is to be written to a JMS containing only collision geometry. |
$ | Physics object prefix. Used to tell the JMI exporter that the object is to be written to a JMS containing only physics geometry. |
~ | Water group object prefix. If used in an ASS file then tool will use the object to generate water in a structure-design file. |
Some symbols are specific when used in conjunction with instanced geometry
Symbol | Description |
---|---|
+ | Static pathfinding prefix. Used in conjunction with the instance object prefix to tell tool how to handle pathfinding for this object. In the case of this symbol it will generate pathfinding for the mesh. |
- | Not pathfinding prefix. Used in conjunction with the instance object prefix to tell tool how to handle pathfinding for this object. In the case of this symbol ignore the object while generating the pathfinding mesh. |
? | Light object per vertex. Used in conjunction with the instance object prefix to tell tool how to handle lighting for this object. In the case of this symbol it will set the geo to use per vertex for lightmap policy. |
! | Light object per pixel. Used in conjunction with the instance object prefix to tell tool how to handle lighting for this object. In the case of this symbol it will set the geo to use per pixel for lightmap policy. |
* | Render only prefix. Used in conjunction with the instance object prefix to tell tool how this object should be treated. In the case of this symbol it will set the geo to use only render geometry. |
& | Chops portals prefix. Used in conjunction with the instance object prefix to tell tool how this object should be treated. In the case of this symbol it will set the geo to chop portals (as regular bsp geometry does). |
^ | Does not block AOE prefix. Used in conjunction with the instance object prefix to tell tool how this object should be treated. In the case of this symbol it will set the geo to not block area of effect damage. |
< | Excluded from lightprobes prefix. Used in conjunction with the instance object prefix to tell tool how this object should be treated. In the case of this symbol it will set the geo to be excluded from lightprobes. |
| | Decal spacing prefix. Used in conjunction with the instance object prefix to tell tool how this object should be treated. In the case of this symbol it will set the geo to use decal spacing. |
@ | Instanced Geometry collision prefix. Used as a prefix for a child object of an instanced geometry object. In the case of this symbol it will override the collision of the parent object with its own collision mesh (note that you do not need the % prefix when using this). |
Portals
Portals are plane objects that cut through geometry to divide it into sections called clusters. This is either usually to enhance performance or section off a part of a level in order to set specific environment sounds or effects in that area. Portals are defined by the special material name +portal
. Portals can also intersect without needing to be connected unlike CE. This makes it extremely simple to just generate a set of grid portals to quickly test high poly geometry before making better portals. See the Portals Example Blend
and Materials Overview for examples.
Instance Geometry
Instance geometry is geometry that is linked and duplicated to cut down on used memory. It's also a decent way to avoid having to stich in geometry into your BSP. Think of it like scenery objects with lightmaps. The ASS exporter checks if an object is an instance by seeing if it has linked mesh data. They should also have the %
symbol at the start of their object names. The only unique property that instance can have is uniform scale. All instances will otherwise look the same. See the Instance Geometry Example Blend
for an example on how to use this.
Object data in Blender can be linked with the Ctrl + L hotkeys.
Infinite Water Plane
You may be aware of infinite water planes from Halo 2. This was a feature that allowed map designers to set an infinite water plane at a certain height in the level. I regret to inform you that this is not a feature in Halo 3. It seems to have been deprecated.
XREFs
Water
We will be using the end result of the level guide for this example but you can look at the completed files in the file list for the items listed here.
Water in Halo 3 is handled by two different files. The ASS file located in the level's structure
sub directory will handle the visual aspects of our water plane while out of water. The ASS file located in the level's structure-design
sub directory will handle things related to how our water region interacts with objects in the world. This includes actions such as objects floating on the surface and screen effects while the game camera is inside a water region. Lets go over setting up the visual aspect in the structure
ASS file first.
Visual
Starting with the visual aspects of our water, we will create a simple plane in our example level to represent the water in our game world. Do not worry about following the sealed world rules for now. We will be naming our new plane object water_plane
and give it a Z height of -400 units. The plane should have a scale of 1000
units on the XYZ axis. We will also be giving it the following material name.
river riverworld_water_rough'
There are three aspects to this material name
- river - This is the shader_
collection prefix that will be used to find the material name that follows after the space. In the case of the river prefix, that will tell tool to search for shaders in levels\multi\riverworld
as set by the shader_collections.txt file in the tags\levels
directory. - riverworld_
water_ rough - The material name that will be used for the water on our level. '
- This is a material symbol that lets tool know we are intending for this surface to be used as a water surface. This will help satisfy the sealed world rules for this mesh.
Once that is done go ahead and give the water plane four UV channels. The purpose of each UV channel are as follows:
- UV_0 - Used by the visual part of our mesh for displaying the texture.
- UV_1 - Used to mask the color of our water. Move your UV coordinates in the positive Y direction to make the water color more pronounced.
- UV_2 - ???
- UV_3 - ???
This ends everything we need to create in our structure
ASS file. We can export our current scene and move on the the structure-design
ASS file in the physical section.
Physical
Now lets handle our water regions properly. We will start by creating another plane in our example level to represent the water in our game world. Give it a Z height of -400 units and set the scale to 1000
units on the XYZ axis. Go into edit mode and extrude the object down around -100
units so that it will reach the bottom of our example level. Make sure that the normals are facing outside/away from the center of our object. We will also be giving it the following object name.
~water_physics00
There are two aspects to this material name
~
- This symbol tells tool to treat the mesh as a water group- water_
physics00 - Just the name for our object. Call it whatever you would like. We will be using water_ physics00 in this example.
Now that we've created a water region lets add another object to define the direction objects will flow in. You can skip this step if you do not want there to be direction in a body of water you make. Add an Arrows
object found under the Empty
list in the Add
menu. Set the scale on this object to 600.0 units on the XYZ axis. We will also be giving it the following object name.
#water_direction00
#
- This symbol tells tool to use the object rotation for direction.- water_
direction00 - Just the name for our object. Call it whatever you would like. We will be using water_ direction00 in this example.
We will be using Ctrl + P with both #water_direction00
and ~water_physics00
selected with ~water_physics00
being the active object in our scene. This will set #water_direction00
to use ~water_physics00
as it's parent object. Now we can rotate our #water_direction00
to define the direction that objects will flow in with the X axis being forward in this case. Lets rotate it 90 degrees.
Now we can export these assets to an ASS file. The ass file we create from the meshes we created must go in a different subdirectory from the assets created in the Visuals
section. The structure-design
command will also be used instead of the standard structure
command to compile our ASS file.
Once the ASS file is compiled, the water_sky_atm_parameters
tag under the Underwater Settings
block to change the Murkiness
and Fog Color
. This is the color the player sees beneath the surface of the water. Additionally, the sky_atm_parameters
tag is referenced in the scenario
tag under the Screen Effect References
block in the atmospheric
slot.
Design surfaces
Design surfaces are special surfaces that can be used to keep players in a set play space. These barriers do not affect AI and do not need to follow the sealed world rules. They can also be enabled or disabled with the script function soft_ceiling_enable
.
There are three different types of surfaces.
+soft_ceiling
+soft_kill
+slip_surface
The following HS commands can be used to debug these.
debug_structure_soft_ceilings 1
debug_structure_soft_kill 1
debug_structure_slip_surfaces 1
Soft ceilings
Objects that are set as soft ceilings will produce invisible barriers that prevent users from walking past the facing normal. If a user somehow ends up on the other side of one then walking near one will allow the user back into the play space. The format for these are as follows:
+soft_ceiling:main_barrier
There are four aspects to this name so lets break this down.
+
- Material symbol that lets tool know this is a special material.- soft_
ceiling - The type of barrier we wish to use for surfaces that have this material assigned. :
- The separator between the barrier type and the name.- main_
barrier - The name for our barrier. This is what the user will give to the soft_ceiling_enable
script function to disable it.
Soft kill
Objects that are set as soft kill will produce invisible regions that kill the user once they enter it for longer than a second. The format for these are as follows:
+soft_kill:death_barrier
There are four aspects to this name so lets break this down.
+
- Material symbol that lets tool know this is a special material.- soft_kill - The type of barrier we wish to use for surfaces that have this material assigned.
:
- The separator between the barrier type and the name.- death_
barrier - The name for our barrier. This is what the user will give to the soft_ceiling_enable
script function to disable it.
Slip surface
Objects that are set as slip surface will produce surfaces that cause players to slide back. This will prevent users from walking past the map boundary without making it too obvious that there is an invisible wall. The facing angle for faces marked as slip surfaces should be greater than 35 degrees. Tool will throw out an error otherwise and the surface will be disabled. The format for these are as follows:
+slip_surface:slip_and_slide
There are four aspects to this name so lets break this down.
+
- Material symbol that lets tool know this is a special material.- slip_
surface - The type of barrier we wish to use for surfaces that have this material assigned. :
- The separator between the barrier type and the name.- death_
barrier - The name for our barrier. This is what the user will give to the soft_ceiling_enable
script function to disable it.
Seams
Seams connect BSPs together. Surfaces that are set as a seam surface will connect to another seam surface if the two surfaces are identical (including triangulation) and occupy the same space. The easiest way to do this in Blender is to use the magnetic snapping tool set to edge mode and sliding the surfaces together on an axis. A seam can only connect two BSPs.
A seam can be made by creating a material called +seam:example_seams_1
+
- Material symbol that lets tool know this is a special material.- seam - Tells Tool that this is a seam surface with this material assigned.
:
- The separator between the seam and the name.- example_
seams_ 1 - The name for our seam. This is what Tool will use to identify the seams in a bsp. It is usually the name of the bsp.
Once we have multiple bsps that seamed together properly, you can use Tool's structure
command to import the individual .ASS files for each bsp.
Once all the .ASS files are imported, you can run structure-seams levels\multi\example_seams
to create the example_seams.structure_seams
file that will later be referenced in the scenario
tag.
After the example_seams.structure_seams
file is created, you might be asked to reimport the .ASS files. This varies depending on what bsps have seams. Reimport those bsps and continue.
Now the example_seams.structure_seams
file can be referenced in the scenario under the Structure Bsps
block.
Zone Sets
Now that seams have been added to the scenario, you must create zone sets
. Zone sets specify which bsps will be loaded as a player progresses and can be triggered through scripting and trigger volumes. For example, if the player starts in zone_set_a
that has bsp_j
and bsp_k
loaded, and the player progresses to zone_set_b
that has bsp_k
and bsp_l
loaded, zone_set_a
will switch to zone_set_b
. There are also zone sets that have all bsps marked to be loaded at once for debugging purposes.
Create a zone set called all
and check all the bsp zone flags
. Save your scenario and open it up in Sapien.
In Sapien, zone sets can be switched by pressing Ctrl+B
or going to Edit > Switch Zone Set...
Acknowledgements
Thanks to the following individuals for their research or contributions to this topic:
- Crisp (Adding additional information on instanced geometry)
- General_101 (Writing this guide)
- MercyMoon (Writing the Seams sections)