Counter-Strike: playing a different song each round

'Ah inseparabile - d'amore il Dio'
'Ah inseparabile - d'amore il Dio'

Table of contents:

1. Introduction

In this tutorial we'll make a destructible radio like the one in cs_italy, but instead of always playing the same song, we'll make it switch to a different song when a new round starts.

We'll use two MESS template entities for this: cs_trigger_roundstart and mtl_trigger_counter, and we will also use target patterns.

2. Setting up the songs

We'll start by creating 4 ambient_generic entities, one for each song:

4 ambient_generics
4 ambient_generics

First create a single ambient_generic entity and set its properties as following:

property value
Name song1
Path/filename ambience/Opera.wav
Volume 10
Start volume 10
Flags Medium Radius, Start Silent

Then create 3 copies of this entity, and change their name and path/filename to the following:

property value
Name song2
Path/filename ambience/chimes.wav
property value
Name song3
Path/filename ambience/arabmusic.wav
property value
Name song4
Path/filename ambience/guit1.wav

3. Stopping the songs

The next step is a way to stop the songs, and of course a breakable radio:

Stopping the song... by breaking the radio!
Stopping the song... by breaking the radio!

When a new round starts, we need to stop the previous song and start the next. However, Counter-Strike entities can be quirky: when a new round starts, an ambient_generic will start playing even when its 'Start Silent' flag is set. So instead of stopping only the previous song, we need to stop all songs.

To do that, create a multi_manager, set its name to stop_songs, then disable SmartEdit mode and add the following keys and values:

key value
targetnamestop_songs
-song10
-song20
-song30
-song40

The minus (-) in front of the song entity names is a 'target pattern' that will cause MESS to generate a trigger_relay that sends an 'off' signal to that entity. This means that we can be certain that the songs will be turned off instead of being toggled (which might accidentally turn them on).

For the radio, create a func_breakable and set its target to stop_songs. This will stop the current song when the radio gets destroyed.

4. Starting the next song

To play a different song each round, we're going to use a counter:

Selecting the next song with a counter
Selecting the next song with a counter

Create an mtl_trigger_counter and give it the following properties:

property value
Targetname play_next_song
Trigger mode Increment when triggered
Initial counter value 0
Reset counter at 4

Then disable SmartEdit mode and add the following keys and values:

key value
+song11
+song22
+song33
+song44

Again, we're using a 'target pattern' here: the plus (+) tells MESS to generate a trigger_relay that sends an 'on' signal to that entity, so instead of toggling a song, this will always turn it on.

This mtl_trigger_counter will start the next song from its list each time it is triggered, and it will cycle back to the first song after all four songs have been played.

5. Starting a song when a new round starts

The final step is to actually start a song (and stop the others) when a new round starts:

Starting a new song each round
Starting a new song each round

Create a cs_trigger_roundstart entity with the following properties:

property value
Target stop_songs, play_next_song: 0.1
Delay (first round) 2
Delay 0

We're using yet another target pattern here: the comma between 'stop_songs' and 'play_next_song: 0.1' tells MESS to generate a multi_manager with two targets: 'stop_songs', which will be triggered immediately, and 'play_next_song', which will be triggered after a 0.1 second delay.

The delay for the first round is set to 2 seconds because of another Counter-Strike quirk. Without this delay, no song will play during the first round. Apparently an ambient_generic can't be triggered too soon after a game has started. This only affects the first round however, so the delay for subsequent rounds should be 0.

And that's it! You can now compile your map and hear the results for yourself in-game:

The end result
The end result

6. Notes

If you want to add more songs, you'll need to create more ambient_generic entities, and add them as targets to the 'stop_songs' multimanager and to the 'play_next_song' mtl_trigger_counter. You also need to update the mtl_trigger_counter's 'Reset counter at' value to match the number of songs.

If you want to use custom songs, place your .wav files somewhere in your cstrike_addon/sound folder and replace the 'Path/filename' of the ambient_generic entities with the path of your own .wav files (relative to the cstrike_addon/sound folder). Don't forget to include the sounds in your map's .res file - a tool like ResGuy should be able to do that automatically.

To select a new song randomly instead of always cycling to the next song, replace the mtl_trigger_counter with an mtl_trigger_random entity and give it the following properties:

property value
Name play_next_song
Trigger mode Fire one target

Then disable SmartEdit mode and add the following keys:

key value
+song1
+song2
+song3
+song4

7. Example map

Example map: