• Follow our Instagram!
  • Curious about what we're currently doing about bots? Check out the latest updates from staff in this thread.

Policy Review Sweepiness Rework

quziel

I am the Scientist now
is a Site Content Manager Alumnusis a Forum Moderator Alumnusis a Community Contributor Alumnusis a Smogon Discord Contributor Alumnusis a Top Metagame Resource Contributor Alumnusis a Top CAP Contributor Alumnusis a Contributor Alumnusis a Battle Simulator Staff Alumnus
Starting this up early cause there's a lot of talk about it in the current process.

So sweepiness currently doesn't fit our understanding of Pokemon. Currently its nearly flat at high speed-factors (sf), whereas in reality we know that going from outrunning Stratagem to outrunning Dragapult is a huge increase in overall power. For example, with t=2.25 and 145 SpA, going from 129 to 144 speed increases BSR by 2. Not 20, 2. This needs to be fixed. Speed factor is also for all mons, not all relevant mons, which has causes some issues.

Let me make some assumptions:
1) Sweepiness should depend on your ability to get KOs, and your ability to outrun mons. That is, it should be some function of SpA and speed.
2) Each additional mon you outrun is more valuable than the last. This is not strictly true, but its approximately true and that's all we need.
3) There should be some user-tunable parameter that we can adjust to account for trying to use the same formula for both Obliteryx and Chuggalong.

How then can we model speed.

The current formula is (sf+t) / (1-sf +t) where t is a "turns parameter", intended to be the average number of turns before 'speed matters' for our role. In practice this has been set between about 1.75 and 3 for all the CAPs I've ever seen. sf is just the fraction of pokemon in the meta we outrun, ignoring evs and any speed modifiers. To turn this into words. Speed only matters on the turn a KO happens.

One approach would be to keep sf, as its a decent "probability of outrunning a randomly selected mon" and just use it differently. I've proposed "probability of outrunning at least k of 6 mons on an opponent's team". I like that one as it exhibits the exponential increase in sweepiness as sf => 1 for high k, but is it ideal?

I'd appreciate thoughts from anyone with experience in both mons and any kind of mathematical modelling, as well as practical approaches to modifying all parts of the formula. I know there was an internal approach to modifying BSR, but its been years hence making this post.

Currently I'm not trying to propose any changes, but more just looking for the functional forms we may want to explore, as well as any challenges to the assumptions I've made.

Edit: Keep in mind that any formula we eventually use should be easy to add into an excel sheet.
 
Last edited:
Before we get too technical, lets lay out as a baseline the goal; namely, to derive, from SpA and Spe (or physical equivalent_, roughly how potent a stat spread is at sweeping. This means that our validation tool for any SS formula should be checking the output of certain spreads against each other, and confirming that relationships between spreads are preserved by our formula. Obviously, if you improve both SpA and Speed, SS should increase. However, how should things change when you decrease SpA and increase Spe by the same amount? This varies across the range of Spe and SpA, though how exactly, I'm not sure.

Here's an assumption I'm curious about: should Sweepiness depend on Speed only as a function of sf? The fact that EVs are fungible to an extent means that an increase in Speed that doesn't result in outspeeding an additional Pokemon is still valuable at a baseline. This ties into the second assumption listed in your post; "Each additional mon you outrun is more valuable than the last." This assumption is not actually violated by our current sweepiness formula; the second derivative of SS wrt sf is positive. This can be seen in basically any BSR vs. sf plot (the graph curves upwards). The behavioral issues arise when we look at BSR vs. raw Speed plots (where we see plateaus) because the amount of Speed needed to outspeed an additional mon becomes quite high.

d/d(sf) SS = SpA * (1 + 2*t) / (1 - sf + t) ^2,
d^2/d(sf)^2 SS = SpA * 2*(1+2*t) / (1 - sf + t)^3

(These were validated using software lol)

Practically speaking:
I think it is worth testing quziel's "probability of outrunning at least k of 6 mons on an opponent's team" concept; plot out BSR vs. raw Speed, and judge if the relationship looks reasonable for various k. This solution seems the simplest at a baseline, and if it works, we're very happy.
1792180465730.png
1792180474275.png
I'd have to do a bit more digging to decide if I like how this looks. If you have any ideas for what to explore for this model, let me know.

Other than that, I'll recap the proposal to base sf off of top 50 Pokemon in the metagame. Some of our problems in the past few projects have occurred because we don't weight the Pokemon we outspeed enough (high Speed, Ram / CAP38) or we consider Pokemon that genuinely don't matter (low Speed, Obliteryx). This definitely doesn't solve all the problems, but should probably be the second thing we look at. Given that speed tiers have stepwise behavior, and we have a low number of Pokemon to average over, some kind of smoother would have to be used here.

If things still don't work after this, I'd consider examining whether SpA and Spe really are separable (that is, SS(SpA, Spe) = f(SpA) g(Spe). This is an annoying assumption to drop though, but depending on our answer to the first question, it is necessary? I'd have to think on it..
 
Last edited:
We don't need speed factor to work out sweepiness. SF only exists because our BSR calc is using old spreadsheet tech. I wanted to kill it in the last update but couldn't without some formulas getting real messy. If we ignore that we use spreadsheets, here's a simpler model without sf, T value etc:
  1. Gather the top 50 mons in the CAP meta. Put them into a playpen and line them up one by one.
  2. Next, gather all mons that can legally be used in the CAP meta. Make them enter the playpen one by one, where they battle each of the 50 mons before making their way out. Free healing between each encounter.
  3. For each battle, record how many turns they need to KO the opponent, and how many turns they survive before getting KO'ed by the opponent. If they outspeed, +1 bonus to their survival turns. If they got outsped, +1 penalty to their turns-to-KO. This part essentially does what SF was trying to do, in the pure form.
  4. Once a mon has done its 50 fights, work out its sweepiness and tankiness. Sweepiness = 1 / average turns to KO the opponent. Tankiness = average survival turns. You can work out other ratings too and mash them together into a BSR rating - let's not worry about that for now.
  5. Standardize the ratings like we currently do.
So then to calculate BSR stats of any custom spread, we once again shove it into the playpen, have it battle the top 50 mons, record its survival turns and turns-to-KO, and calculate the sweep/tank/BSR stats based on that. Ordinary programming languages can do this, and I don't think we should let spreadsheets dictate what model we use. I also argue in this day and age that the BSR calculator ought be a simple webpage anyone can open, type in the numbers and get the results instantly, without needing to save any files or use certain apps. Such thing can be vibe coded to exist right away (though the stance on AI usage is probably another discussion). Maybe it's me but I think this is what the vision ought to be in the long term.

That said, if we want a quick bandaid fix I agree to repurpose sf to be based on the top 50 rather than the entire pool of legal mons.
 
Last edited:
We don't need speed factor to work out sweepiness. SF only exists because our BSR calc is using old spreadsheet tech. I wanted to kill it in the last update but couldn't without some formulas getting real messy. If we ignore that we use spreadsheets, here's a simpler model without sf, T value etc:
  1. Gather the top 50 mons in the CAP meta. Put them into a playpen and line them up one by one.
  2. Next, gather all mons that can legally be used in the CAP meta. Make them enter the playpen one by one, where they battle each of the 50 mons before making their way out. Free healing between each encounter.
  3. For each battle, record how many turns they need to KO the opponent, and how many turns they survive before getting KO'ed by the opponent. If they outspeed, +1 bonus to their survival turns. If they got outsped, +1 penalty to their turns-to-KO. This part essentially does what SF was trying to do, in the pure form.
  4. Once a mon has done its 50 fights, work out its sweepiness and tankiness. Sweepiness = 1 / average turns to KO the opponent. Tankiness = average survival turns. You can work out other ratings too and mash them together into a BSR rating - let's not worry about that for now.
  5. Standardize the ratings like we currently do.
So then to calculate BSR stats of any custom spread, we once again shove it into the playpen, have it battle the top 50 mons, record its survival turns and turns-to-KO, and calculate the sweep/tank/BSR stats based on that. Ordinary programming languages can do this, and I don't think we should let spreadsheets dictate what model we use. I also argue in this day and age that the BSR calculator ought be a simple webpage anyone can open, type in the numbers and get the results instantly, without needing to save any files or use certain apps. Such thing can be vibe coded to exist right away (though the stance on AI usage is probably another discussion). Maybe it's me but I think this is what the vision ought to be in the long term.

That said, if we want a quick bandaid fix I agree to repurpose sf to be based on the top 50 rather than the entire pool of legal mons.

What is the battle logic here? Do we take into account abilities? Typing? Setup? Moves?
I remember some of the stuff that was approximated in the t-value, but I didn't look at it too closely.
 
Battle logic is the same as always in BSR. Stats only. It doesn't factor in anything else besides stats. We just assume everyone spams an attack of average bp and modifiers. Right now these averages are jumbled up inside the T value along with N (number of targets) whereas the new model uses the averages directly without a need for T or N.

So basically- no typing, abilities etc. I called them "battles" to make it easier to picture but it's really just damage calcs in both directions:

Damage = ((((2 * Level / 5 + 2) * AttackStat * BasePower / DefenseStat) / 50) + 2) * Modifiers * Random / 100
Survival Turns = OwnHPStat / IncomingDamage
Turns to KO = EnemyHPStat / OutgoingDamage
 
Back
Top