Ask A Simple Question, Get A Simple Answer - PS! Edition (please read before posting a thread)

Hey, this is more of a technical question and I'm not sure if anyone will be able to answer, but I figured I might ask anyway...

I've been wanting to make my own Showdown Battle API for a while, but I have no idea where to start. I don't need it to do much, just start a battle and then send progress updates back to my server where I'll send back commands to make specific moves etc...

  • How does authentication work? Is there a way to authenticate outside the client?
  • I heard that Showdown uses sock.js for WebSockets, is this correct?
  • Has anyone made something similar before?
Worst case I'll just use Selenium, but I'd prefer to remain browser-free since I'll want to run 5-6 games at once.

I'm assuming this is best done with NodeJS, but I can use Python 3 as well.
 

HKT

formerly Heika
Quite a time ago now, a friend of mine has been auto lock for posting a screamer. So I was currious about this rule since I didn’t find out where it was written.
I’m not contesting such things, as it’s obviously bad to post screamers but I believe it should be shown on the rule page of showdown.
If it’s include in « respect the US law » I apologies but not totally as this sentance is an exemple of how fuzzy rules are (at least half showdown users ain’t from US so don’t know US law)
 

HoeenHero

The Misspelled Hero!
is a Battle Server Administratoris a Community Leaderis a Programmer
Community Leader
Its not a direct rule, but It can fall under
Global:
1. Be nice to people. Respect people. Don't be rude or mean to people.
5. Moderators have discretion to punish any behaviour they deem inappropriate, whether or not it's on this list. If you disagree with a moderator ruling, appeal to a leader (a user with & next to their name) or Discipline Appeals.

Chat:
1. Do not spam, flame, or troll. This includes advertising, raiding, asking questions with one-word answers in the lobby, and flooding the chat such as by copy/pasting logs in the lobby. (trolling specifically)

As for global rule 5, its not really appropriate to post something thats meant to shock/scare other people. We filter them to prevent trolls from randomly posting them in chats.
 
So I've noticed Gallade, Gardevoir and Mega-Absol have new animations, I was wondering a few things:
-are there any more new animations?
-why are there are new animations?
-who made them?
 
So I've noticed Gallade, Gardevoir and Mega-Absol have new animations, I was wondering a few things:
-are there any more new animations?
-why are there are new animations?
-who made them?
There’s also typhlosion, snorlax and espeon for new ones. they were added since staff liked them better iirc. And DJTHED made them
(Here’s the link to his display thread if you so desire to see)
 
Last edited:
This was probably asked already, but how did you guys get permission to make Showdown! and use copyrighted stuff?

Edit: What are all the soundtracks that Showdown! has now?
 
Last edited:
Sorry I haven't had the time to read through this whole thread so I don't know if a question like the one I have now has been answered so I apologize in advance, but anyway:

If I wanted to do something like bring down Mew from Ubers into Gen 4 OU and play on a private server/room/whatever it is called, would this be possible? If so, what would be the steps to make it happen? I'm not super well known in Smogon or anything so I don't particularly know the power hierarchy here and who controls what. Just curious on whether or not things like this are possible and happen here.
 
What's the maximum number of Pokemon that you can bring to a Custom Battle?
24 pokemon is the maximum.
Sorry I haven't had the time to read through this whole thread so I don't know if a question like the one I have now has been answered so I apologize in advance, but anyway:

If I wanted to do something like bring down Mew from Ubers into Gen 4 OU and play on a private server/room/whatever it is called, would this be possible? If so, what would be the steps to make it happen? I'm not super well known in Smogon or anything so I don't particularly know the power hierarchy here and who controls what. Just curious on whether or not things like this are possible and happen here.
from what I’m reading, no it isn’t, since Mew is Ubers in Gen 4. though you could play Custom Game with a gen 4 team, that’s as close as you could get.
 
Sorry I haven't had the time to read through this whole thread so I don't know if a question like the one I have now has been answered so I apologize in advance, but anyway:

