Mapping et Hammer

Créer des maps TTT : entités, spawns et tests dans GMod

Créer des maps TTT : spawns et armes que TTT reprend tout seul, rôle de chaque entité ttt_, chargement de ttt.fgd dans Hammer et test des manches en solo.

Techniquement, une map pour Trouble in Terrorist Town n’a besoin que d’assez de points de spawn info_player_deathmatch, plus des armes et des munitions. Tout le reste est facultatif : TTT est livré avec son propre fichier FGD et des entités ttt_ qui te permettent de construire des boutons de traître, des vérifications de rôle, des pièges avec une attribution correcte des kills et des événements de manche. Deux particularités comptent : TTT réinitialise complètement la map avant chaque manche, et pendant la phase de préparation chaque joueur compte comme innocent.

Ce que TTT reprend automatiquement d’une map

Spawns. En plus de info_player_deathmatch, TTT utilise info_player_terrorist, info_player_counterterrorist, info_player_combine, info_player_rebel, info_player_axis, info_player_allies, info_player_teamspawn et gmod_player_start. Le code ne se rabat sur info_player_start que si aucune de ces classes n’existe, et la documentation de TTT le déconseille. Les classes de spawn des autres modes de jeu sont traitées dans points de spawn et entités de mode de jeu.

Armes et munitions. Quand il prépare une manche, TTT remplace les entités d’armes et d’objets de Half-Life 2 par les siennes. Un extrait de la table du code de TTT :

Entité dans la mapDevient dans TTT
weapon_smg1weapon_zm_mac10
weapon_shotgunweapon_zm_shotgun
item_healthkitweapon_zm_shotgun

Les maps d’origine de Counter-Strike: Source ne contiennent généralement pas d’entités d’armes. Si TTT ne trouve aucune arme spawnable et aucun info_player_deathmatch, mais trouve un info_player_counterterrorist, il répartit des armes aléatoires sur les points de spawn et les entités d’otages.

Réinitialisation. Avant chaque manche, TTT appelle game.CleanUpMap. Les portes, les boutons, les props cassés et toutes les entités de logique reviennent alors à leur état initial. Ne construis donc rien qui doive garder un état en mémoire d’une manche à l’autre.

Charger les entités TTT dans Hammer

ttt.fgd se trouve dans garrysmod/gamemodes/terrortown/. Le sous-dossier mapexamples contient trois maps d’exemple : ttt_traitorcheck.vmf, ttt_traps.vmf et ttt_weaponcheck.vmf. Dans Hammer, ouvre Tools > Options, sélectionne l’onglet Game Configurations et ajoute le fichier sous « Game Data files » avec Add.

Hammer propose alors info_player_deathmatch (cette classe manque dans garrysmod.fgd), les armes (weapon_zm_*, weapon_ttt_*), les munitions (item_*_ttt) et les entités ttt_.

TTT repose sur le contenu de Counter-Strike: Source, et depuis la mise à jour de juillet 2025, GMod fournit lui-même la majeure partie du contenu de CS:S et des épisodes de Half-Life 2, sans les maps, la musique ni les voix. Tu peux donc l’utiliser dans une map TTT. Ce qui est inclus exactement est détaillé dans contenu CS:S et HL2 dans les maps GMod.

Placer les spawns, les armes et les munitions

  • Nombre de spawns. D’après la documentation, TTT est prévu pour 16 à 18 joueurs, et beaucoup de serveurs en autorisent davantage. Pour les scripts de placement, elle recommande au moins 32 spawns. Si aucun spawn n’est libre, TTT crée des spawns de fortune à 36 unités d’un spawn existant et écrit TTT WARNING: Map has too few spawn points dans la console. Si cela échoue aussi, un spawn est forcé et celui qui s’y trouve meurt. Laisse donc du sol dégagé autour de chaque spawn.
  • ttt_random_weapon. Au spawn, elle se transforme en une arme aléatoire parmi toutes les armes enregistrées sur le serveur comme spawnables automatiquement. Cela inclut les armes des addons, ce que des entités weapon_zm_* fixes ne permettent pas. Les spawnflags (Sub-Machine Guns, Assault Rifles, Sniper Rifles, Shotguns et d’autres) restreignent la sélection. auto_ammo ajoute le nombre indiqué de boîtes de munitions correspondantes. Laisse un peu de place au-dessus de l’entité, car les boîtes y sont créées puis tombent. De la même façon, ttt_random_ammo se transforme en une boîte de munitions aléatoire.
  • Scripts de placement. Autre possibilité : TTT lit un fichier texte maps/<mapname>_ttt.txt (ou le même fichier dans data_static/). Il se crée avec l’addon TTT Weapon Placer en Sandbox et sert surtout aux maps qui n’ont pas été construites pour TTT. Important : si un tel script existe, TTT retire les armes et les munitions placées dans la map (tout ce qui est spawnable automatiquement, plus les classes de Half-Life 2 qu’il remplacerait sinon) et charge à la place le contenu du script. Avec replacespawns 1, il remplace aussi les spawns. Tu peux désactiver ce comportement avec ttt_use_weapon_spawn_scripts 0.

Une ligne se compose de la classe, de la position et des angles, séparés par des tabulations :

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

Les entités TTT en un coup d’œil

