Ask simple questions here! [READ ORIGINAL POST before posting]

Hecate

Be the serpent under't
is a Battle Simulator Administratoris a Community Leaderis a Programmer
PS Admin
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 Simulator Administratoris a Programmeris a Member of Senior Staffis a Community Contributoris a Smogon Discord Contributor Alumnus
PS Admin
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 Simulator Administratoris a Programmeris a Member of Senior Staffis a Community Contributoris a Smogon Discord Contributor Alumnus
PS Admin
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 Simulator Administratoris a Programmeris a Member of Senior Staffis a Community Contributoris a Smogon Discord Contributor Alumnus
PS Admin
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.
 
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
 
Hi, i have a server just for me and my friends, and we're making some fakemon.
I tried to add these fakemon but they dont appear in teambuilding listing, but if I use !data on them, it works. Can someone help me? :/

1537978798512.png


1537978819337.png
 

Lionyx

is a Battle Simulator Administratoris a Community Leaderis a Smogon Media Contributor Alumnus
PS Admin
Hi, i have a server just for me and my friends, and we're making some fakemon.
I tried to add these fakemon but they dont appear in teambuilding listing, but if I use !data on them, it works. Can someone help me? :/

View attachment 137678

View attachment 137679
The teambuilder doesn't depend on the server so you can't edit it with only the server files, I'd say you need to set up a custom client but don't know if that's actually feasible to modify the teambuilder that way, since I have never tried.
 
The teambuilder doesn't depend on the server so you can't edit it with only the server files, I'd say you need to set up a custom client but don't know if that's actually feasible to modify the teambuilder that way, since I have never tried.
I made a custom Metagame (named Fakemon Factory) for these fakemon im trying to add, and the teambuilder reads it.
1537989942318.png


The teambuilder doesnt get the pokemon list from the server?
 

Pikachuun

the entire waruda machine
The teambuilder doesnt get the pokemon list from the server?
correct. formats are handled through the server, while the teambuilder itself (for the most part) is handled with the client.
you can still use the mons in said format via import/exporting them in, but they won't display properly (probably as broken images)
 

HoeenHero

The Misspelled Hero!
is a Battle Simulator Administratoris a Programmeris a Member of Senior Staffis a Community Contributoris a Smogon Discord Contributor Alumnus
PS Admin
well, i wonder Why some specific IDs are not available, it shows disabled. anybody knows it?
There are multiple reasons for an account being disabled: Inactvity, the account is comprimised, the owner requested the name be disabled, or the name is considered inappropriate.
 

Adeleine

after committing a dangerous crime
is a Top Social Media Contributoris a Community Contributoris a Smogon Discord Contributoris a Top Contributoris a Smogon Media Contributoris a Battle Simulator Moderator Alumnus
Since registered accounts apply across Main to/and actual registered sub-servers of PS like Azure, you should be able to get that reset by posting a thread in Other Admin Requests, unless I misunderstand something specific about what you're asking.
 
My friend and I have been doing a CageLocke and we haven't played in a while so we forget who we gave TMs and items to and we would like to see if there is a way to look back at our battle history to see the fights we have done. Is this possible? Unfortunately we delete our teams afterwards since it is a one time battle for them so that won't be of use.
 

HoeenHero

The Misspelled Hero!
is a Battle Simulator Administratoris a Programmeris a Member of Senior Staffis a Community Contributoris a Smogon Discord Contributor Alumnus
PS Admin
My friend and I have been doing a CageLocke and we haven't played in a while so we forget who we gave TMs and items to and we would like to see if there is a way to look back at our battle history to see the fights we have done. Is this possible? Unfortunately we delete our teams afterwards since it is a one time battle for them so that won't be of use.
Unless you saved replays no. If there are replays check https://replay.pokemonshowdown.com/ for them
 

Users Who Are Viewing This Thread (Users: 1, Guests: 4)

Top