Mapping y Hammer

Guía de soundscapes: sonido ambiente para mapas de GMod en Hammer

Cómo funcionan los soundscapes de Source: env_soundscape, proxy y trigger, un script por mapa, empaquetarlo en el BSP y soluciones si el mapa se queda mudo.

Un soundscape es una entrada con nombre en un archivo de script que describe una mezcla de fondo: sonidos en bucle, sonidos sueltos aleatorios y un efecto de reverberación. En el mapa colocas un env_soundscape por zona y escribes ese nombre. El motor decide por separado para cada jugador qué entity se aplica en cada momento y hace un fundido cruzado cuando cambia. Tus propios soundscapes los escribes en el archivo scripts/soundscapes_<mapname>.txt, que empaquetas en el BSP junto con sus sonidos.

Cómo funciona un soundscape

El trabajo está repartido. El servidor comprueba para cada jugador qué entity de soundscape está activa y se lo comunica al cliente. El cliente lee la entrada del script y reproduce los sonidos en local. Esto implica:

  • Servidor y cliente necesitan el mismo script. Si uno de los dos no conoce el nombre, hay silencio.
  • Al cambiar, los bucles se funden entre sí. La duración la marca soundscape_fadetime, que en el Source SDK es de 3 segundos.

Colocar las entities: env_soundscape, proxy y trigger

EntityFunciónKeyvalues importantes
env_soundscapePoint entity que se activa por radio y línea de visiónRadius (radius, por defecto 128), Soundscape (soundscape), Sound Position 0 a 7 (position0 a position7)
env_soundscape_proxyUbicación y radio propios, toma el soundscape y las posiciones de otra entitySoundscape Entity (MainSoundscapeName), Radius (radius)
env_soundscape_triggerableComo env_soundscape, y además la activa un trigger_soundscapeLos mismos que env_soundscape
trigger_soundscapeTrigger de brush que activa la entity indicada al entrar en élSoundscape (soundscape): nombre de un env_soundscape_triggerable

La regla de selección figura en el FGD: el soundscape activo es el último que tuvo línea de visión con el jugador mientras este estaba dentro de su radio. El código fuente del Source SDK muestra los detalles:

  • La línea de visión se comprueba desde la entity hacia el jugador. La geometría sólida y el agua la bloquean.
  • Si varias entities cumplen las dos condiciones, gana la más cercana.
  • Si ya ninguna cumple las condiciones, sigue sonando la última.
  • Un radio de -1 significa: basta con la línea de visión, la distancia no importa.

Así que coloca la entity en un espacio despejado y elige un radio que no se cuele por las puertas hasta la sala de al lado. Los puntos de spawn también necesitan un soundscape, de lo contrario los jugadores no oyen nada hasta llegar a la primera entity. En salas con recovecos, coloca varias env_soundscape_proxy que apunten a la misma entity principal. Donde la línea de visión no encaja con la distribución de las salas, por ejemplo con paredes de cristal o patios abiertos, usa trigger_soundscape. Según la Valve Developer Community, una entity que alcanza al jugador por radio y línea de visión tiene prioridad sobre el trigger, y la propia env_soundscape_triggerable sigue reaccionando al radio y a la línea de visión. Por eso, colócala donde los jugadores no entren en su radio.

Usar soundscapes existentes

Los scripts que se cargan figuran en scripts/soundscapes_manifest.txt. El manifiesto de GMod enumera entradas propias como construct.outside, además de los scripts de Half-Life 2, los episodios, Portal, Counter-Strike: Source, Day of Defeat: Source y Team Fortress 2. El desplegable de la entity solo muestra unas pocas entradas como GenericIndoor, pero puedes escribir cualquier nombre.

Que un nombre esté en el manifiesto no significa que los sonidos estén ahí. En una instalación actual, los paquetes que trae el propio GMod contienen casi todos los archivos de sonido que usan los scripts de Half-Life 2, los episodios y Counter-Strike: Source, pero solo una pequeña parte de los de Team Fortress 2 y Day of Defeat: Source. Más sobre esto en Contenido de CS:S y HL2 en mapas de GMod.

Para escuchar uno, escribe sv_cheats 1 en la consola y después playsoundscape con un nombre.

Escribir tu propio script

Crea el archivo scripts/soundscapes_<mapname>.txt, donde <mapname> es el nombre del BSP sin la extensión. El motor lo carga además del manifiesto en cuanto existe. El manifiesto en sí no lo toques. Si renombras el mapa, renombra también el archivo.

