Skip to content

Instantly share code, notes, and snippets.

@dtalley11

dtalley11/pssdoc.md

Last active Nov 4, 2020
Embed
What would you like to do?
General documentation for modifying Pokemon Showdown

Pokemon Showdown Source Documentation

Due to the amount of interest in adding pokemon to the source, I have decided to create a little bit of documentation to help explain modify the source to add and modify formats and Pokemon.

Table of Contents

Adding and Modifying Formats in Pokemon Showdown

The various formats in Pokemon Showdown are defined in config/formats.js, but the rules and bannings that the formats follow are defined in data/rulesets.js

config/formats.js

This defines each format displayed in the list, which section to catagorize it in and the various rules and banings for the format

// CAP Little Cup format definition in formats.js
{
	name: "CAP LC", // This shows up on the list of formats
	section: "Other Metagames", // This is what catagory it is listed under
	// This is a list of each ruleset that the format follows. Rulesets are defined in data/rulesets.js
	ruleset: ['CAP Pokemon', 'Standard', 'Team Preview', 'Little Cup'], 
	// This is a combonation of banned groups, single pokemon and single items
	banlist: ['Uber', 'Soul Dew', 'Gengarite', 'Kangaskhanite', 'Sonicboom', 'Dragon Rage', 'Scyther', 'Sneasel', 'Yanma', 'Tangela'] 
},

data/rulesets.js

Rulesets.js is a complicated but aptly named file that handles the rules for each format. Most rules are broken up between the actual rules (general stipulations on which pokemon can enter, if Team Preview is used and the various clauses) and ban lists

// Rules for CAP  
cappokemon: {
	effectType: 'Rule', // For this, it's usually a Rule or Banlist
	validateSet: function(set, format) {
		return this.getEffect('Pokemon').validateSet.call(this, set, format, true);
	}
},
// Standard Banlist
standard: {
	effectType: 'Banlist',
	ruleset: ['Sleep Clause Mod', 'Species Clause', 'OHKO Clause', 'Moody Clause', 'Evasion Moves Clause', 'Endless Battle Clause', 'HP Percentage Mod'],
	banlist: ['Unreleased', 'Illegal']
},
// Little Cup rules
littlecup: {
	effectType: 'Rule',
	validateSet: function(set) {
		var template = this.getTemplate(set.species || set.name);
		if (template.prevo) {
			return [set.species+" isn't the first in its evolution family."];
		}
		if (!template.nfe) {
			return [set.species+" doesn't have an evolution family."];
		}
	}
},

Adding and Modifying Pokemon in Pokemon Showdown's Server

Expanded and flattened data structures are seen the same way by the node.js, but flattened structures tend to be more difficult for people to read and expanded structures use more resources to host

Structures will be modified and created while expanded (also easier to see typos) but implemented after they have been flattened

My other version of this, when I was just making myself some notes can be found here: http://pastebin.com/dj1FrW7f

Pokedex.js

pokedex.js is where each pokemon is defined, and contains general information about each pokemon

Pokedex.js (flattened)

syclar:{num:-101,species:"Syclar",types:["Ice","Bug"],genderRatio:{M:0.5,F:0.5},baseStats:{hp:40,atk:76,def:45,spa:74,spd:39,spe:91},abilities:{0:"Compound Eyes",1:"Snow Cloak"},heightm:0.2,weightkg:4.0,color:"",evos:["syclant"],eggGroups:["Bug"]}

Pokedex.js (expanded)

syclar:{
		num:-101, // Pokedex Number
		species:"Syclar", // Friendly Species name (can use caps and space)
		types:["Ice","Bug"], // List of types (["type"] for mono or ["typea","typeb"] for dual types)
		genderRatio:{M:0.5,F:0.5}, // Genderless pokemon and pokemon with only 1 gender are done using gender:"N", gender:"M"/"F"
		baseStats:{hp:40,atk:76,def:45,spa:74,spd:39,spe:91},
		abilities:{0:"Compound Eyes",1:"Snow Cloak"}, // {index:"string"}
		heightm:0.2,
		weightkg:4.0,
		color:"", // if this has no color, make it a empty string
		evos:["syclant"], // don't bother defining this if it does not evolve
		eggGroups:["Bug"] // another list ["group"] or ["groupa","groupb"]
},

