How to Script with the Showdown Replay Engine
The Showdown Replay Engine, as I've taken to calling it, is a way to turn pretty much any battle you can calculate into an animated battle video. While scripting with this is relatively simple and takes no programming knowledge, it is a bit tedious, as every action in the battle must be scripted induvidually. The goal of this page is to teach you the basic information you need to be able to script a battle using the Showdown Replay Engine. If you run into something while scripting that I don't cover, please make a Showdown replay of the situation and I'll track down the necessary code in the replay and add it here.
A template with the bare basics required to create a replay is available for you to download.
Navigation:
I. Basic Syntax
II. Pre-battle Setup and Starting the Battle
III. Moves, HP, and Status
IV. Stat Changes
V. Abilities and Items
VI. Weather and Field Effects
VII. Other Important Actions
I. Basic Syntax
In order to be able to pick up the Showdown Replay Engine more easily, it's important to understand how the commands are written. All commands are preceeded by a pipe character (|, usually below the backspace key). The pipe is also used to seperate different portions of a command. The parser does not appear to be whitespace sensitive, meaning you can put blank lines in between your code without worrying. That being said, I still recommend putting each command on its own line, both because it's easier to keep track of and because I'm not sure if a line break is required between commands.
II. Pre-battle Setup and Starting the Battle
The battle officially starts at the point where the viewer of the replay clicks the "play" button and officially ends when the replay's music stops and the replay declares the winner. While the pre-battle setup isn't vital to making the replay work, having all the pre-battle information set up makes the replay look more polished and gives the viewer all the information they need before beginning the battle.
The first commands you should put in your replay are the player declarations. This puts the player names on the sides of the replay and adds the sprites. A player declaration is formatted as follows:
|player|[player id]|[player name]|[sprite number]
[player id]
can be one of two values: "p1" or "p2". "p1" is the player on the viewer's side of the battlefield, while "p2" is the player on the opposite side of the battlefield.
[player name]
is simply the name of the player.
[sprite number]
is the number of the sprite used for the player. The sprites are numbered according to the numbering system Showdown uses. There is currently no good way to find the sprite number you want besides counting in the sprite sheet. I'm not planning on creating a numbered list of sprites anytime soon.
The next line is the style of battle you want to do. This guide is dedicated to the "singles" style, so for now the only code you'll put for this is |gametype|singles
.
The next command is the generation the battle takes place in. Odds are it will be |gen|7
. You can replace 7 with the number of the generation your battle is taking place in.
The next line is meant to be used for the tier of battle that is taking place. However, it can also be used to specify the base rules for a URPG match. For example:
|tier|6v6 Sun/Moon Public Open
Replace the rules above with whatever rules are used in the match you are scripting.
Any additional clauses used in the battle can be defines with the |rule
command. That command simply outputs the text you specify into the chat box in a distinctive style. So, for example, to specify that Sleep Clause is on, you would type:
|rule|Sleep Clause: Only one Pokemon asleep at a time
Next is setting up the team preview so the viewer can see what Pokémon were used in the battle. First use the |clearpoke
command to make sure there are no Pokémon already set that would mess up the preview. Then, you can add the Pokémon to your team preview. Use the following format:
|poke|[player id]|[pokemon name], [gender]
The player id should match the player id of the player using that Pokémon. The gender is simply specified by M or F. For genderless Pokémon, remove the comma and don't specify a gender (|poke|[player id]|[pokemon name]
).
Once all your Pokémon have been declared, you have to trigger the team preview. This does not trigger automatically, as Showdown does not show a preview for random battles. Additionally, you might want to skip the preview for URPG random battles. If you want to show the team preview, you do so with the |teampreview
command.
Now we're finally ready to actually start the battle. First use the |start
command to trigger the start of the battle. Anything you code after this will not apper until the viewer clicks the "play" button.
Then, you need to specify which Pokémon will be leading in the battle. This is done with the |switch
command. This will be explained in-depth later, but for now, format the code as follows:
|switch|p1a: [pokemon nickname]|[pokemon species], [gender]|[max hp]\/[max hp]
|switch|p2a: [pokemon nickname]|[pokemon species], [gender]|[max hp]\/[max hp]
If the Pokémon does not have a nickname, simply use the species name for the nickname. Lie with the team preview, omit the comma and gender for genderless Pokémon. p1a:
is the Pokémon for the player specified as "p1" and p2a:
is the Pokémon for the player specified as "p2".
The "p1a"/"p2a" section of the |switch
command is very important, as it sets up the idenitfier for the Pokémon. This identifier is how you will tell the engine which active Pokémon is using a move, taking damage, etc. For example, a Charizard being used by p2 without a nickname would be referred to as p2a: Charizard
, and a Togekiss named "Omelette" being used by p1 would be referred to as p1a: Omelette
.
Finally, use |turn|1
to signal the start of the first turn of your battle. Now you're ready to get started.
III. Moves, HP, and Status
Likely one of the first things that happens in the battle is one side or the other using a move. The Showdown Replay Engine is able to display move animations as you specify them, as well as announce that a move has been used. This is done with the |move
command. The format for using the move command is:
|move|[user id]|[move name]|[target id]
[user id]
is the identifier for the Pokémon using the move and [target id]
is the identifier for the Pokémon being targeted by the move. For attacking moves, the user will usually be the attacker and the target will be the one being attacked. For some status moves, the user and target will be the same.
[move name]
is simply the name of the move. This will tell the engine which animation to use to signify the attack. If you misspell the move's name or choose a move that does not exist, the engine will simply use a generic move animation.
Example:
|move|p1a: Charizard|Flamethrower|p2a: Venusaur
|move|p2a: Venusaur|Synthesis|p2a: Venusaur
You must manually designate the effectiveness of an attack. No designation is needed for normal effectiveness. Super effective attacks are designated with |-supereffective
, and not very effective attacks are designated with |-resisted
.
Example:
|-supereffective|p2a: Venusaur
|-resisted|p1a: Charizard
A move that has no effect is designated by |-immune
. This has a required suffix ([msg]
) to show the proper flavor text.
Example: |-immune|p1a: Charizard|[msg]
The hitpoints of a Pokémon are the most basic thing to keep track of in any replay, and arguably the most important. Since manipulating HP is something that will be done often, the commands required for it will become second-nature quickly.
The most basic HP command is |-damage
. The format for the damage command is:
|-damage|[pokemon id]|[new hp]\/[max hp]
[pokemon id]
is the identifier of the Pokémon that is taking damage. [new hp]
is the hitpoint value of the Pokémon after it has taken damage and [max hp]
is the maximum number of hitpoints the Pokémon taking damage can have. These values are turned into percentages by the engine.
Healing a Pokémon is done similarly to damaging it. You use the |-heal
command to do this.
|-heal|[pokemon id]|[new hp]\/[max hp]
You could probably use |-damage
to heal and |-heal
to cause damage, but that would throw off the flavor text, so using the right command at the right time is important.
Example:
|-damage|p2a: Venusaur|140\/364
|-heal|p2a: Venusaur|322\/364
Status effects are applied in two steps. First, to display the flavor text announcing the status effect, use |-status
.
Example: |-status|p1a: Charizard|psn
Then, you must include the three character abbreviation for the status effect in every damage statement until the status effect is removed or the Pokémon faints.
Example: |-damage|p2a: Venusaur|140\/364 brn
The abbreviations you can use are brn
, frz
, par
, psn
, and tox
.
When a Pokémon's hitpoints reach zero, apply the damage as normal, but add fnt
as if it was a status effect. Then, add a "faint" command imediately after.
Example: |faint|p2a: Venusaur
This plays the fainting animation, removing the Pokemon from the field and designating it as fainted in the team preview on the side. Use the "switch" command to designate the next active Pokémon.
At the end of each turn, once all actions have been performed, use |upkeep
to designate the end of the turn and perform any necessary end-of-turn animations.
Before beginning actions for the next turn, use another |turn
to designate the start of the new turn. Increment the number next to it for each new turn so the engine knows what turn number to display (|turn|2
, |turn|3
, etc.).
IV. Stat Changes
Stat changes are very simple to add into a replay. The Showdown Engine will keep track of all stat changes for you, so you simply have to tell it when a stat goes up or down. The first thing to learn is Showdown's abbreviations for each stat.
- atk - Attack
- def - Defense
- spa - Special Attack
- spd - Special Defense
- spe - Speed
Stats are increased with |-boost|[pokemon id]|[stat]|[stages]
. [stat]
is the abbreviation of the stat being increased, and [stages]
is how many stages it is being increaced (1 to 6).
Example: |-boost|p1a: Charizard|atk|2
Stats are decreased with |-unboost
. The usage is the same as |-boost
, the only difference being you designate how many stages to decrease the stat.
For moves like Belly Drum, you will want to set the number of stages a stat is boosted by instead of increasing it. This is done with |-setboost
. The usage is the same as the previous two, the difference being that you set what stage of boosting the stat is at.
For moves that copy the stat changes of the opposing Pokémon, you would use |-copyboost
. You designate the Pokémon recieving the boosts first, then the one providing them.
Example: |-copyboost|p2a: Venusaur|p1a: Charizard
For moves that remove all stat changes from a Pokémon, use |-clearboost
.
Example: |-clearboost|p2a: Venusaur
V. Abilities and Items
In a battle, each Pokémon has an ability and the option of holding an item. The Showdown Engine has flavor text set for a number of these. Using them in a replay adds to the polish and makes sure the viewer is entirely aware of what is happening in the battle.
For abilities that trigger when a Pokémon enters the field, |-ability
triggers the flavor text. This can also be used to designate when a Pokémon obtains a new ability.
Example: |-ability|p1a: Haxorus|Mold Breaker
Most of the time, you will not be using |-ability
. Instead, you can add suffixes to other statements to designate that a specific ability caused them. Most statements let you add [from]
to the end to add flavor text related to the ability designated.
Example: |-boost|p1a: Blaziken|spe|1|[from] ability: Speed Boost
Replacing "ability:" with "item:" or "move:" lets you add flavor text for certain moves or items as well. As a rule, if something in the battle happened as a result of a move, item, or ability, add [from]
to the end of it.
Example: |-heal|p2a: Mamoswine|129\/424|[from] item: Leftovers
Similar to |-ability
, there is |-item
for items that trigger when entering the field or for obtaining a new item. Most of the time, however, you will not use this.
Example: |-item|p1a: Heatran|Air Balloon
When a consumable item has been used or an item has been removed in another way, use |-enditem
.
Example: |-enditem|p2a: Espeon|Red Card
VI. Weather and Field Effects
The Showdown Engine gives visual reminders of any weather or other field effects that are active at any point in time. While it does track the number of turns, you must manually end them.
Weather is called with |-weather
. You specify the type of weather based on the move that calls it, or the ability that calls it for the harsh weather conditions (Primordial Sea, Desolate Land, Delta Stream).
Example: |-weather|Sunny Day
To end the weather, replace it with a new weather condition or set it to "none".
You can use [from]
to designate the ability/move that triggered the weather, and [of]
to further designate which Pokémon used the move/ability.
Example: |-weather|DeltaStream|[from] ability: Delta Stream|[of] p1a: Rayquaza
There are also various field effects that change the field in some way. There are two type of these: effects that affect only one side of the field and effects that affect the entire field.
For effects that only affect one side, use |-sidestart
. You will have to designate the id of the player whose side of the field is affected.
Example: |-sidestart|p1: Red|Stealth Rock
If a field effect set up like the one above expires, use |-sideend
to show that. The usage is the same as |-sidestart
.
Example: |-sideend|p2: Blue|Tailwind
For effects that affect the entire field, use |-fieldstart
and |-fieldend
.
Example:
|-fieldstart|move: Trick Room|[of] p1a: Porygon2
|-fieldend|move: Trick Room
There are many field effects, so the best way to find the one you are looking for is to find a Showdown-generated replay and check there.
VII. Other Important Actions
For moves that have an effect for one turn only, you can use |-singleturn
. The most common move that fits in the category is Protect.
Example: |-singleturn|p2a: Togekiss|Protect
Scripting Mega Evolution is a two step process. First, use |detailschange
to change the Pokémon from its normal form to its Mega form in the preview on the side. This is used similarly to |poke
from the very beginning.
Example: |detailschange|p2a: Gengar|Gengar-Mega, M
The second step is triggering the Mega Evolution animation and flavor text. This is done with |-mega
.
|-mega|[nickname]|[species]|[mega stone]
[nickname]
is whatever nickname you set for the Pokémon that is Mega Evolving. If none is set, this is the same as [species]
. [species]
is the species of the Pokémon Mega Evolving. [mega stone]
is whatever Mega Stone the Pokémon is holding.
Example: |-mega|p2a: Gengar|Gengar|Gengarite
For moves that miss, first add [miss]
to the end of the |move
statement. Then, add |-miss
as the next line.
|-miss|[user id]|[target id]
Example:
|move|p1a: Porygon2|Zap Cannon|p2a: Chandelure|[miss]
|-miss|p1a: Porygon2|p2a: Chandelure
For moves that fail to execute for some reason, use |-fail
immediately after the |move
statement.
Example: |-fail|p2a: Togekiss
Recoil damage is scripted the same way normal damage is. Add [from] recoil
to the end to trigger the appropriate flavor text.
Example: |-damage|p1a: Porygon2|149\/374|[from] recoil
Note that recoil damage is different from Life Orb damage. Life Orb has its own flavor text that is different than normal recoil, and should be designated with [from] item: Life Orb
like all other items.