Mapping guide
Maps for Source engine games like Gmod, and therefore also TTT maps, are made using the Hammer map editor. You can find guides about Hammer basics elsewhere, this page will only cover TTT-specific stuff and assumes some Hammer familiarity.
Resources
TTT includes an FGD file you will need, and a couple of simple example maps showing how certain entities can be used. If you find your Gmod directory, you can open \garrysmod\gamemodes\terrortown\
which will contain ttt.fgd
. There you can also find the mapexamples
directory that contains the example VMF files.
Configuring Hammer
Garry’s Mod runs on the Orange Box version of the engine, so you will probably want to select Episode 2 in the Source SDK launcher, so that you get the new version of Hammer etc. If Garry’s Mod is in the list of configurations, that’s good too of course.
As stated above TTT has an FGD that you can add in your Hammer options. It will add all TTT weapons (entities start with weapon_zm_*
or weapon_ttt_*
), ammo, and special entities (which start with ttt_*
) to the entity list.
Note that TTT requires CS:S, but does not (by default) require Episode 2. Hence you should not use Ep2 materials and models unless you know all your players will have it, but you can safely use CS:S stuff if you want.
From this point on, you can make a map as any other. The basics you’ll need to include are spawnpoints, and most likely a ttt_map_settings
entity. These and other entities are discussed below, after we cover how you can test your map.
Configuring the game for testing by yourself
Once you have compiled a map, you can install it as any other Gmod map (in \garrysmod\maps
), and start a local TTT game on it.
TTT assumes you want to play with multiple people, so it will start out in “waiting for players” mode. Use the following commands in the console (enable it if you haven’t) to make it playable by yourself:
ttt_debug_preventwin 1
ttt_minimum_players 1
The first convar prevents a round from ending. You need this because with just you playing it looks like you’ve won immediately (seeing as no one else is alive). The second convar sets the minimum required players to one, so that a round will start. This is necessary because things like entity replacement do not occur until a round starts. This convar will be stored for future games once you’ve set it once (unlike the first convar).
If you manage to kill yourself, force a respawn as follows:
ttt_force_terror
This will respawn you (as an innocent).
If for some reason you need to be the traitor but you’re not, use ttt_force_traitor
. There is an equivalent command to become a detective: ttt_force_detective
.
Spawnpoints
The spawnpoint entity people tend to use is info_player_deathmatch
. Technically other spawn ents will work equally well (for example CS:S ones), but there’s little reason to use them over that one. Do not use info_player_start
, though, as it can cause issues.
Although TTT is intended for 16 to 18 players, many servers have a higher limit, so you might want to consider adding a bunch of extra spawns. Something to consider is that when there are more players than there are free spawnpoints, TTT will dynamically create temporary spawnpoints next to existing spawns. As a consequence, spawns are best placed in areas where there is some space directly around them, so that when a server runs at a higher playercount than you expect, TTT has room to do its thing.
Entities
The following TTT entities exist, besides the weapon and ammo ones:
ttt_map_settings
This entity can be used to customize certain TTT gameplay aspects. It is a point entity you place in your map, and then configure some settings on that will take effect in-game. It should be straightforward as long as you have the FGD loaded, just place it and take a look.
These are the things you can currently configure:
- Enable/disable the crowbar forcibly unlocking doors you may have scripted to open only under specific circumstances.
- Enable/disable the crowbar doing the same with buttons.
- Enable/disable the crowbar forcing “movelinear” entities to open.
- Specify the player model all players will use instead of the default randomly picked one. Must be a proper path to the model, like “models/player/phoenix.mdl”. You can check the garrysmod GCF for more playermodels. To use one of the other ones TTT uses at random by default, use the path I just gave and replace “phoenix” with “arctic”, “guerilla”, or “leet”.
- Enable/disable whether spectators can possess props that have a targetname set (defaults to off)
The entity also fires outputs at certain points in a TTT round:
- MapSettingsSpawned
- RoundPreparation
- RoundStart
- RoundEnd (has an argument of 2 = traitors win, 3 = innocent win, 4 = timelimit)
ttt_logic_role
This entity can be used to test the role (traitor/detective/innocent) of the !activator. You can use any trigger to send an input to a ttt_logic_role. It will then fire its OnPass output if the player is of the role you specified in the entity, and OnFail if it is not.
The ttt_traitorcheck.vmf example map shows one way to use this entity. You should use it instead of ttt_traitor_check, which is older, less versatile and harder to get working.
ttt_traitor_button
This button works much like regular buttons when it comes to entity I/O. However, it is shown only on the HUD of traitors, who can simply aim at it and press their +use key to press it. Hence, it does not need a world model. Traitors can press it from a distance of up to 1024 units by default, but you can customize this through the “Usable Range” entity property.
Unlike regular buttons that have a ttt_logic_role or ttt_traitor_check to prevent innocent players from using them, these traitor buttons are not even visible to innocents. This means they can also not be used as an improvised traitor testing device where innocents tell a player to press the button to see if a door opens.
The ttt_traitorcheck.vmf and ttt_traps.vmf examples have a traitor button in them.
ttt_traitor_check
The ttt_traitor_check entity is a brush-based entity meant for detecting traitors within its bounds. You will almost always want to use ttt_logic_role with a standard trigger_* instead of this entity.
If you are sure you want to use this one, send it a “CheckForTraitor” input and it will in turn send a “TraitorsFound” output, that will have the number of traitors whose feet are inside the brush as parameter. You can use it to with a logic_compare and such to do things depending on this value.
The ttt_traitorcheck.vmf example map has a setup where a player presses a button and a sprite turns red or green depending on if there is a traitor or only innocents near the button.
ttt_weapon_check
Use ttt_weapon_check for weapon/metal detectors and such. It checks if there is a player carrying a certain weapon or weapon type inside it. It works much like traitor_check with a few differences. It has two kinds of inputs: “CheckForType” and “CheckForClass”. The last one takes a string as parameter, and checks only for the weapon named by that string (it should be a weapon entity name, such as weapon_zm_shotgun
or weapon_ttt_c4
).
CheckForType checks on a certain type of weapon, which you specify by setting the input parameter to one of the following:
1 = Primary weapons (shotgun etc)
2 = Secondary weapons (pistol/deagle)
3 = Traitor equipment (weapons and items, so c4 and body armor will trigger it)
4 = Grenades
5 = Any of the above (so any weapon the player did not spawn with)
When the entity receives one of these inputs, it will see if there is a player inside it carrying a weapon of the requested type/class. If yes, it fires the output WeaponsFound with “1” as parameter. If not, the parameter will be “0”.
The ttt_weapon_check.vmf example map has a setup similar to the ttt_traitor_check example map, with one button testing for primary weapons, and another for C4 specifically.
ttt_win
You can use this entity in order to force a win for the traitors or the innocent. Send it a “TraitorWin” input or an “InnocentWin” input, they should be self-explanatory.
I recommend you keep your objectives very simple and straightforward, or find a good way to explain them.
ttt_random_ammo
Turns into a random type of ammo when it spawns.
ttt_random_weapon
Turns into a random type of weapon when it spawns. You can set it to spawn some boxes of the matching ammo type.
ttt_game_text
Similar to standard game_text, but shows a message in the TTT message area in the top right. You can specify which types of player to send it to (!activator, everyone, traitors, etc), as well as the colour it should have. I recommend you use a colour that is not white, so that players are more likely to notice it and know it is the map telling them something rather than a standard gamemode message.
ttt_damageowner
Lets you attribute the damage dealt by an entity (like a trigger_hurt) to a specific player. Useful for making traps give score/karma to their user, as well as showing up properly in the round report.
You set the entity of which you want to attribute the damage as the “Target Entity” property of the ttt_damageowner entity. Then you fire the SetActivatorAsDamageOwner input on the ttt_damageowner, and whoever is the !activator of that input chain will be the player responsible for the damage done by the Target Entity.
To change who is responsible for the damage, fire the SetActivatorAsDamageOwner output again with a different activator (ie. when someone else presses the button enabling the trap), or fire ClearDamageOwner.
The ttt_traps.vmf example map has a number of trap configurations that correctly attribute damage.
ttt_credit_adjust
This entity can be used to give or take credits to/from a player. Upon receiving a TakeCredits input, it will attempt to take the number of credits you specify in the entity from the !activator. If this number is negative, it will give the credits instead. The output OnSuccess is fired if giving/taking the credits was successful, while OnFail is fired if the player had insufficient credits (only occurs when taking credits).
ttt_spectator_spawn
Spectators will be moved to this entity as soon as they stop viewing their ragdoll. If more than one of these exists, a random one is used. The angles of this entity determine the eye angles of the player, ie. where they are facing after being moved here.
This entity is completely optional, and only useful if you have some sort of special spectator area in your map.