Making a Dota 2 Announcer
Dota announcers work as a database of responses to specific events: "your top tower has fallen", "opposing team bottom barracks fallen", "courier slain", and so on. Custom announcers can be created by recording lines for each of these events, replacing the default announcer's voice for each of them. Currently, the easiest way to create a new announcer for submission is to work from the given template spreadsheet, which lists all of the events requiring voice and their criteria.

Download the Sample Announcer spreadsheet and the Sample Killing Spree Announcer spreadsheet

Recording Format

You should record your original audio in PCM .WAV format with 16 bit depth and a 44.1khz or 48khz sample rate. This will provide the highest quality result for the final in-game audio.

To reduce the size of your initial workshop submission and make it generally easier to move around and work with, feel free to compress your audio into .MP3 format using a program such as SoundForge or iTunes before upload. If your submission is accepted, we will contact you for the original high-res .WAVs.

Package and submit the spreadsheet to us as a workshop item through the game client. If your directory of .WAVs is too big to fit into the upload quota, you can upload them to a file-hosting service such as Dropbox and provide us with a link inside the submission.

Artistic Suggestions

Variety, intensity, and brevity are the keys to a successful announcer.

Every line you record will be heard many times by every player that activates them. In one game, a player might hear fifteen "tower has fallen" events, three "Roshan has fallen" events, and over thirty "your [building] is under attack" events. For an announcer to remain fresh after many games, each event should have as wide a variety of available lines as possible. The Juggernaut announcer has about three variations on every line; the Dr. Kleiner announcer has as many as five for some of them. The followup mechanism gives you an easy way to create lots of variety by allowing the announcer to mix and match a base event ("your top tower has fallen") with a different set of followup lines ("that doesn't look good for you").

Go big with your performance! Your announcer gets its chance to be an interesting character for a few words at a time. Bringing lots of intensity to each bit of dialog helps make your character unique. But it's important to also record at least one "straight" version of each main event in your character's voice, to help keep the really big ones fresh. For example, if your Renaissance Faire Announcer has a line such as "Behold! Thine top tower doth find itself beseiged!", also record a basic "Your top tower is under attack" in the same voice. This will help keep your over-the-top lines from becoming repetitive, since they can be mixed in with the straightforward lines at a lower frequency.

Remember that Dota is a chaotic game and things happen very quickly. Try to keep your announcer's lines short, since the interval between a tower falling and a hero saying something else may be only a few seconds long. Long lines can be distracting to players, who are trying to focus on keeping their hero alive. Longer lines also become repetitive and tired more quickly.

Spectator-only lines, which are heard only when users equip your announcer while watching a game, have more leeway in length and content, since spectators aren't focused on cutting through noise to hear game-critical information in the same way that players are. You may mark any line as being spectator-specific, so that spectators and players can hear entirely different dialogue for the same events. In the sample spreadsheet, players hear "your tower is under attack", whereas spectators hear "radiant's tower is under attack" for the same event.

Editing the Announcer Spreadsheets

After recording your .wavs, you should fill out the spreadsheet to specify which .wav files go with which events. The following example indicates that you would like to play "announcer_battle_begin_02.wav" after the "game start" horn honks.
announcer_battle_begin_02 The battle begins! IsGameStart
You may specify several lines for the same event, such as this example from the Dr. Kleiner announcer:
announcer_fort_rad_01 I've never seen Radiant's structures looking so fortified. GlyphUsedGood
announcer_fort_rad_02 Radiant's structures are beautifully fortified. GlyphUsedGood
announcer_fort_rad_03 Radiant's structures are fortified. GlyphUsedGood
announcer_fort_rad_04 Radiant's structures are fortified. There appears to be some sort of magic at work. GlyphUsedGood
In this case the engine will pick from one of announcer_fort_rad_01, announcer_fort_rad_02, announcer_fort_rad_03, or announcer_fort_rad_04 to play when the radiant ("good") team uses the glyph of fortification. Wherever multiple rows have identical criteria in their third column, they are considered to be alternative lines for the same event. In some cases the third column of the spreadsheet has multiple criteria. These three criteria together define the particular event that the line responds to; the wav will play only if all of them are true. In the example above, announcer_rax_fall_yr_top.wav plays when a tower has been killed and it was in the top lane and the "kill" was not a deny.
announcer_twr_fall_yr_top Your top tower has fallen. IsTowerKilled IsTopLane IsNotDeny
Certain optional criteria can be added to a third column to further specify when you want a wav to play: for example, you can use IsSpectator to define a wav that plays only for spectators and not for players.
announcer_rax_attack_dire_bot Dire's bottom barracks are under attack. IsBarracksAttacked IsBadAttacked IsSpectator IsBotLane
Certain event types are "followup" lines that optionally play after other event lines have played. In this case announcer_victory_01.wav will play after the "radiant victory!" or "dire victory!" line has played. This lets you mix and match lines for more variety like "The Radiant's Courier has been killed... Who would pick on such a defenseless creature?" by recording the "courier killed" and followup parts separately.
announcer_victory_01 A foregone conclusion, I should think. IsFollowup_PlayerVictory

Pick Mode Lines

Certain lines in the spreadsheet do not have a criterion column because the game engine plays them by a different route. You should record your own version of these lines and add them to the spreadsheet as well, but leave the third column empty.
announcer_choose_hero Choose your hero.
announcer_now_select You may now select your heroes.
announcer_pick_yr Your turn to pick.
announcer_pick_enm Enemy's turn to pick.
announcer_pick_dire Dire team pick.
announcer_pick_rad Radiant team pick.
announcer_ban_yr Your turn to ban.
announcer_ban_enm Enemy's turn to ban.
announcer_ban_dire Dire team ban.
announcer_ban_rad Radiant team ban.
announcer_team_complete_rad Radiant's team is complete.
announcer_team_complete_yr Your team is complete.
announcer_team_complete_our Our team is complete.
announcer_team_complete_dire Dire's team is complete.

