Mapping et Hammer

Guide des soundscapes : le son d’ambiance des maps GMod dans Hammer

Comment fonctionnent les soundscapes de Source : env_soundscape, proxy et trigger, un script par map, packing dans le BSP et solutions si la map reste muette.

Un soundscape est une entrée nommée dans un fichier de script, qui décrit un fond sonore : des sons en boucle, des sons ponctuels aléatoires et un effet de réverbération. Dans la map, tu places un env_soundscape par zone et tu y saisis ce nom. Le moteur détermine séparément pour chaque joueur quelle entité s’applique à cet instant et fait un fondu enchaîné quand elle change. Tes propres soundscapes s’écrivent dans le fichier scripts/soundscapes_<mapname>.txt, que tu packes dans le BSP avec ses sons.

Comment fonctionne un soundscape

Le travail est réparti. Le serveur vérifie pour chaque joueur quelle entité de soundscape est active et le signale au client. Le client lit l’entrée dans le script et joue les sons en local. Il en découle :

  • Le serveur et le client ont besoin du même script. Si l’un des deux ne connaît pas le nom, c’est le silence.
  • Lors d’un changement, les boucles s’enchaînent en fondu. La durée est fixée par soundscape_fadetime, qui vaut 3 secondes dans le Source SDK.

Placer les entités : env_soundscape, proxy et trigger

EntitéRôleKeyvalues importants
env_soundscapeEntité ponctuelle qui devient active par le rayon et la ligne de vueRadius (radius, 128 par défaut), Soundscape (soundscape), Sound Position 0 à 7 (position0 à position7)
env_soundscape_proxyEmplacement et rayon propres, reprend le soundscape et les positions d’une autre entitéSoundscape Entity (MainSoundscapeName), Radius (radius)
env_soundscape_triggerableComme env_soundscape, et en plus activée par un trigger_soundscapeLes mêmes que env_soundscape
trigger_soundscapeTrigger sous forme de brush qui active l’entité indiquée quand on y entreSoundscape (soundscape) : nom d’un env_soundscape_triggerable

La règle de sélection figure dans le FGD : le soundscape actif est le dernier à avoir eu une ligne de vue sur le joueur alors que celui-ci se trouvait dans son rayon. Le code source du Source SDK en montre les détails :

  • La ligne de vue est testée de l’entité vers le joueur. La géométrie solide et l’eau la bloquent.
  • Si plusieurs entités remplissent les deux conditions, la plus proche l’emporte.
  • Si plus aucune ne remplit les conditions, la dernière continue de jouer.
  • Un rayon de -1 signifie : la ligne de vue suffit, la distance ne compte pas.

Place donc l’entité dans un espace dégagé et choisis un rayon qui ne déborde pas dans la pièce voisine à travers les portes. Les points de spawn ont eux aussi besoin d’un soundscape, sinon les joueurs n’entendent rien tant qu’ils n’ont pas atteint la première entité. Pour les pièces pleines de recoins, place plusieurs env_soundscape_proxy qui pointent vers la même entité principale. Là où la ligne de vue ne correspond pas au découpage des pièces, par exemple avec des parois vitrées ou des cours ouvertes, utilise trigger_soundscape. D’après la Valve Developer Community, une entité qui atteint le joueur par le rayon et la ligne de vue a la priorité sur le trigger, et le env_soundscape_triggerable lui-même continue de réagir au rayon et à la ligne de vue. Place-le donc à un endroit où les joueurs n’entrent pas dans son rayon.

Utiliser les soundscapes existants

Les scripts chargés sont listés dans scripts/soundscapes_manifest.txt. Le manifeste de GMod liste ses propres entrées, comme construct.outside, ainsi que les scripts de Half-Life 2, des épisodes, de Portal, de Counter-Strike: Source, de Day of Defeat: Source et de Team Fortress 2. La liste déroulante de l’entité n’affiche que quelques entrées comme GenericIndoor, mais tu peux saisir n’importe quel nom.

Un nom dans le manifeste ne veut pas dire que les sons sont présents. Sur une installation à jour, les paquets que GMod fournit lui-même contiennent presque tous les fichiers son utilisés par les scripts de Half-Life 2, des épisodes et de Counter-Strike: Source, mais seulement une petite partie de ceux de Team Fortress 2 et de Day of Defeat: Source. Plus de détails dans Contenu CS:S et HL2 dans les maps GMod.

Pour en écouter un, saisis sv_cheats 1 dans la console, puis playsoundscape suivi d’un nom.

Écrire ton propre script

Crée le fichier scripts/soundscapes_<mapname>.txt, où <mapname> est le nom du BSP sans l’extension. Le moteur le charge en plus du manifeste dès qu’il existe. Ne touche pas au manifeste lui-même. Si tu renommes la map, renomme le fichier avec.