If I wanted to do something like bring down Mew from Ubers into Gen 4 OU and play on a private server/room/whatever it is called, would this be possible? If so, what would be the steps to make it happen? I'm not super well known in Smogon or anything so I don't particularly know the power hierarchy here and who controls what. Just curious on whether or not things like this are possible and happen here.
You could do it in a tour, with the command /tour rules +mew. That would require a roomdriver / mod (depending on per issions) from a room to agree. Ruins of Alph would probably be your best bet.

Alternatively, you could ask for a match in such a metagame, and simply play in ubers witha gentlemans agreement.
 
Hey, this is more of a technical question and I'm not sure if anyone will be able to answer, but I figured I might ask anyway...

I've been wanting to make my own Showdown Battle API for a while, but I have no idea where to start. I don't need it to do much, just start a battle and then send progress updates back to my server where I'll send back commands to make specific moves etc...

  • How does authentication work? Is there a way to authenticate outside the client?
  • I heard that Showdown uses sock.js for WebSockets, is this correct?
  • Has anyone made something similar before?
Worst case I'll just use Selenium, but I'd prefer to remain browser-free since I'll want to run 5-6 games at once.

I'm assuming this is best done with NodeJS, but I can use Python 3 as well.
Is there any answer for this guy? I want to know too.
 

HoeenHero

The Misspelled Hero!
is a Battle Server Administratoris a Community Leaderis a Programmer
Community Leader
Hey, this is more of a technical question and I'm not sure if anyone will be able to answer, but I figured I might ask anyway...

I've been wanting to make my own Showdown Battle API for a while, but I have no idea where to start. I don't need it to do much, just start a battle and then send progress updates back to my server where I'll send back commands to make specific moves etc...

  • How does authentication work? Is there a way to authenticate outside the client?
  • I heard that Showdown uses sock.js for WebSockets, is this correct?
  • Has anyone made something similar before?
Worst case I'll just use Selenium, but I'd prefer to remain browser-free since I'll want to run 5-6 games at once.

I'm assuming this is best done with NodeJS, but I can use Python 3 as well.
Is there any answer for this guy? I want to know too.
Didn't see the question till now sorry.

I'm not an expert in the area of authentication for PS, but I have written a bot with NodeJs.

When you connect to showdown, PS sends you a chalstring in the form of |chalstr|str. You'll want to make a HTTP GET or HTTP POST request to http://play.pokemonshowdown.com/action.php depending on what exactly your trying to do. (You can also use a HTTPS request).
  • If your trying to login to an unregistered name, you'll want to make a GET request with ?act=getassertion&userid=userid&challstr=chalstr where userid is the userid of the username you want to login to (all lowercase letters/numbers, no spaces, no symbols), and chalstr is your chalstring.
  • If your trying to login to a registered name, you'll want to make a POST request with act=login&name=userid&pass=password&challstr=chalstr where userid is the userid of the username you want to login to, password is the password (case sensetive of course), and chalstr is the your chalstring.
  • If your trying to login to a name you have session cookies for, use ?act=upkeep&challstr=chalstr where chalstr is your chalstring.
After sending the chalstr, you should get a response from the login server. This could be a number of things including:
  • ; meaning the name you chose is registered, and you did not provide a password, or provided an incorrect password.
  • A message explaining why the login failed.
  • If you made a POST login request: A JSON object starting with ] that contains what you need to login. You'll want to parse it and access the assertion property since youll need it to login.
  • If you made a GET login to an unregistered name request: A string of characters that you will need to use to login (your assertion).
After getting your assertion, go ahead and send /trn Username,0,assertion where Username is your Username (case sensetive), and assertion is the assertion you got from your HTTP(S) request.
An example implementation that I use can be seen below:
JavaScript:
            this.challstr = parts.join('|');
            const reqOptions = {
                hostname: "play.pokemonshowdown.com",
                path: "/~~showdown/action.php",
                agent: false,
            };

            let loginQuerystring;
            if (!Config.pass) {
                reqOptions.method = 'GET';
                reqOptions.path += `?act=getassertion&userid=${toId(Config.nick)}&challstr=${this.challstr}`;
            } else {
                reqOptions.method = 'POST';
                loginQuerystring = `act=login&name=${toId(Config.nick)}&pass=${Config.pass}&challstr=${this.challstr}`;
                reqOptions.headers = {
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Content-Length': loginQuerystring.length,
                };
            }
            debug(`Sending login to ${reqOptions.path}${loginQuerystring ? ` | Data: ${loginQuerystring}` : ''}`);

            const req = https.request(reqOptions, res => {
                res.setEncoding('utf8');
                let data = '';
                res.on('data', chunk => {
                    data += chunk;
                });
                res.on('end', () => {
                    if (data === ';') {
                        console.log(`LOGIN FAILED - The name ${Config.nick} is registered and ${Config.pass ? 'an invalid' : 'no'} password was provided.`);
                        process.exit(1);
                    }
                    if (data.length < 50) {
                        console.log(`LOGIN FAILED - ${data}`);
                        process.exit(1);
                    }
                    if (data.indexOf('heavy load') > -1) {
                        console.log(`LOGIN FAILED - The login server is experiencing heavy load and cannot accommodate the bot's connection right now.`);
                        process.exit(1);
                    }
                    try {
                        data = JSON.parse(data.slice(1));
                        if (data.actionsuccess) {
                            data = data.assertion;
                        } else {
                            console.log(`Unable to login; the request was unsuccessful\n${JSON.stringify(data)}\n`);
                            process.exit(1);
                        }
                    } catch (e) {}
                    // Autojoining should be handled before sending /trn; since only
                    // eleven rooms can be autojoined at a time, leave any extras to
                    // be joined manually. (This allows the server to remember the first
                    // eleven if you happen to cut back on rooms)
                    if (Config.autojoin.length) {
                        const [autojoin, extra] = [Config.autojoin.slice(0, 11), Config.autojoin.slice(11)];
                        this.send(`|/autojoin ${autojoin.join(',')}`);
                        if (extra.length) this.extraJoin = extra;
                    }
                    this.send(`|/trn ${Config.nick},0,${data}`);
                });
            });
            req.on('error', e => {
                console.error(`Error while logging in: ${e.stack}`);
                return;
            });
            if (loginQuerystring) req.write(loginQuerystring);
            req.end();
See also: https://github.com/Zarel/Pokemon-Showdown/blob/master/PROTOCOL.md#global-messages (chalstr)
Let me know if there are any other questions.
 
Last edited:
Didn't see the question till now sorry.

I'm not an expert in the area of authentication for PS, but I have written a bot with NodeJs.

When you connect to showdown, PS sends you a chalstring in the form of |chalstr|str. You'll want to make a HTTP GET or HTTP POST request to http://play.pokemonshowdown.com/action.php depending on what exactly your trying to do. (You can also use a HTTPS request).
  • If your trying to login to an unregistered name, you'll want to make a GET request with ?act=getassertion&userid=userid&challstr=chalstr where userid is the userid of the username you want to login to (all lowercase letters/numbers, no spaces, no symbols), and chalstr is your chalstring.
  • If your trying to login to a registered name, you'll want to make a POST request with act=login&name=userid&pass=password&challstr=chalstr} where userid is the userid of the username you want to login to, password is the password (case sensetive of course), and chalstr is the your chalstring.
  • If your trying to login to a name you have session cookies for, use ?act=upkeep&challstr=chalstr where chalstr is your chalstring.
After sending the chalstr, you should get a response from the login server. This could be a number of things including:
  • ; meaning the name you chose is registered, and you did not provide a password, or provided an incorrect password.
  • A message explaining why the login failed.
  • If you made a POST login request: A JSON object starting with ] that contains what you need to login. You'll want to parse it and access the assertion property since youll need it to login.
  • If you made a GET login to an unregistered name request: A string of characters that you will need to use to login (your assertion).