Learnset.js

learnset.js list each move for each pokemon, and how the move is learned

  • This DOES NOT need to be in alphabetical order.
  • The move Return needs to be delimited for every Pokemon, so it looks like "return". (otherwise javascript will interpret it wrong)
  • Moves in this file do not contain spaces or capital letters.
  • L is moves learned when leveling up (xLy where x is the generation and y is the * level it learns it).
  • T is Moves learned from the Tutor (xT, where x is the generation).
  • M is Learned from a Technical or Hidden Machine (TM/HM) (xM where x is the generation).
  • E is for Egg Moves (xE where x is the generation).

Learnset.js (flattened)

syclar:{learnset:{furyattack:["6L1"],leer:["6L1"],leachlife:["6L5"],iceshard:["6L8"],focusenergy:["6L13"],icywind:["6L18"],xscissor:["6L23"],hail:["6L28"],bugbuzz:["6L42"],sheercold:["6L49"],bugbite:["6T"],counter:["6T"],earthpower:["6T"],furycutter:["6T"],icywind:["6T"],mimic:["6T"],snore:["6T"],stringshot:["6T"],superpower:["6T"],waterpulse:["6M"],toxic:["6M"],hail:["6M"],hiddenpower:["6M"],taunt:["6M"],icebeam:["6M"],blizzard:["6M"],protect:["6M"],frustration:["6M"],"return":["6M"],doubleteam:["6M"],facade:["6M"],secretpower:["6M"],rest:["6M"],attract:["6M"],falseswipe:["6M"],fling:["6M"],endure:["6M"],silver Wind:["6M"],avalanche:["6M"],swordsdance:["6M"],captivate:["6M"],xscissor:["6M"],sleeptalk:["6M"],naturalgift:["6M"],swagger:["6M"],uturn:["6M"],substitute:["6M"],cut:["6M"],earthpower:["6E"],pinmissile:["6E"],spikes:["6E"],superpower:["6E"],tailglow:["6E"]}},

Learnset.js (expanded)

syclar:{
		learnset:{
				furyattack:["6L1"],
				leer:["6L1"],
				leachlife:["6L5"],
				focusenergy:["6L13"],
				...
				frustration:["6M"],
				// Return needs to be in quotes otherwise JS thinks it's the function return
				"return":["6M"],
				doubleteam:["6M"],
				...
				pinmissile:["6E"],
				tailglow:["6E"]
		}
},

formats-data.js

formats-data.js has information for each pokemon, more specific to Pokemon Showdown.

  • Moves in this file are delimited and do not contain spaces or capital letters

formats-data.js (flattened)

syclar: {
		viableMoves: {"furyattack":1,"leer":1,"leechlife":1,"iceshard":1,"focusenergy":1,"icywind":1,"xscissor":1,"hail":1},
		isNonstandard: true,
		tier: "CAP"
}

formats-data.js (expanded)

syclar: {
		viableMoves:{ // I don't know what the 1 is for, but every move for every pokemon is like this
				"furyattack":1,
				"leer":1,
				"leechlife":1,
				"iceshard":1,
				"focusenergy":1,
				"icywind":1,
				"xscissor":1,
				"hail":1
		},
		isNonstandard: true,
		tier: "CAP"
},

Adding and Modifying Pokemon in Pokemon Showdown's client

Aside from the server side edits, the pokemon showdown client needs to be modified to display and fully support new and modified pokemon (though the server changes are good enough for testing)

Sprites

To get Pokemon Showdown's Client to have sprites for custom pokemon, battledata.js needs to be modified, and all other sprites need to be hosted.

Battledata.js Edits

in battledata.js the following function needs to be modifed

resourcePrefix: (function() {
	var prefix = '';
	if (document.location.protocol === 'file:') prefix = 'http:';
	return prefix + '//play.pokemonshowdown.com/'; // this is the prefix it uses to fetch resources, like sprites
})(),

Getting the Resources

using wget (or wget for windows), this script can download most of the files from the server, and removes the index.htmls