"mymap.hall"
{
	"dsp"	"1"

	"playlooping"
	{
		"volume"	"0.4"
		"wave"		"ambient/atmosphere/indoor2.wav"
	}

	"playlooping"
	{
		"volume"	"0.6"
		"soundlevel"	"SNDLVL_70dB"
		"position"	"0"
		"wave"		"yourname/mymap/generator_loop.wav"
	}

	"playrandom"
	{
		"time"		"8,20"
		"volume"	"0.3,0.6"
		"pitch"		"90,110"
		"soundlevel"	"SNDLVL_75dB"
		"position"	"random"
		"rndwave"
		{
			"wave"	"ambient/levels/canals/drip1.wav"
			"wave"	"ambient/levels/canals/drip2.wav"
		}
	}
}
  • Nom : les noms de soundscapes sont communs à tous les fichiers chargés. Un préfixe comme mymap. évite les collisions.
  • dsp : l’effet de réverbération de la zone. Dans les scripts d’origine, 0 signifie désactivé et 1 le choix automatique.
  • playlooping : une boucle continue. Le chemin indiqué pour wave est relatif au dossier sound/. Indique toujours volume : dans le code du Source SDK, la valeur initiale est 0, et une boucle au volume 0 est ignorée.
  • playrandom : joue l’un des sons de rndwave à intervalles aléatoires. time, volume et pitch sont des plages écrites sous la forme minimum,maximum, time étant en secondes.
  • position : sans elle, le son vient uniformément de partout. Le nombre 0 renvoie au keyvalue Sound Position 0 de l’entité, dans lequel tu saisis le nom d’une entité cible, par exemple un info_target près du générateur. random ne fonctionne que dans playrandom et place le son à chaque fois à un endroit différent près du joueur. Un son positionné dans playrandom a aussi besoin de soundlevel ou de attenuation : dans le code du Source SDK, le niveau reste sinon à 0 et le son est joué sans atténuation avec la distance, comme s’il n’avait pas de position.

Packer le script et les sons dans le BSP

Le serveur et les joueurs ont besoin du script et de chaque fichier son custom. En fichier séparé dans un addon Workshop, le script ne suit pas : la whitelist de gmad n’autorise que scripts/vehicles/*.txt dans le dossier scripts/. La voie habituelle est donc le pakfile de la map. La marche à suivre est décrite dans Packer du contenu custom dans un BSP. Deux points sont propres aux soundscapes :

  • Les sons qui n’apparaissent que dans le script ne sont référencés nulle part dans la map elle-même. Vérifie donc à la main la liste d’un packer automatique.
  • Pour playlooping, il te faut un WAV avec un marqueur de boucle (cue point), comme en ont les boucles d’origine. Source ne reconnaît une boucle qu’à ce marqueur, sans lui le WAV n’est joué qu’une fois.

Pour savoir si le script et les sons sont bien arrivés dans le pakfile, utilise bspzip -dir ou le Map Scanner, qui liste les fichiers intégrés.

Quand ambient_generic convient mieux

Soundscapeambient_generic
Prévu pourl’ambiance de fond d’une zoneune source sonore isolée
Contrôleautomatique, selon la position du joueurpar des inputs comme PlaySound, StopSound, Volume, FadeIn, FadeOut
Qui l’entendchaque joueur son propre mixtous les joueurs à portée la même chose

Utilise ambient_generic pour tout ce que la map doit allumer ou éteindre : une machine avec un interrupteur d’arrêt, une alarme, de la musique sur pression d’un bouton. D’après le FGD, les flags « Start Silent » et « Is NOT Looped » sont cochés sur une nouvelle entité. Elle reste donc muette jusqu’à ce qu’un output déclenche PlaySound. Le câblage est expliqué dans Inputs et outputs dans Hammer.

Problèmes typiques

  • Silence partout : le plus souvent, le nom est faux, ou le fichier ne porte pas le nom de la map. Avec developer 1, la console affiche Can't find soundscape: <name>. D’après la Valve Developer Community, les soundscapes ont aussi besoin d’une map compilée avec VVIS, au minimum avec -fast.
  • Le soundscape ne change pas, ou change au mauvais endroit : la nouvelle entité n’a pas de ligne de vue, son rayon est trop petit, ou une entité plus proche voit dans la pièce à travers une porte. soundscape_debug 1 trace des lignes vers toutes les entités : vert pour l’entité active, blanc pour les entités à portée, rouge pour les entités hors de portée.
  • Il manque des sons chez les autres joueurs : le script ou les fichiers son ne sont pas packés, ou le soundscape utilise les sons d’un jeu que les joueurs n’ont pas. Teste la map packée sans tes fichiers non packés.
  • Les modifications du script restent sans effet : soundscape_flush recharge les scripts sans relancer la map.
sv_cheats 1
soundscape_debug 1
playsoundscape mymap.hall
stopsoundscape
soundscape_flush

Les commandes deux à quatre nécessitent sv_cheats 1. Le serveur n’accepte soundscape_flush que depuis sa propre console ou de la part de l’hôte d’un serveur local, et dans le Source SDK, la partie côté client qu’elle déclenche (cl_soundscape_flush) est elle aussi une commande de cheat.

Questions fréquentes

Tous les joueurs entendent-ils le même soundscape ?

Non. Le soundscape actif est déterminé séparément pour chaque joueur et joué sur son client. Chacun entend le mix de l’endroit où il se trouve.

Que signifient les nombres de dsp ?

Chaque nombre correspond à un preset de réverbération. Les commentaires du script de Valve lui-même citent, outre 0 (désactivé) et 1 (générique), entre autres 2 à 4 pour les pièces en métal, 5 à 7 pour les tunnels, 17 à 19 pour les pièces en béton et 23 à 25 pour les cavernes, chaque fois en petit, moyen et grand, plus 14 à 16 pour l’eau.

Dois-je modifier soundscapes_manifest.txt ?

Non. Le moteur charge de lui-même un fichier nommé scripts/soundscapes_<mapname>.txt, en plus de tout ce qui est listé dans le manifeste. Le manifeste vaut pour toutes les maps et reste inchangé.