EasyRPG / Player

RPG Maker 2000/2003 and EasyRPG games interpreter
https://easyrpg.org/player/
GNU General Public License v3.0
965 stars 183 forks source link

RM2K escape chance is usually high #3122

Closed zankplus closed 6 months ago

zankplus commented 8 months ago

Hi there,

I make RM2K games sometimes and I've been subbing in EasyRPG Player for portability. However it seems that the escape chance is substantially higher than when I use the native RPG_RT. RM2K's original flee chance algorithm is far from perfect, but it does ensure that running from fast enemies is difficult and that's very useful for balance control, so being stuck with a more generous algorithm poses challenges for me (and potentially threatens to disrupt a number of existing RM2K games one might wish to play with Easy RPG).

At first I thought this was just a bug, but I saw that there was a request about this a few years back, which was marked resolved. In the explication of the RM2K escape algorithm, a line in the initial escape chance section clamps the chance to between 64 and 100%. I guess my issue is that I'm not sure this is correct. It's not supported by the RM2K help file formula reference page, which doesn't mention clamping and suggests a 50% flee chance should be possible; and my own testing with RPG_RT anecdotally suggests a flee chance far lower than 64% against a foe with vastly superior speed. So my question is, is there an intentional reason that EasyRPG clamps the escape chance to such a high value when RM2K ostensibly does no such thing? And is there any way I might disable it?

Some numbers so you know I did my due diligence: By my own testing, using RPG_RT with party average speed = 50 and enemy average speed = 800, it took an average of 4.75 attempts to successfully escape, with a 0% escape chance of escaping on the first round (which is what the RM2K help file algorithm would predict). Fighting the same test battle with EasyRPG Player, it took an average of 1.45 attempts to escape, with a 66.6% of fleeing on the first round (close to the 64% minimum value in the linked page). I did 24 trials in each case which isn't a ton but enough in this case to make the trend clear, and of course I disregarded pre-emptive strikes.

I'm on Windows 10, if it matters. I've declined to upload a test game to demonstrate since it seems unnecessary in this case, but let me know if it would in fact be helpful and I'll put one up.

PS. 0.8 is fantastic and has otherwise amended all issues I encountered with 0.7. Thank you for all your hard work.

Ghabry commented 8 months ago

Thanks for the report. Maybe the escape algorithm we figured out differs between 2k and 2k3. Will check if there is something wrong here...

Ghabry commented 7 months ago

tl;dr: The 64 is wrong.

The formula in the help is usually only partially true. They omit details. Though for escape it is fine:

Escape success rate (%) = {1.5 – (Enemies' average agility / actors' average agility)} x 100

The clamping is not mentioned because a percentage is usually 0% to 100%.

When agi is same it is 50% (what the helpfile says).

When you have 66% of the enemy AGI your initial escape chance is 0.

For 100% escape chance you must be twice as fast as the enemy.


I checked this now. Current code:

void Scene_Battle::InitEscapeChance() {
    int avg_enemy_agi = Main_Data::game_enemyparty->GetAverageAgility();
    int avg_actor_agi = Main_Data::game_party->GetAverageAgility();

    int base_chance = Utils::RoundTo<int>(100.0 * static_cast<double>(avg_enemy_agi) / static_cast<double>(avg_actor_agi));
    this->escape_chance = Utils::Clamp(150 - base_chance, 64, 100);
}

bool Scene_Battle::TryEscape() {
    if (first_strike || Game_Battle::GetInterpreterBattle().IsForceFleeEnabled() || Rand::PercentChance(escape_chance)) {
        return true;
    }
    escape_chance += 10;
    return false;
}

For the initial escape chance RPG2k and RPG2k3 use as algorithm:

// Initial escape chance
int chance = int(avg_enemy_agi / avg_actor_agi * 100) // div is double
escape_chance = clamp(150 - chance, 0, 100)

// During escaping
When initiative: Escape always succesful.
Otherwise: Success when: rand(100) < fleeChance
On failure fleeChance is increased by 10 // what the helpfile says

So this 64 is indeed wrong and must be 0. Possible reasons how matthew messes this up when implementing: