#2 Developing World of Warcraft AddOns - Music Player
Tags: wowaddons
Published: 2020-04-27 15:32:10

---
title: #2 Developing World of Warcraft AddOns - Music Player
published: true
date: 2020-04-25 20:19:48 UTC
tags: Wow Addons
canonical_url: 
---

 ![#2 Developing World of Warcraft AddOns - Music Player](https://developer.school/content/images/2020/04/wow_p2-1.jpg)

In [Part One of our Developing World of Warcraft AddOns series](https://dev.to/paulhalliday/1-developing-world-of-warcraft-addons-hello-world-2m7l-temp-slug-945809) we looked at how to create a basic "Hello, World!" AddOn. We managed to load it up in game and display a message on screen, both at initialisation time _and_ with a slash command.

![#2 Developing World of Warcraft AddOns - Music Player](https://developer.school/content/images/2020/04/Screenshot-2020-04-25-at-21.29.08-min.png)<figcaption>Zolten gave me 16g whilst writing this article. He's a cool guy!</figcaption>

Today we'll be looking at how to play music and sound file(s) with our AddOns and creating a sound board, of sorts. It'll be slash command based, so the user will be able to type in something like:

1. `/playsound ding`
2. `/playsound murlocs`
3. `/playsound main theme`
4. `/playsound custom`
5. `/stopsound`

As you can imagine, each one allows us to play a particular sound _or_ music file. We'll also be able to play _custom_ sounds that we've added directly to our AddOn!

#### New AddOn

Let's create a new AddOn folder at `Interface/AddOns/MusicPlayer` with the following `MusicPlayer.toc`:

```
## Interface: 11303
## Title: MusicPlayer
## Notes: Play sounds and music inside of the game.
## Author: Paul Halliday
## Version: 0.0.1

MusicPlayer.lua
```

#### Finding Sounds

The easiest way to find sounds from World of Warcraft is to head over to Wowhead and find the in-game ID. For example, if we wanted to add the `MurlocAggro` sound, we'd likely search for `Murloc` and then click `Links > Copy In-game Sound Command`:

![#2 Developing World of Warcraft AddOns - Music Player](https://developer.school/content/images/2020/04/Screenshot-2020-04-25-at-17.35.38.png)

This gives us the following command:

```
/script PlaySound(416)
```
<figcaption>Try it in-game. You'll hear mrlrlrmrmrrrgllkrkglrl!</figcaption>

We can also go ahead and do the same for the `Ding!` noise:

![#2 Developing World of Warcraft AddOns - Music Player](https://developer.school/content/images/2020/04/Screenshot-2020-04-25-at-17.44.25.png)

This gives us the following command:

```
/script PlaySound(888)
```
<figcaption>&gt; Ding! &gt; Grats!</figcaption>

We can also find game music with sites such as [wow.tools](https://wow.tools) which we can play using `PlayMusic(id)`

![#2 Developing World of Warcraft AddOns - Music Player](https://developer.school/content/images/2020/04/Screenshot-2020-04-25-at-18.59.42.png)

This can be played in-game by typing the following command:

```
/script PlayMusic("Sound\\Music\\GlueScreenMusic\\wow_main_theme.mp3")
```

You'll need to ensure that you've got music enabled for this to work.

> If you're making an AddOn for retail, you'll want to use the fileId instead, i.e. `PlayMusic(53223)`

We're then able to stop the music by typing:

```
/script StopMusic()
```
<figcaption>That's enough title music for now... :)</figcaption>

Given what we now know, we can create a little `MusicPlayer` which allows us to play sounds with a slash command.

**It's time to write some code!**

#### Registering Slash Commands

The first thing that we're going to do is register a slash command for our sound player. We'll want to register both `/playsound` and `/stopsound` inside of `MusicPlayer.lua`:

```
SLASH_SOUND1 = "/playsound"
SLASH_STOPSOUND1 = "/stopsound"

local function playSoundHandler()
  print("Play sound!")
end

local function stopSoundHandler()
  print("Stop sound!")
end

SlashCmdList["SOUND"] = playSoundHandler;
SlashCmdList["STOPSOUND"] = stopSoundHandler;

```

If we type `/reload` in-game, we should be able to see our messages if we type either of our slash commands.

![#2 Developing World of Warcraft AddOns - Music Player](https://developer.school/content/images/2020/04/Screenshot-2020-04-25-at-20.24.39.png)

#### Displaying Sounds

In order to _play_ these sounds with our AddOn, we can make a `table` named `sounds` which contains information about the sound we'd like to play.

This allows us to either make a decision on which method we want to call to _play the sound_, or display information on screen to the user _about the sound_.

```
local soundType = {
    SOUND = 1,
    GAME_MUSIC = 2,
    CUSTOM = 3
}

local sounds = {
    ["murloc"] = {
        ["sound"] = 416,
        ["description"] = "Mglrlrlrlrlrl!",
        ["type"] = soundType.SOUND
    },
    ["ding"] = {
        ["sound"] = 888,
        ["description"] = "Grats!",
        ["type"] = soundType.SOUND
    },
    ["main theme"] = {
        ["sound"] = "Sound\\Music\\GlueScreenMusic\\wow_main_theme.mp3",
        ["description"] = "DUN DUNNN... DUNNNNNNNNNN",
        ["type"] = soundType.GAME_MUSIC
    },
    ["custom"] = {
        ["sound"] = "Interface\\AddOns\\MusicPlayer\\Sounds\\custom.mp3",
        ["description"] = "Custom sound!",
        ["type"] = soundType.CUSTOM
    }
}
```

Feel free to add your own sounds here and experiment with different sounds from Wowhead.

I've also added a sound called `custom.mp3` inside of a new folder I created at `AddOns/MusicPlayer/Sounds`. This represents the ability to play a sound outside of the standard game files.

There isn't anything special about the folder name `Sounds`, so feel free to add a custom sound wherever suits your use case. If you'd like to play your own sounds, go ahead and add it to the directory and `sounds` table like I did.

We can now create a new function named `displaySoundList` which will be used to print the potential sounds on screen to the user:

```
local function displaySoundList()
    print("----------------------------")
    for command in pairs(sounds) do
        local description = sounds[command].description
        print("Command: /playsound " .. command .. " - Description: " .. description)
    end
    print("----------------------------")
end
```

In order to use this, update your `playSoundHandler` to call the `displaySoundList` whenever we activate this command:

```
local function playSoundHandler()
  displaySoundList()
end
```

![#2 Developing World of Warcraft AddOns - Music Player](https://developer.school/content/images/2020/04/Screenshot-2020-04-25-at-20.40.30.png)

#### Playing Sounds

Now that we've got a _very helpful sound list_, the user knows that they can type a particular command to play a sound!

Let's now wire up that functionality to actually _play_ a sound by updating our `playSoundHandler`:

```
local function playSoundHandler(trackId)
  if(string.len(trackId) > 0) then
      local matchesKnownTrack = sounds[trackId] ~= nil

      if (matchesKnownTrack) then
          local track = sounds[trackId]
          
          playTrack(track)
      else
          displaySoundList()
          
          print(trackId .. " - Doesn't match a known track.")
      end
  else
      displaySoundList()
  end
end
```

Our control flow now looks like the following:

1. If there has been a `track` passed in by the user _and_ it _exists_, play the track.
2. If there has been a `track` passed in by the user _and_ it _doesn't exist,_ display the sound list and a message.
3. If there is no `track`, display the sound list.

Let's write our `playTrack` method so that we can actually _play_ a sound!

```
local customSoundId

local function playTrack(track)
  print(track.description)

  if(track.type == soundType.GAME_MUSIC) then
      PlayMusic(track.sound)

      print("To stop the music type /stopsound")
  elseif(track.type == soundType.SOUND) then
      PlaySound(track.sound)
  elseif(track.type == soundType.CUSTOM) then
      stopSoundHandler()
      customSoundId = select(2, PlaySoundFile(track.sound))
  end
end
```

We're now able to either `PlayMusic(track.sound)`, `PlaySound(track.sound)` or `PlaySoundFile(track.sound)` depending on the type that we determined inside of our `sounds` table earlier.

![#2 Developing World of Warcraft AddOns - Music Player](https://developer.school/content/images/2020/04/Screenshot-2020-04-25-at-21.26.45.png)

Notice how we're creating a `customSoundId` and only defining a value when we use `PlaySoundFile` as this returns us an `id` which we can use to _stop_ the sound later in the next step.

#### Stopping Sounds

For the next step, I'm going to assume that any _sound_ is just a few seconds long and a user _wouldn't want_ to type `/stopsound` to cancel it. A user may want to stop _music_ and custom sound files though.

Let's update our `stopSoundHandler` to support this:

```
local function stopSoundHandler()
  StopMusic()

  if(customSoundId ~= nil) then
      StopSound(customSoundId)
      customSoundId = nil
  end
end
```

We're now able to _stop_ sounds using `/stopsound`!

You can try this out if you either play a custom sound file _or_ some music with `PlayMusic`.

#### Summary

In the second part of our Developing WoW AddOns series we created a little Music Player! It's not going to win _AddOn of the year award_ by any stretch just yet, but we hopefully learned a little more about playing sound files.

Code for this article: [https://github.com/PaulHalliday/wow\_addon\_music\_player](https://github.com/PaulHalliday/wow_addon_music_player)