# Download all the sprites
wget --execute="robots = off" --mirror --convert-links --no-parent http://play.pokemonshowdown.com/sprites/
# Download all the audio
wget --execute="robots = off" --mirror --convert-links --no-parent http://play.pokemonshowdown.com/audio/
# Download other resources
wget --execute="robots = off" --mirror --convert-links --no-parent http://play.pokemonshowdown.com/fx/
# remove index.html files
rm $(find ./play.pokemonshowdown.com/ -name 'index.html*')

The previous scripts missed the trainer sprites, so here is a loop that goes through and downloads them:

# Download the range of trainer sprites from 1 to 294
for i in {1..294}
	do wget http://play.pokemonshowdown.com/sprites/trainers/$i.png
	done 

Adding New sprites

To add new sprites for a pokemon, there needs to be 4 unique images:

  1. The normal front sprite
  2. the back sprite
  3. the shiny front sprite
  4. the shiny back sprite

Each image needs to be on a 96x96 canvas, png file format and they need to have transparent backgrounds. The Server expects each image to be in it's corresponding folder. There are 4 folders:

  1. sprites/bw
  2. sprites/bw-back
  3. sprites/bw-shiny
  4. sprites/bw-back-shiny

The name of each image is expected to be the pokemon's name (all lowercase, no spaces) and the .png file extension.

Note that this is not for animations and mini-sprites. Animations have their own folders that they go in, and mini-sprites are part of a sprite sheet.

Recently, Pokemon Showdown added gif images that had animations from pokemon X/Y. I was worried this was going to cause a problem with your Black/White sprites, but thus far it has not. For future reference, X/Y anumations are in sprites/xyani, sprites/xyani-back etc.

Data Files

in /data there are a few files that have to be changed to accommodate for the new pokemon. Most of the changes are already done on the server side in the /data folder, and the files just need to be copied over to the client. One specific file still needs to be changed specifically for the client.

Pokedex-mini.js

pokedex-mini.js looks similar to pokedex.js, but has info regarding animated sprites for each pokemon. Not all pokemon need to have an animation, but they do need to have a entry in this file. If the pokemon doesn't have an animation, then just put it's pokedex number.

"binacle":{num:688, front:{ani:{w: 96, h: 96}},back:{ani:{w: 96, h: 96}}},
"barbaracle":{num:689},

learnsets-g6.js

This file is a data structure with gen6 specific movesets. Because we code our moves for gen 6, this needs to be updated with the same data that went in Learnset.js for teambuilder to work correctly

References

@jbella5

This comment has been minimized.

Copy link

@jbella5 jbella5 commented Jan 20, 2016

What kind of testing can I do without modifying the client? Should I at least be able to see a Pokemon I created in the team builder (because I can't). And modifying the client doesn't seem to help with this. I'm not sure what I'm doing wrong. To test it most simply, I tried adding aquatail to Ditto's movepool, but that didn't show up as valid when I tested it.

@dtalley11

This comment has been minimized.

Copy link
Owner Author

@dtalley11 dtalley11 commented Jan 23, 2016

I have not worked with this in a long time, but if you haven't modified with the client then you're limited to working around team builder. One of the problems I remember is if you add a move to a poke's pool in the server but not the client you it wouldn't show up in team builder. I think I recall using the import/export feature and manually tyoing in the move to get around this specific problem. I seem to remember this being the case for custom poke's as well.

If push comes to shove, so long as you for everything right in import/export you should be able to use any custom poke's in a custom match.

@dtalley11

This comment has been minimized.

Copy link
Owner Author

@dtalley11 dtalley11 commented Jan 23, 2016

Also this document is nearly two years old and I don't know how much of it is still relevant. However, I do know that the client resource stuff is out of date. For example, PS added 3D gifs under some x/y folder since I wrote this. I also never wrote instructions on how to add a mini-icon for team builder.

@XBagon

This comment has been minimized.

Copy link

@XBagon XBagon commented Jul 13, 2019

is there a newer version of this? I'm wondering what 7V and xSy stands for in learnset.js.

@bajunkins

This comment has been minimized.

Copy link

@bajunkins bajunkins commented Sep 20, 2019

A more updated version of this would be awesome, lot of things have changed since this evidently

@Dedemetrionator

This comment has been minimized.

Copy link

@Dedemetrionator Dedemetrionator commented Oct 23, 2020

why can't I find these files in the client master on my pc?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment