I originally wrote this tutorial for the Valve Developer Community, but considering it's very much so TF2 related, I thought it may be worth it to post it here as well. The tutorial on the VDC can be found here: https://developer.valvesoftware.com/wiki/Team_Fortress_2_Halloween_Bosses
Team Fortress 2 have a variety of halloween bosses that can be used in a map. These are special entities that acts like NPCs. Most of them requires a nav mesh to work.
Ghost
The ghost appears in Harvest Event, Moonshine and a couple of other maps. It's a blue ghost wearing a Ghastly Gibus on it's head. It will roam around the map for a while, stunning any players that come to close to it.
Tutorial
This tutorial will show how to set up a ghost to periodically appear and roam around the map, like in Harvest Event.
1. First, create a func_tracktrain about 48w*48l*80h textured with tools/toolsnodraw where you want the ghost to be when it's inactive. This is what will make the ghost actually move around in the map. In Harvest Event, this is a small room underneath the map. Give it a name. For this tutorial, it will be ghost_train.
2. Set the rest of the train's keyvalues to the following:
Render Mode: Don't Render
Disable Recieving Shadows: Yes
Disable Shadows: Yes
First Stop Target: ghost_path_home
Max Speed (units / second): 90
Change Velocity: Linear blend
Change angles: Ease in/ease out
Distance Between the Wheels: 20
Height above track: 0
Damage on Crush: 1000
Also set the following spawn flags to be on, No User Control, Passable, Is unblockable by player and leave the rest off.
3. Next, create a path_track at the same place as the func_tracktrain and name it ghost_path_home. This will serve as the starting point for the ghost when it's not in use.
4. Create a 255l*256w*72h brush textured with tools/toolstrigger. Make this brush a trigger_stun and name it ghost_stun. Set it's parent to ghost_train. Also set it's Trigger Delay to .5, Duration to 3, Stun Type to Loser State + Controls + Movement and enable Stun Effects. Add the following output to it:
OnStartTouch | ghost_sound_boo | PlaySound | <none> | 0.00
5. Create three ambient_generic entities. Name one of them ghost_sound_boo, and the other two ghost_sound_haunted. Make sure that the Start Silent and Is NOT Looped spawnflags are enabled on all of them. Set the SourceEntityName to ghost_train for all of them.
6. Set ghost_sound_boo's Sound Name to Halloween.GhostBoo, and it's Max Audible Distance to 1944.
7. For one of the ghost_sound_haunting entities, set the Sound Name to Halloween.GhostMoan and the Max Audible Distance to 1352. For the second ghost_sound_haunting, set the Sound Name to Halloween.Haunted and the Max Audible Distance to 1944.
8. Next, create a prop_dynamic, set its model to models/props_halloween/ghost.mdl and position it within the ghost_train. Disable its shadows, set collision to Not Solid and set its Default Animation to idle. Finally, set its parent to ghost_train.
9. Create an info_particle_system slightly underneath the ghost model. Name it ghost_teleport_effect and set its parent to ghost_train. Set its Particle System Name to ghost_appearation.
10. Create a path_track entity where you want the first path the ghost will follow to start 48 units above the ground and name it ghost_path1_0. No other options or spawn flags should be set.
11. Shift-drag ghost_path1_0 to copy it. The previous path_track will automaticly be linked to the new one. Continue doing this until you have track of path_track entities that the ghost will follow. Optionally, you can create a different path named ghost_path2_* (where * is replaced by a number, starting with 0) and clone it to create a separate track that the ghost also can follow.
12. In the first path_track entity in each track, add the following outputs:
OnTeleport | ghost_train | StartForward | <none> | 0.00
OnTeleport | ghost_teleport_effect | Start | <none> | 0.00
OnTeleport | ghost_sound_haunting | PlaySound | <none> | 0.01
And in the last path_track entity in each track, add the following outputs:
OnPass | ghost_train | TeleportToPathTrack | ghost_path_home | 0.00 | No
OnPass | ghost_teleport_effect | Stop | <none> | 0.00 | No
13. Next, create a logic_timer and a logic_case. Name the logic_timer ghost_timer and the logic_case ghost_case. Set Minimum Random Interval on ghost_timer to 14 and Maximum Random Interval to 20. Also enable Use Random Time. Add the following output to it:
OnTimer | ghost_case | PickRandomShuffle | <none> | 0.00
14. Add the following outputs to ghost_case. Replace ghost_path*_0 with whatever you named the first points in each of your tracks respectively.
OnCase01 | ghost_train | TeleportToPathTrack | ghost_path1_0 | 0.00
OnCase02 | ghost_train | TeleportToPathTrack | ghost_path2_0 | 0.00
OnCase03 | ghost_train | TeleportToPathTrack | ghost_path3_0 | 0.00
15. Compile the map and test if everything works. The ghost should occasinally appear and follow the paths until it reaches the end and disappears.
Horseless Headless Horsemann
The Horseless Headless Horsemann was the first Boss NPC to be added to Team Fortress 2. It requires a nav mesh to move around the map. It will remain in the map until its killed and won't disappear on its own. It will also not respawn after dying.
Tutorial
1. Create a point_template somewhere in your map. Name it hhh_template. Set its first template to hhh_entity.
2. Create a new entity at the same place as hhh_template. Change its entity class to headless_hatman. This entity does not exist in the FGD and will be displayed as obsolete. Turn off Smart-Edit and add a keyvalue called targetname with a value off hhh_entity.
3. Create a prop_dynamic somewhere in your map and set its model to models/bots/headless_hatman.mdl. Disable shadows on it, set its solidity to Not Solid and its render mode to Don't render.
4. Place an env_entity_maker where you want the Horseless Headless Horsemann to spawn. Name it hhh_maker and set its template to spawn to hhh_template. To spawn the Horseless Headless Horsemann, send a ForceSpawn input to the hhh_maker entity.
Monoculus
Monoculus (stylised as MONOCULUS!) was the second Halloween Boss to be added to Team Fortress 2. It appears in Eyeaduct, Hellstone and a few other maps. It will shoot eyeballs at players that acts like critical rockets. It will occasionally teleport in the map, leaving behind a swirling purple vortex that takes any players that jumps into it to the underworld.
Monoculus will automaticly disappear after two minutes if it isn't defeated. It requires a nav mesh to work properly.
Tutorial
1. Create a point_template entity somewhere in the map and name it monoculus_template. Set its first template to monoculus_entity.
2. Place a new entity in the same place as monoculus_template and set its classname to eyeball_boss. It will appear as obsolete in Hammer, but it will work in-game. Turn off Smart-edit and add a new keyvalue kalled targetname with its value set to monoculus_entity.
3. Create a prop_dynamic somewhere in the map with its model set to models/props_halloween/halloween_demoeye.mdl. Disable its shadows and set its collisions to Not Solid and its render mode to Dont render.
4. Place a few info_target entities around your map named spawn_boss_alt. Monoculus will occasionally teleport to a randomly selected one of these.
5. Create an env_entity_maker where you want Monoculus to spawn named monoculus_maker. Set its template to spawn to monoculus_template.
To spawn Monoculus, send a ForceSpawn input to monoculus_maker.
Truce
Monoculus and Merasmus can have a truce called when they spawn. During a truce, no players will be allowed to attack any player on the other team. To allow truces to be used in the map, send a SetMapForcedTruceDuringBossFight input with a parameter of 1 to the tf_gamerules entity in the map.
The truce will automaticly start when a boss spawns into the map, and will automaticly end when there are no bosses left in the map, either becuase they are dead, or becuase they have left after a certain amount of time.
tf_gamerules will fire OnTruceStart and OnTruceEnd outputs when the truce starts and ends respectively, allowing you to disable map objectives such as control points and flags during the truce.
Underworld
The '''underworld''' is where players are taken when they jump into the vortex Monoculus leaves behind when it teleports.
The underworld requires the following entities to work:
Merasmus
Merasmus (stylised as MERASMUS! in-game) was the third Halloween boss to be added to Team Fortress 2. He appears in Ghost Fort among other maps.
His attacks includes attacking with his staff, launching players in the air, and using the bombonomicon to summon bombs to launch at players if there is one control point in the map. He requires a nav mesh to work.
Tutorial
1. Create a point_template entity somewhere in the map and name it merasmus_template. Set its first template to merasmus_entity.
2. Place a new entity in the same place as merasmus_template and set its classname to merasmus. It will appear as obsolete in Hammer, but it will work in-game. Turn off Smart-edit and add a new keyvalue kalled targetname with its value set to merasmus_entity.
3. Create a prop_dynamic somewhere in the map with its model set to models/bots/merasmus/merasmus.mdl. Disable its shadows and set its collisions to Not Solid and its render mode to Dont render.
4. Create a brush covering the entire area that you want Merasmus to be able to move around in. Tie it to a func_nav_prefer entity, and name it boss_nav_prefer. Merasmus will stay within this area when he is on the map, and he will ocassionally teleport within it. Players within this volume will also randomly be selected by the bombonomicon to have their heads replaced with bombs. They are instructed to run these to Merasmus to stun him, making him imobile and take more damage for a limited time.
5. Create an env_entity_maker where you want Merasmus to spawn named merasmus_maker. Set its template to spawn to merasmus_template.
To spawn Monoculus, send a ForceSpawn input to merasmus_maker. Merasmus can also have a truce called when he spawns. For more information, see the truce section above.
Skeleton
Skeletons are hostile npcs that will attack any player, or players on the opposite team if summoned belonging to a team. They appear in Helltower, spawning regularly, but can also be sommuned by players to attack the enemy team through spells. There are two types of skeletons, regular skeletons and the skeleton king, with the skeleton king being much more stronger than regular skeletons. Skeletons require a nav mesh to work.
Tutorial
1. Create a couple of tf_zombie_spawner entities around the map. The skeletons will be spawned from these.
2. Set up the tf_zombie_spawners' keyvalues. Skeleton Life Time is how long the skeletons will live before they automaticly disappears. Skeleton Count is how many skeletons this spawner will spawn before it needs to be enabled again. Infinite Spawn means that it will continue to spawn skeletons until it reaches the skeleton count until it's disabled. The Skeleton Type determines wether or not the skeletons spawned will be a normal skeleton, or the skeleton king.
3. To spawn the skeletons, send an Enable input to the tf_zombie_spawner entities.
Team Fortress 2 have a variety of halloween bosses that can be used in a map. These are special entities that acts like NPCs. Most of them requires a nav mesh to work.
Ghost
The ghost appears in Harvest Event, Moonshine and a couple of other maps. It's a blue ghost wearing a Ghastly Gibus on it's head. It will roam around the map for a while, stunning any players that come to close to it.
Tutorial
This tutorial will show how to set up a ghost to periodically appear and roam around the map, like in Harvest Event.
1. First, create a func_tracktrain about 48w*48l*80h textured with tools/toolsnodraw where you want the ghost to be when it's inactive. This is what will make the ghost actually move around in the map. In Harvest Event, this is a small room underneath the map. Give it a name. For this tutorial, it will be ghost_train.
2. Set the rest of the train's keyvalues to the following:
Render Mode: Don't Render
Disable Recieving Shadows: Yes
Disable Shadows: Yes
First Stop Target: ghost_path_home
Max Speed (units / second): 90
Change Velocity: Linear blend
Change angles: Ease in/ease out
Distance Between the Wheels: 20
Height above track: 0
Damage on Crush: 1000
Also set the following spawn flags to be on, No User Control, Passable, Is unblockable by player and leave the rest off.
3. Next, create a path_track at the same place as the func_tracktrain and name it ghost_path_home. This will serve as the starting point for the ghost when it's not in use.
4. Create a 255l*256w*72h brush textured with tools/toolstrigger. Make this brush a trigger_stun and name it ghost_stun. Set it's parent to ghost_train. Also set it's Trigger Delay to .5, Duration to 3, Stun Type to Loser State + Controls + Movement and enable Stun Effects. Add the following output to it:
OnStartTouch | ghost_sound_boo | PlaySound | <none> | 0.00
5. Create three ambient_generic entities. Name one of them ghost_sound_boo, and the other two ghost_sound_haunted. Make sure that the Start Silent and Is NOT Looped spawnflags are enabled on all of them. Set the SourceEntityName to ghost_train for all of them.
6. Set ghost_sound_boo's Sound Name to Halloween.GhostBoo, and it's Max Audible Distance to 1944.
7. For one of the ghost_sound_haunting entities, set the Sound Name to Halloween.GhostMoan and the Max Audible Distance to 1352. For the second ghost_sound_haunting, set the Sound Name to Halloween.Haunted and the Max Audible Distance to 1944.
8. Next, create a prop_dynamic, set its model to models/props_halloween/ghost.mdl and position it within the ghost_train. Disable its shadows, set collision to Not Solid and set its Default Animation to idle. Finally, set its parent to ghost_train.
9. Create an info_particle_system slightly underneath the ghost model. Name it ghost_teleport_effect and set its parent to ghost_train. Set its Particle System Name to ghost_appearation.
10. Create a path_track entity where you want the first path the ghost will follow to start 48 units above the ground and name it ghost_path1_0. No other options or spawn flags should be set.
11. Shift-drag ghost_path1_0 to copy it. The previous path_track will automaticly be linked to the new one. Continue doing this until you have track of path_track entities that the ghost will follow. Optionally, you can create a different path named ghost_path2_* (where * is replaced by a number, starting with 0) and clone it to create a separate track that the ghost also can follow.
12. In the first path_track entity in each track, add the following outputs:
OnTeleport | ghost_train | StartForward | <none> | 0.00
OnTeleport | ghost_teleport_effect | Start | <none> | 0.00
OnTeleport | ghost_sound_haunting | PlaySound | <none> | 0.01
And in the last path_track entity in each track, add the following outputs:
OnPass | ghost_train | TeleportToPathTrack | ghost_path_home | 0.00 | No
OnPass | ghost_teleport_effect | Stop | <none> | 0.00 | No
13. Next, create a logic_timer and a logic_case. Name the logic_timer ghost_timer and the logic_case ghost_case. Set Minimum Random Interval on ghost_timer to 14 and Maximum Random Interval to 20. Also enable Use Random Time. Add the following output to it:
OnTimer | ghost_case | PickRandomShuffle | <none> | 0.00
14. Add the following outputs to ghost_case. Replace ghost_path*_0 with whatever you named the first points in each of your tracks respectively.
OnCase01 | ghost_train | TeleportToPathTrack | ghost_path1_0 | 0.00
OnCase02 | ghost_train | TeleportToPathTrack | ghost_path2_0 | 0.00
OnCase03 | ghost_train | TeleportToPathTrack | ghost_path3_0 | 0.00
15. Compile the map and test if everything works. The ghost should occasinally appear and follow the paths until it reaches the end and disappears.
Horseless Headless Horsemann
The Horseless Headless Horsemann was the first Boss NPC to be added to Team Fortress 2. It requires a nav mesh to move around the map. It will remain in the map until its killed and won't disappear on its own. It will also not respawn after dying.
Tutorial
1. Create a point_template somewhere in your map. Name it hhh_template. Set its first template to hhh_entity.
2. Create a new entity at the same place as hhh_template. Change its entity class to headless_hatman. This entity does not exist in the FGD and will be displayed as obsolete. Turn off Smart-Edit and add a keyvalue called targetname with a value off hhh_entity.
3. Create a prop_dynamic somewhere in your map and set its model to models/bots/headless_hatman.mdl. Disable shadows on it, set its solidity to Not Solid and its render mode to Don't render.
4. Place an env_entity_maker where you want the Horseless Headless Horsemann to spawn. Name it hhh_maker and set its template to spawn to hhh_template. To spawn the Horseless Headless Horsemann, send a ForceSpawn input to the hhh_maker entity.
Monoculus
Monoculus (stylised as MONOCULUS!) was the second Halloween Boss to be added to Team Fortress 2. It appears in Eyeaduct, Hellstone and a few other maps. It will shoot eyeballs at players that acts like critical rockets. It will occasionally teleport in the map, leaving behind a swirling purple vortex that takes any players that jumps into it to the underworld.
Monoculus will automaticly disappear after two minutes if it isn't defeated. It requires a nav mesh to work properly.
Tutorial
1. Create a point_template entity somewhere in the map and name it monoculus_template. Set its first template to monoculus_entity.
2. Place a new entity in the same place as monoculus_template and set its classname to eyeball_boss. It will appear as obsolete in Hammer, but it will work in-game. Turn off Smart-edit and add a new keyvalue kalled targetname with its value set to monoculus_entity.
3. Create a prop_dynamic somewhere in the map with its model set to models/props_halloween/halloween_demoeye.mdl. Disable its shadows and set its collisions to Not Solid and its render mode to Dont render.
4. Place a few info_target entities around your map named spawn_boss_alt. Monoculus will occasionally teleport to a randomly selected one of these.
5. Create an env_entity_maker where you want Monoculus to spawn named monoculus_maker. Set its template to spawn to monoculus_template.
To spawn Monoculus, send a ForceSpawn input to monoculus_maker.
Truce
Monoculus and Merasmus can have a truce called when they spawn. During a truce, no players will be allowed to attack any player on the other team. To allow truces to be used in the map, send a SetMapForcedTruceDuringBossFight input with a parameter of 1 to the tf_gamerules entity in the map.
The truce will automaticly start when a boss spawns into the map, and will automaticly end when there are no bosses left in the map, either becuase they are dead, or becuase they have left after a certain amount of time.
tf_gamerules will fire OnTruceStart and OnTruceEnd outputs when the truce starts and ends respectively, allowing you to disable map objectives such as control points and flags during the truce.
Underworld
The '''underworld''' is where players are taken when they jump into the vortex Monoculus leaves behind when it teleports.
The underworld requires the following entities to work:
- A few info_target entities named spawn_purgatory. These are where the players will teleport after jumping into Monoculus's teleport vortex.
- A trigger_add_tf_player_condition covering the entire underworld with its condition set to 108 and duration set to -1. This will add a temporary übercharge and heal the player to full health when entered, and give the player a critboost, speedboost and übercharge after leaving the underworld. Damage done to Monoculus while under these effects will temporarily stun it.
- A trigger_hurt covering the underworld, with its damage type set to Bullet, and its damage per second set to 9.
Merasmus
Merasmus (stylised as MERASMUS! in-game) was the third Halloween boss to be added to Team Fortress 2. He appears in Ghost Fort among other maps.
His attacks includes attacking with his staff, launching players in the air, and using the bombonomicon to summon bombs to launch at players if there is one control point in the map. He requires a nav mesh to work.
Tutorial
1. Create a point_template entity somewhere in the map and name it merasmus_template. Set its first template to merasmus_entity.
2. Place a new entity in the same place as merasmus_template and set its classname to merasmus. It will appear as obsolete in Hammer, but it will work in-game. Turn off Smart-edit and add a new keyvalue kalled targetname with its value set to merasmus_entity.
3. Create a prop_dynamic somewhere in the map with its model set to models/bots/merasmus/merasmus.mdl. Disable its shadows and set its collisions to Not Solid and its render mode to Dont render.
4. Create a brush covering the entire area that you want Merasmus to be able to move around in. Tie it to a func_nav_prefer entity, and name it boss_nav_prefer. Merasmus will stay within this area when he is on the map, and he will ocassionally teleport within it. Players within this volume will also randomly be selected by the bombonomicon to have their heads replaced with bombs. They are instructed to run these to Merasmus to stun him, making him imobile and take more damage for a limited time.
5. Create an env_entity_maker where you want Merasmus to spawn named merasmus_maker. Set its template to spawn to merasmus_template.
To spawn Monoculus, send a ForceSpawn input to merasmus_maker. Merasmus can also have a truce called when he spawns. For more information, see the truce section above.
Skeleton
Skeletons are hostile npcs that will attack any player, or players on the opposite team if summoned belonging to a team. They appear in Helltower, spawning regularly, but can also be sommuned by players to attack the enemy team through spells. There are two types of skeletons, regular skeletons and the skeleton king, with the skeleton king being much more stronger than regular skeletons. Skeletons require a nav mesh to work.
Tutorial
1. Create a couple of tf_zombie_spawner entities around the map. The skeletons will be spawned from these.
2. Set up the tf_zombie_spawners' keyvalues. Skeleton Life Time is how long the skeletons will live before they automaticly disappears. Skeleton Count is how many skeletons this spawner will spawn before it needs to be enabled again. Infinite Spawn means that it will continue to spawn skeletons until it reaches the skeleton count until it's disabled. The Skeleton Type determines wether or not the skeletons spawned will be a normal skeleton, or the skeleton king.
3. To spawn the skeletons, send an Enable input to the tf_zombie_spawner entities.