"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"
		}
	}
}
  • Nombre: los nombres de soundscape se comparten entre todos los archivos cargados. Un prefijo como mymap. evita colisiones.
  • dsp: el efecto de reverberación de la zona. En los scripts de serie, 0 significa desactivado y 1 la elección automática.
  • playlooping: un bucle continuo. La ruta indicada en wave es relativa a la carpeta sound/. Indica siempre volume: en el código del Source SDK el valor inicial es 0, y un bucle con volumen 0 se omite.
  • playrandom: reproduce uno de los sonidos de rndwave a intervalos aleatorios. time, volume y pitch son rangos escritos como minimum,maximum, time en segundos.
  • position: sin ella, el sonido llega por igual desde todas partes. El número 0 remite al keyvalue Sound Position 0 de la entity, donde escribes el nombre de una entity de destino, por ejemplo un info_target junto al generador. random solo funciona en playrandom y coloca el sonido cada vez en un punto distinto cerca del jugador. Un sonido posicionado en playrandom necesita además soundlevel o attenuation: en el código del Source SDK, de lo contrario el nivel se queda en 0 y el sonido se reproduce sin atenuación por distancia, como si no tuviera posición.

Empaquetar el script y los sonidos en el BSP

El servidor y los jugadores necesitan el script y cada archivo de sonido custom. Como archivo suelto en un addon de Workshop, el script no se incluye: la whitelist de gmad solo permite scripts/vehicles/*.txt dentro de la carpeta scripts/. Por eso, la vía habitual es el pakfile del mapa. El procedimiento se describe en Empaquetar contenido custom en un BSP. Hay dos puntos específicos de los soundscapes:

  • Los sonidos que solo aparecen en el script no están referenciados en ninguna parte del propio mapa. Por eso, revisa a mano la lista de un empaquetador automático.
  • Para playlooping necesitas un WAV con un marcador de bucle (cue point), como el que tienen los bucles de serie. Source solo reconoce un bucle por ese marcador, sin él el WAV suena una sola vez.

Si el script y los sonidos han llegado al pakfile te lo muestra bspzip -dir o el Map Scanner, que enumera los archivos incrustados.

Cuándo encaja mejor ambient_generic

Soundscapeambient_generic
Pensado parael ambiente de fondo de una zonauna única fuente de sonido
Controlautomático, según la ubicación del jugadormediante inputs como PlaySound, StopSound, Volume, FadeIn, FadeOut
Quién lo oyecada jugador su propia mezclatodos los jugadores dentro del alcance lo mismo

Usa ambient_generic para todo lo que el mapa tenga que encender o apagar: una máquina con interruptor de apagado, una alarma, música al pulsar un botón. Según el FGD, los flags «Start Silent» e «Is NOT Looped» vienen marcados en una entity nueva. Por tanto, permanece en silencio hasta que un output dispara PlaySound. Cómo conectarlo se explica en Inputs y outputs en Hammer.

Problemas típicos

  • Silencio en todas partes: normalmente el nombre está mal, o el archivo no se llama como el mapa. Con developer 1, la consola muestra Can't find soundscape: <name>. Según la Valve Developer Community, los soundscapes necesitan además un mapa compilado con VVIS, al menos con -fast.
  • El soundscape no cambia, o cambia en el sitio equivocado: la entity nueva no tiene línea de visión, su radio es demasiado pequeño, o una entity más cercana ve el interior de la sala a través de una puerta. soundscape_debug 1 dibuja líneas hacia todas las entities: verde para la activa, blanco para las entities dentro del alcance, rojo para las entities fuera del alcance.
  • A otros jugadores les faltan sonidos: el script o los archivos de sonido no están empaquetados, o el soundscape usa sonidos de un juego que los jugadores no tienen. Prueba el mapa empaquetado sin tus archivos sueltos.
  • Los cambios en el script no tienen efecto: soundscape_flush recarga los scripts sin reiniciar el mapa.
sv_cheats 1
soundscape_debug 1
playsoundscape mymap.hall
stopsoundscape
soundscape_flush

Los comandos del dos al cuatro necesitan sv_cheats 1. El servidor solo acepta soundscape_flush desde su propia consola o del host de un servidor local, y en el Source SDK la parte del lado del cliente que este comando desencadena (cl_soundscape_flush) también es un comando de cheats.

Preguntas frecuentes

¿Todos los jugadores oyen el mismo soundscape?

No. El soundscape activo se determina por separado para cada jugador y se reproduce en su cliente. Cada uno oye la mezcla del lugar donde está.

¿Qué significan los números de dsp?

Cada número corresponde a un preset de reverberación. Los comentarios del propio script de Valve citan, además de 0 (desactivado) y 1 (genérico), entre otros, del 2 al 4 para salas metálicas, del 5 al 7 para túneles, del 17 al 19 para salas de hormigón y del 23 al 25 para cavernas, cada uno en pequeño, mediano y grande, más del 14 al 16 para agua.

¿Tengo que editar soundscapes_manifest.txt?

No. El motor carga por sí solo un archivo llamado scripts/soundscapes_<mapname>.txt, además de todo lo que figura en el manifiesto. El manifiesto vale para todos los mapas y se queda como está.