EntitéRôleKeyvalues, inputs et outputs principaux
ttt_map_settingsRéglages et événements de manchecbar_doors, cbar_buttons, cbar_other, plymodel, propspec_allow_named ; outputs RoundPreparation, RoundStart, RoundEnd
ttt_traitor_buttonBouton que seuls les traîtres voient sur leur HUD et actionnent à distancedescription, wait, RemoveOnPress, UsableRange ; inputs Lock, Unlock ; output OnPressed
ttt_logic_roleVérifie le rôle du !activatorRole ; input TestActivator ; outputs OnPass, OnFail
ttt_filter_roleFiltre pour triggers selon le rôleRole
ttt_traitor_checkBrush qui compte les traîtres vivants dans son volumeInput CheckForTraitor ; output TraitorsFound
ttt_weapon_checkBrush qui vérifie les armes des joueurs dans son volumeInputs CheckForType, CheckForClass ; output WeaponsFound
ttt_damageownerAttribue les dégâts d’une entité à un joueurdamager, killname ; inputs SetActivatorAsDamageOwner, ClearDamageOwner
ttt_winMet fin à la mancheInputs TraitorWin, InnocentWin
ttt_game_textMessage dans la zone de messages de TTT, en haut à droitereceive, message, color ; input Display
ttt_credit_adjustRetire des crédits TTT au !activator ou lui en donnecredits ; input TakeCredits ; outputs OnSuccess, OnFail
ttt_spectator_spawnPoint de destination pour les spectateursAngles de l’entité

Quatre choses que le tableau ne montre pas :

  • Le pied-de-biche ouvre les portes nommées. Par défaut, un coup de pied-de-biche déverrouille et ouvre chaque func_door, func_door_rotating et prop_door_rotating, déverrouille et actionne chaque func_button et ouvre chaque func_movelinear, à condition que l’entité ait un nom. Si une porte ne doit s’ouvrir que par ta logique, règle l’option cbar_ correspondante de ttt_map_settings sur No.
  • Pendant la phase de préparation, tout le monde est innocent. ttt_logic_role et ttt_filter_role traitent alors tous les joueurs comme des innocents.
  • ttt_traitor_check est obsolète. Le FGD marque la classe avec editor/obsolete.vmt, et la documentation recommande à la place ttt_logic_role avec un trigger normal.
  • RoundEnd transmet l’issue en paramètre : 2 pour les traîtres, 3 pour les innocents, 4 pour la limite de temps.

Le câblage des outputs vers les inputs est expliqué dans inputs et outputs dans Hammer. info_manipulate, dans le dossier de TTT, n’est qu’un substitut pour les anciennes maps Zombie Master et devient un ttt_traitor_button en jeu.

Layout : des conseils, pas des règles

Cette section relève de l’expérience de design, pas d’exigences documentées. Seules les proportions sont fixes : avec les valeurs par défaut, 25 % des joueurs sont des traîtres (arrondi à l’inférieur, au moins un), et les détectives apparaissent à partir de 8 joueurs. Avec 16 joueurs, cela donne 4 traîtres et 2 détectives.

  • Varie les lignes de vue. Les traîtres ont besoin de moments sans témoin, les innocents d’endroits offrant une vue d’ensemble. Une map faite uniquement de longs couloirs ne sert qu’un camp.
  • Des endroits pour les corps. Un corps retrouvé fournit des indices. Des recoins à l’écart des axes principaux permettent de le cacher, mais ils doivent rester accessibles.
  • Des pièges équitables. Un piège est équitable quand des joueurs attentifs peuvent le repérer ou l’éviter. Relie-le à un ttt_damageowner, sinon le kill n’est attribué à aucun joueur, ni pour le score et le karma ni dans le rapport de manche. Utilise wait ou RemoveOnPress pour limiter le nombre de déclenchements.
  • Les testeurs de traîtres. Ils font débat dans la communauté, car ils peuvent remplacer la déduction par une file d’attente. Les compromis courants sont des testeurs qui fonctionnent lentement, ne vérifient qu’une personne ou peuvent être sabotés par les traîtres.

Le code de TTT n’utilise pas de navmesh. Tu n’en as besoin que si des serveurs font tourner des bots ou des Nextbots, voir navmesh et AI nodes.

Tester avec le système de manches

  1. Place le BSP dans garrysmod/maps, choisis TTT comme mode de jeu et lance la map. Au début, TTT attend des joueurs.
  2. Règle ttt_minimum_players 1 et ttt_debug_preventwin 1. Les entités ne sont remplacées et les armes placées qu’une fois que TTT prépare la première manche.
  3. Active sv_cheats 1 et change de rôle avec ttt_force_traitor, ttt_force_detective et ttt_force_terror.
  4. Lance une nouvelle manche avec ttt_roundrestart et vérifie que tout se réinitialise.
  5. Pour tester ttt_win, remets ttt_debug_preventwin à 0, sinon TTT ignore la victoire.

Le nombre de spawns, la répartition des armes et les pièges ne font leurs preuves que sur un serveur plein. L’organisation de ce test est décrite dans tester une map GMod avec des joueurs.

Questions fréquentes

Le nom d’une map TTT doit-il commencer par ttt_ ?

Techniquement non, TTT tourne sur n’importe quelle map. Mais le fichier de mode de jeu de TTT contient le motif ^ttt_, que Garry’s Mod utilise pour classer les maps sous le mode de jeu dans le sélecteur de maps.

Pourquoi les armes que j’ai placées sont-elles absentes de ma map ?

Vérifie s’il existe un fichier <mapname>_ttt.txt. TTT est livré avec de tels scripts pour plusieurs maps de CS:S, et un script remplace les armes placées dans la map.

Jusqu’où porte un ttt_traitor_button ?

1024 unités par défaut, mesurées entre le bouton et le joueur. Modifie la valeur avec UsableRange. Les innocents ne voient pas du tout le bouton.