I'm currently trying to run this with Pokebuddy, which has been properly configured to swap out the low level pets at 90% HP
What you describe as the problem, sounds entirely like you haven't understood or "properly configured" PB. PokeBuddy uses math, so if you understand the math, you understand the problem. And how to fix it.
the default rating sliders will always put a low level pet back in the rotation, which is the problem you and others experience, the suicide swaps, the ringer failures, etc.
Several times I've covered this, but, I did not explain, and perhaps I should have shown THE MATH... (Cue ominous music) to do so. I will proceed, because it is a good way to cure my insomnia at this point... Sic.
For example, lets put a level 10 vs a lvl 20. 400hp vs 1100hp. Give or take.
(If you want to do this in PB, enable debugging, which shows re-rating & do a real battle with defaults vs my pretend settings. I welcome you to correct my inelegant, 2am rambling)
(So, A paper napkin math pokeh rating for a pet is (level x -100) + (health x 5) + advantage + disadvantage = A / B / C ratings for each pet. The ranking works as a handicapping system for each pet, using these values. ( the actual ratings work in a similar way, give or take.)
So let's do a ringer battle, a lvl 10, 12, 20 vs 18,18,18. Battle.
And let's pretend this is how poke buddy works... For a moment at least.
i assume a few things, that if a lvl 10/20 takes a 200hp hit, it can be 20% or 90% of a pet's health, that a level 18 can hit for 200 or so .. And if we leave the sliders as default, Let's say the sliders are -100 level difference and 5 health, this is what happens...
If a level 10 pet vs an 18, takes a 10-20% hit, lets have a look at 3 rounds, and use the 90% swapouts.
The level 10 -18 difference is -8. Multiply by -100, you get 800. Health is 100% x5
the LD rating is 800 + 500 = 1300
The level 12 pet has 600 + 500 = 1100
The level 20 pet has -200 + 500 = 300
Now we take the 10% health hit.
A is now 800 + 450 = 1250
B is still 1100
C is still 300.
So, we've hit our swap out target HP, and we swap. PB sorts the new ratings, as A>B>C
PB scratches it head, says "oh okay you mean swap to the second highest", and chooses B.
Second pet , gets chomped by 15%. And we swap again.
A with 90% = 1250
B with 85% = 1025
C is still 300
Guess who's going to be called up when you call a swap ? A is. It's still A>B>C.
A, now gets chomped by 40%, it's now 50% HP and pet B has 85% HP.
A has 1050
B has 1025
C has 300
because the LD is so high, even if the HP of pet A = 0, or B = 0, the dead A will still be chosen over C. And to get A to swap to B, You need to push the HP of A below 40% of B, due to the level difference in this example, to get it to swap to B.
So, Math.
Swapping a pet by it's health alone, works fine for equal level pets. It does not work if you try to set health so high. Or Level difference so high.
The best, "proper" config is to work with a more consistent health/level slider and 50% HP swapouts, since its more forgiving than working out THE MATH of making a 50%hp pet with 10 levels difference (handicap) swap to a pet with 100% HP, but a negative handicap.
the "swapout" slider rating you want is difficult with 90% swapouts :
I.e. here's the criteria for a perfect ringer rating:
Pet A with 90% ( your swapout target ) has to be lower rated than C with 100%, in order for PB to swap to C properly.
Pet A with 100% has to be higher rated than C with 100% so A can go first.
Pet C, with 30% (near it's fatal value) has to be higher rated than Pet A with 90% (your swapout target)
You need to maintain a balance of health and level delta values if you change the swapout values; the pokebuddy plugin is not going to handle differential calculus to work out what to do to make 90% swapouts work as intended -- as pokebuddy was never designed to handle ringer settings, just 1v1.
If maybe gets around to it, version 2.0 might do something as a hack to get ringer settings to work, but the rating system is a functional handicapping system, as it stands, a good kludge.