• The moderator of this forum is jetou.
  • Welcome to Smogon! Take a moment to read the Introduction to Smogon for a run-down on everything Smogon, and make sure you take some time to read the global rules.

Programming How to gather information about a Battle going on in showdown

I wanted to create an extension that required getting the information about the battle, what moves have been used so far etc. However, I'm not sure how I'd go about it.

I originally tried to use the websocket functionality to do what I wanted but I thought that'd be overkill since I didn't want to interact with anyone, but
just get an idea of what moves have been used in battle.

I then tried to use the protocol here at simultor.md but I was just unable to install `pokemon-showdown` using npm or bun. I just couldn't import it or use require to use it (it wasn't just for the extension where I had modules set to true in package.json, but I also tried it in a different random react project and the import failed there too). What could I use then so that in a browser extension, you can get the battle data of the page the extension is loaded into?
 
If you want something that will work out of the box you have the fulllifegame scouter API

Another solution is to use the official game parser you can find it in the battle.ts file on the official pokemon showdown client repo.

Otherwise you can write your own scouter that take the log file of a replay as an argument. You can get such log through a method of the battle object : var log = battle.stepQueue.join('\n')
 
Last edited:
If you want here's an example with the beautiful pkmn/client package from pre that replicates the battle class from the pokemon showdown official client in a smaller env

JavaScript:
import {Generations} from '@pkmn/data';
import {Dex} from '@pkmn/dex';
import {Sets} from '@pkmn/sets';
import {Battle} from '@pkmn/client';

var log = `[insert replay log here]`;

const battle = new Battle(new Generations(Dex));

for (const line of log.split('\n')) {
  battle.add(line);
}
battle.update(); // optional, only relevant if stream contains |request|
console.log(battle.p1.team[0]); //get the first pokemon objet of player1 with all the revealed info !
source: https://github.com/pkmn/ps/tree/main/client#usage

if you're using the official client you can use battle.seekBy(Infinity); to get to the end of the battle and therefore get your scout in the battle.p[1or2].team objet

In fact if you're doing an extension everything from the client is already imported so the Battle class is already accesible as a global variable, pre packages in browser are mostly useful for server stuff but you only need client stuff to get a scout.

edit: if your extension is loaded lets say in a live pokemon battle such as play.pokemonshowdown.com/gen9ou-XXXXX then the battle object is already instanced so you can just get the team like that battle.p1.pokemon
 
Last edited:
If you want here's an example with the beautiful pkmn/client package from pre that replicates the battle class from the pokemon showdown official client in a smaller env
JavaScript:
import {Generations} from '@pkmn/data';
import {Dex} from '@pkmn/dex';
import {Sets} from '@pkmn/sets';
import {Battle} from '@pkmn/client';

var log = `[insert replay log here]`;

const battle = new Battle(new Generations(Dex));

for (const line of log.split('\n')) {
  battle.add(line);
}
battle.update(); // optional, only relevant if stream contains |request|
console.log(battle.p1.team[0]); //get the first pokemon objet of player1 with all the revealed info !
source: https://github.com/pkmn/ps/tree/main/client#usage

if you're using the official client you can use battle.seekBy(Infinity); to get to the end of the battle and therefore get your scout in the battle.p[1or2].team objet

In fact if you're doing an extension everything from the client is already imported so the Battle class is already accesible as a global variable, pre packages in browser are mostly useful for server stuff but you only need client stuff to get a scout.

edit: if your extension is loaded lets say in a live pokemon battle such as play.pokemonshowdown.com/gen9ou-XXXXX then the battle object is already instanced so you can just get the team like that battle.p1.pokemon
Thank you so much for your reply, but I assume the post above your edit is if I have the battle/link itself? I wanted to get information about the battle when the user is playing a battle, I want to know about what's going on in a battle. I tried doing as you said in the edit, and tried `battle.p1.pokemon` in the console, but then I got
1734589228511.png
. What am I doing wrong in this case?
 
Last edited:
you must put the battle object in its context (eg: using the 'this' keyword)

1734611237101.png


You can also acces it easily with jquery using the $ alias


If there are multitude battles ongoing you can acces them throughs the rooms array
 
Last edited:
you must put the battle object in its context (eg: using the 'this' keyword)

View attachment 696596

You can also acces it easily with jquery using the $ alias


If there are multitude battles ongoing you can acces them throughs the rooms array
I have another question about the room object. Is it possible to suppress the "Your replay has been uploaded!" popup when calling "this.room.send('/savereplay')"? Or is there a better way to save the replay of a battle without any popups in the background?
 
I have another question about the room object. Is it possible to suppress the "Your replay has been uploaded!" popup when calling "this.room.send('/savereplay')"? Or is there a better way to save the replay of a battle without any popups in the background?
the popup is sent from the server so idk so
 
i mean you can alway do something very junky by redefining the method that generate the popup so it doesnt show up after ypi dp /send savereplay but it would be very terrible code (i do that all the time)
 
Back
Top