Building TTT Maps: Entities, Spawns and Testing in GMod
Building TTT maps: which spawns and weapons TTT picks up automatically, what each ttt_ entity does, how to load ttt.fgd in Hammer and test rounds alone.
Technically, a map for Trouble in Terrorist Town only needs enough info_player_deathmatch spawn points plus weapons and ammo. Everything else is optional: TTT ships its own FGD file with ttt_ entities that let you build traitor buttons, role checks, traps with correct kill attribution and round events. Two quirks matter: TTT resets the map completely before every round, and during the preparation phase every player counts as innocent.
What TTT takes from a map automatically
Spawns. Besides info_player_deathmatch, TTT uses info_player_terrorist, info_player_counterterrorist, info_player_combine, info_player_rebel, info_player_axis, info_player_allies, info_player_teamspawn and gmod_player_start. The code only falls back to info_player_start when none of these exist, and the TTT documentation advises against it. The spawn classes of other gamemodes are covered in spawn points and gamemode entities.
Weapons and ammo. When it prepares a round, TTT replaces the weapon and item entities from Half-Life 2 with its own. An excerpt from the table in the TTT code:
| Entity in the map | Becomes in TTT |
|---|---|
weapon_smg1 | weapon_zm_mac10 |
weapon_shotgun | weapon_zm_shotgun |
item_healthkit | weapon_zm_shotgun |
The stock maps from Counter-Strike: Source usually contain no weapon entities. If TTT finds no spawnable weapon and no info_player_deathmatch, but does find an info_player_counterterrorist, it scatters random weapons at the spawn points and hostage entities.
Reset. Before every round TTT calls game.CleanUpMap. Doors, buttons, broken props and all logic entities are then back in their initial state. So build nothing that has to remember state across rounds.
Loading the TTT entities in Hammer
ttt.fgd is located in garrysmod/gamemodes/terrortown/. The mapexamples subfolder holds three example maps: ttt_traitorcheck.vmf, ttt_traps.vmf and ttt_weaponcheck.vmf. In Hammer, open Tools > Options, select the Game Configurations tab and add the file under "Game Data files" with Add.
Hammer then offers info_player_deathmatch (this class is missing from garrysmod.fgd), the weapons (weapon_zm_*, weapon_ttt_*), the ammo (item_*_ttt) and the ttt_ entities.
TTT is built on the content of Counter-Strike: Source, and since the update of July 2025 GMod itself ships most CS:S and Half-Life 2 episode content, without maps, music and voice-over. You can therefore use it in a TTT map. What exactly is included is covered in CS:S and HL2 content in GMod maps.
Placing spawns, weapons and ammo
- Number of spawns. According to the documentation, TTT is intended for 16 to 18 players, and many servers allow more. For placement scripts it recommends at least 32 spawns. If no spawn is free, TTT creates makeshift spawns 36 units next to an existing one and writes
TTT WARNING: Map has too few spawn pointsto the console. If that fails as well, a spawn is forced and whoever is standing there dies. So leave open floor around every spawn. ttt_random_weapon. On spawn, it turns into a random weapon from all weapons registered on the server as automatically spawnable. That includes weapons from addons, which fixedweapon_zm_*entities cannot do. The spawnflags (Sub-Machine Guns, Assault Rifles, Sniper Rifles, Shotguns and more) narrow the selection.auto_ammoadds the given number of matching ammo boxes. Leave some room above the entity, because the boxes are created there and drop down.ttt_random_ammolikewise turns into a random ammo box.- Placement scripts. Alternatively, TTT reads a text file
maps/<mapname>_ttt.txt(or the same file indata_static/). It is created with the TTT Weapon Placer addon in Sandbox and mainly meant for maps not built for TTT. Important: if such a script exists, TTT removes the weapons and ammo placed in the map (everything automatically spawnable plus the Half-Life 2 classes it would otherwise replace) and loads the script's contents instead. Withreplacespawns 1it replaces the spawns too. You can switch this off withttt_use_weapon_spawn_scripts 0.
A line consists of class, position and angles, separated by tabs:
setting: replacespawns 1
ttt_playerspawn -203.8 -1811.8 -209.6 0 36 0
ttt_random_weapon -1107.0 2109.9 194.0 1.8 132.9 -92.7 auto_ammo 2
The TTT entities at a glance
| Entity | Purpose | Key keyvalues, inputs and outputs |
|---|---|---|
ttt_map_settings | Settings and round events | cbar_doors, cbar_buttons, cbar_other, plymodel, propspec_allow_named; outputs RoundPreparation, RoundStart, RoundEnd |
ttt_traitor_button | Button that only traitors see on their HUD and press from a distance | description, wait, RemoveOnPress, UsableRange; inputs Lock, Unlock; output OnPressed |
ttt_logic_role | Checks the role of the !activator | Role; input TestActivator; outputs OnPass, OnFail |
ttt_filter_role | Filter for triggers by role | Role |
ttt_traitor_check | Brush that counts living traitors inside its volume | Input CheckForTraitor; output TraitorsFound |
ttt_weapon_check | Brush that checks the weapons of players inside its volume | Inputs CheckForType, CheckForClass; output WeaponsFound |
ttt_damageowner | Attributes the damage of an entity to a player | damager, killname; inputs SetActivatorAsDamageOwner, ClearDamageOwner |
ttt_win | Ends the round | Inputs TraitorWin, InnocentWin |
ttt_game_text | Message in the TTT message area at the top right | receive, message, color; input Display |
ttt_credit_adjust | Takes TTT credits from the !activator or gives them some | credits; input TakeCredits; outputs OnSuccess, OnFail |
ttt_spectator_spawn | Destination point for spectators | Angles of the entity |
Four things the table does not show:
- The crowbar opens named doors. By default a crowbar hit unlocks and opens every
func_door,func_door_rotatingandprop_door_rotating, unlocks and presses everyfunc_buttonand opens everyfunc_movelinear, as long as the entity has a name. If a door should only open through your logic, set the matchingcbar_option inttt_map_settingsto No. - During the preparation phase everyone is innocent.
ttt_logic_roleandttt_filter_rolethen treat all players as innocent. ttt_traitor_checkis outdated. The FGD tags the class witheditor/obsolete.vmt, and the documentation recommendsttt_logic_rolewith a normal trigger instead.RoundEndpasses the outcome as a parameter: 2 for traitors, 3 for innocents, 4 for the time limit.
Wiring outputs to inputs is explained in Hammer inputs and outputs. info_manipulate in the TTT folder is only a placeholder for old Zombie Master maps and turns into a ttt_traitor_button in game.
Layout: advice, not rules
This section is design experience, not documented requirements. Only the ratios are fixed: with the default values, 25 percent of the players are traitors (rounded down, at least one), and detectives appear from 8 players upwards. With 16 players that means 4 traitors and 2 detectives.
- Mix your sight lines. Traitors need unobserved moments, innocents need spots with an overview. A map made only of long corridors serves one side.
- Places for bodies. A body that is found provides clues. Niches away from the main routes make hiding possible, but they should stay reachable.
- Fair traps. A trap is fair when attentive players can recognise or avoid it. Connect it to a
ttt_damageowner, otherwise the kill is credited to no player, neither for score and karma nor in the round report. UsewaitorRemoveOnPressto limit how often it fires. - Traitor testers. They are controversial in the community because they can replace deduction with queueing. Common compromises are testers that work slowly, check only one person or can be sabotaged by traitors.
The TTT code does not use a navmesh. You only need one if servers run bots or Nextbots, see navmesh and AI nodes.
Testing with the round system
- Put the BSP into
garrysmod/maps, select TTT as the gamemode and start the map. TTT waits for players at first. - Set
ttt_minimum_players 1andttt_debug_preventwin 1. Entities are only replaced and weapons only placed once TTT prepares the first round. - Enable
sv_cheats 1and switch roles withttt_force_traitor,ttt_force_detectiveandttt_force_terror. - Start a new round with
ttt_roundrestartand check that everything resets. - To test
ttt_win, setttt_debug_preventwinback to 0, otherwise TTT ignores the win.
Spawn count, weapon distribution and traps only prove themselves on a full server. How to organise that is covered in playtesting a GMod map with players.
FAQ
Does the name of a TTT map have to start with ttt_?
Technically no, TTT runs on any map. But TTT's gamemode file contains the pattern ^ttt_, which Garry's Mod uses to sort maps under the gamemode in the map selector.
Why are the weapons I placed missing from my map?
Check whether a file <mapname>_ttt.txt exists. TTT ships such scripts for several CS:S maps, and a script replaces the weapons placed in the map.
How far does a ttt_traitor_button reach?
1024 units by default, measured between the button and the player. Change the value with UsableRange. Innocents do not see the button at all.