After getting your assertion, go ahead and send /trn Username,0,assertion where Username is your Username (case sensetive), and assertion is the assertion you got from your HTTP(S) request.
An example implementation that I use can be seen below:
JavaScript:
            this.challstr = parts.join('|');
            const reqOptions = {
                hostname: "play.pokemonshowdown.com",
                path: "/~~showdown/action.php",
                agent: false,
            };

            let loginQuerystring;
            if (!Config.pass) {
                reqOptions.method = 'GET';
                reqOptions.path += `?act=getassertion&userid=${toId(Config.nick)}&challstr=${this.challstr}`;
            } else {
                reqOptions.method = 'POST';
                loginQuerystring = `act=login&name=${toId(Config.nick)}&pass=${Config.pass}&challstr=${this.challstr}`;
                reqOptions.headers = {
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Content-Length': loginQuerystring.length,
                };
            }
            debug(`Sending login to ${reqOptions.path}${loginQuerystring ? ` | Data: ${loginQuerystring}` : ''}`);

            const req = https.request(reqOptions, res => {
                res.setEncoding('utf8');
                let data = '';
                res.on('data', chunk => {
                    data += chunk;
                });
                res.on('end', () => {
                    if (data === ';') {
                        console.log(`LOGIN FAILED - The name ${Config.nick} is registered and ${Config.pass ? 'an invalid' : 'no'} password was provided.`);
                        process.exit(1);
                    }
                    if (data.length < 50) {
                        console.log(`LOGIN FAILED - ${data}`);
                        process.exit(1);
                    }
                    if (data.indexOf('heavy load') > -1) {
                        console.log(`LOGIN FAILED - The login server is experiencing heavy load and cannot accommodate the bot's connection right now.`);
                        process.exit(1);
                    }
                    try {
                        data = JSON.parse(data.slice(1));
                        if (data.actionsuccess) {
                            data = data.assertion;
                        } else {
                            console.log(`Unable to login; the request was unsuccessful\n${JSON.stringify(data)}\n`);
                            process.exit(1);
                        }
                    } catch (e) {}
                    // Autojoining should be handled before sending /trn; since only
                    // eleven rooms can be autojoined at a time, leave any extras to
                    // be joined manually. (This allows the server to remember the first
                    // eleven if you happen to cut back on rooms)
                    if (Config.autojoin.length) {
                        const [autojoin, extra] = [Config.autojoin.slice(0, 11), Config.autojoin.slice(11)];
                        this.send(`|/autojoin ${autojoin.join(',')}`);
                        if (extra.length) this.extraJoin = extra;
                    }
                    this.send(`|/trn ${Config.nick},0,${data}`);
                });
            });
            req.on('error', e => {
                console.error(`Error while logging in: ${e.stack}`);
                return;
            });
            if (loginQuerystring) req.write(loginQuerystring);
            req.end();
See also: https://github.com/Zarel/Pokemon-Showdown/blob/master/PROTOCOL.md#global-messages (chalstr)
Let me know if there are any other questions.
Thanks so much Hoeen Hero! I've snooped around on GitHub and you seem to have a lot of commits. Great job, thanks for helping make Showdown awesome!

If I want to create a pokemon showdown battle bot, which programming language would be the best to be used?
I would recommend NodeJS, it's what Showdown is written in and it's great for bots!
 
hey, for some reason i can't log into the downloaded version of pokemon showdown or the web version. i tried changing my password twice already and it's been a few days
 

HoeenHero

The Misspelled Hero!
is a Battle Server Administratoris a Community Leaderis a Programmer
Community Leader
The first is the client repo, which is the code that is run on your web browser. The second is the server, which is what your web browser conencts to so you can talk to other users and battle.
 

HoeenHero

The Misspelled Hero!
is a Battle Server Administratoris a Community Leaderis a Programmer
Community Leader
And where can I find the logics of pokemon battle? Which directory or which file?

Ty
the sim and data directories hold what your looking for (in gen7) https://github.com/Zarel/Pokemon-Showdown/tree/master/sim https://github.com/Zarel/Pokemon-Showdown/tree/master/data . for older gens, look in their mod folders as well mods/gen#/ https://github.com/Zarel/Pokemon-Showdown/tree/master/mods/gen6 Please note that mods inherit the base code (gen7 aka the data folder) or another mod (ex gen5 inherits gen6, gen4 inherits gen5...) meaning that the code is a slightly modified version of the code it inherits (its a chain with the generation mods). This means that functions/ect that arent changed arent included in the mod's files, they would be in the respective data/ file.
 

Users Who Are Viewing This Thread (Users: 2, Guests: 0)

Top