Mega Kill Announcer

Mega kill announcers have relatively few lines but follow the same general system as above. The sample spreadsheet is:
wav name subtitle Criteria
announcer_kill_double_01 Double kill! IsDoubleKill
announcer_kill_triple_01 Triple kill! IsTripleKill
announcer_kill_ultra_01 Ultra kill! IsQuadKill
announcer_kill_rampage_01 Rampage! IsQuintupleKill
announcer_kill_wipeout_01 Team wipeout!
announcer_kill_spree_01 Killing spree! IsThreeSpree
announcer_kill_dominate_01 Dominating! IsFourSpree
announcer_kill_mega_01 Mega kill! IsFiveSpree
announcer_kill_unstop_01 Unstoppable! IsSixSpree
announcer_kill_wicked_01 Wicked sick! IsSevenSpree
announcer_kill_monster_01 Monster kill! IsEightSpree
announcer_kill_godlike_01 Godlike! IsNineSpree
announcer_kill_holy_01 Holy shit! IsMaxSpree
announcer_ownage_01 Ownage!
announcer_1stblood_01 First blood! IsFirstBlood

Event Types

IsAnnounceIdle
Triggers at random intervals when nothing "interesting" has happened for the last few minutes (eg no heroes have been killed or seriously damaged, no buildings fallen, etc). Optional.
IsBadBarracksKilled
Triggers when a Dire barracks has fallen.
IsBadVictory
Triggers when Dire wins.
IsGoodVictory
Triggers when Radiant wins.
IsBarracksAttacked
Triggers when either team's barracks are under attack. Use in conjunction with eg IsTopLane and IsGoodAttacked to specify which line plays for which lanes and teams. See the spreadsheet for an example of use.
IsBarracksKilled
Triggers when the player's team's barracks have fallen.
IsEnemyBarracksKilled
Triggers when the opposing team's barracks have fallen.
IsGoodBarracksKilled
Triggers when the radiant team's barracks have fallen.
IsBadBarracksKilled
Triggers when the dire team's barracks have fallen.
IsTowerKilled
Triggers when the player's tower has fallen.
IsBadTowerKilled
Triggers when a Dire tower falls.
IsGoodTowerKilled
Triggers when a Radiant tower falls.
IsEnemyTowerKilled
Triggers when the enemy team's tower falls.
IsFortAttacked
Triggers when either team's ancient is attacked.
IsTowerAttacked
Triggers when either team's tower is attacked.
IsMegaCreeps
Triggers when the player's team gets mega creeps.
IsBadMegaCreeps
Triggers when Dire gets mega creeps.
IsGoodMegaCreeps
Triggers when Radiant gets mega creeps.
IsEnemyMegaCreeps
Triggers when opposing team gets mega creeps.
IsGameStarting30
Triggers 30 seconds before the game begins (eg when the countdown clock clock at the top of the screen reads '30'). Optional.
IsGameStarting10
Triggers 10 seconds before the game begins. Optional.
IsGameStart
Triggers after the horn honks. "The battle begins!"
IsPrepStart
Triggers for an individual player a few seconds after their hero spawns for the first time. "Prepare for battle!"'
IsRoshanKilledBad
Triggers when Roshan is killed by the Dire.
IsRoshanKilledGood
Triggers when Roshan is killed by the Radiant.
CourierLostBad
Triggers when Dire's courier is killed.
CourierLostGood
Triggers when Radiant's courier is killed.
GlyphUsedBad
Triggers when Dire uses its Glyph of Fortification.
GlyphUsedGood
Triggers when Radiant fortifies.
IsFollowupGameStart30
Triggers after the IsGameStarting30 line plays, if any. Optional.
IsFollowup_BattleBegins
Triggers after the "battle begins" line. Optional.
IsFollowup_CourierDead
Triggers after CourierLostBad or CourierLostGood plays. Optional.

Criteria Types

IsBadAttacked
True if the Dire team was attacked and the event is one of IsBarracksAttacked or IsTowerAttacked or IsFortAttacked.
IsGoodAttacked
True if the Radiant team was attacked (during the IsBarracksAttacked, IsTowerAttacked, or IsFortAttacked events).
IsBotLane
True if the event is one of IsBarracksAttacked or IsTowerAttacked, and the attacked building was in the bottom lane.
IsMidLane
True if the attacked building was in the middle lane.
IsTopLane
True if the attacked building was in the top lane.
IsDeny
True if the event is IsTowerKilled (or one of the variants) and the tower was killed by its own team.
IsNotDeny
True only if the building was killed by the opposing team.
IsGameTime_After_45m
True if the game has gone on for at least 45 minutes.
IsGameTime_After_60m
True if the game clock is after 60 minutes.
IsGameTime_Before_10m
True if the game clock is before 10 minutes.
IsDaytime
True if it's daylight, false if it's night (or Night Stalker has cast his ultimate).
IsSpectator
True if the listening player is a spectator and not actively part of the game. Useful for sportscaster-like comments.
IsNotSpectator
True if the listening player is not a spectator.
IsPlayerTeam_Dire
True if the listening player is on the Dire team.
IsPlayerTeam_Radiant
True if the listening player is on the Radiant team.
IsRoshanCheese
True if Roshan has been killed at least three times.
Chance_10%
A random die roll, true one tenth of the time. Use to make some lines play infrequently (if for example you want a more rare variant of 'the courier has died' that doesn't play as often as the others).
Chance_25%
A random die roll, true one quarter of the time.
Chance_50%
A random die roll, true one half of the time.
Chance_75%
A random die roll, true three quarters of the time.