Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Bug Reports

Development::Bug Reports Post detailed bug reports and what you would like to see next in the emu here.

Reply
 
Thread Tools Display Modes
  #1  
Old 05-06-2015, 01:12 AM
Shendare
Dragon
 
Join Date: Apr 2009
Location: California
Posts: 814
Default Fizzle Rate capped at Character Level 49

Bug:

The fizzle rate check is capping skill-based spell casting difficulty at Level 49 values. A Level 90 character casting a Level 90 spell will be fizzling basically only as often if they were only casting a Level 49 spell.

Mitigating Factor:

Classic servers with a Level Cap of 50 won't really be affected by this, but the problem gets bigger and bigger the more levels a character gets above that on more modern/customized servers.

Full Report:

I happened to be looking over the fizzle code to see how fizzles are rolled, and am scratching my head over how the math came out as I mentally walked through it.

I wanted to see what odds are like for fizzles on a worst-case scenario character with very low skill for the level spell they're casting.

It looks like the code is far too lenient in these cases!

The code is in spells.cpp:

Code:
...
Line 675: bool Client::CheckFizzle(uint16 spell_id)
...
I won't paste the full function here, as I'll reference its relevant lines as I go.

First, to get a few things out of the way, we'll ignore the GM test, specializations, and Mastery of the Past style AA's that are checked, as we're assuming our character doesn't have any of those benefits to fall back on.

This leaves us with the following walkthrough. Let's assume we've got a character trying to cast a Level 90 spell with absolutely 0 skill in the spell's type. Should be eeeeasily maximum fizzle chance, right? Like, crazy in the red. Let's find out.

Code:
	par_skill = spells[spell_id].classes[GetClass()-1] * 5 - 10;//IIRC even if you are lagging behind the skill levels you don't fizzle much
	if (par_skill > 235)
		par_skill = 235;

	par_skill += spells[spell_id].classes[GetClass()-1]; // maximum of 270 for level 65 spell
par_skill = (Spell Level 90) * 5 - 10 = 450 - 10 = 440

if (par_skill > 235) par_skill = 235.

^ This. This right here. We'll get back to it. Caps maximum spell level checking at Level 49 (49 * 5 - 10 = 235).

par_skill += (Spell Level 90) = 235 + 90 = 325.

So, absolute maximum par_skill is 325 for a Level 90 spell, thanks to the L49 cap above.

Code:
	act_skill = GetSkill(spells[spell_id].skill);
	act_skill += GetLevel(); // maximum of whatever the client can cheat
actual skill = character's skill + character's level.

Sure, we'll give them a 1-point leeway for each level they've attained. Works for me.

Code:
	float diff = par_skill + static_cast<float>(spells[spell_id].basediff) - act_skill;
Note: Spell base difficulty, aka fizzle adjust, is a field for each spell in spells_new that ranges up to a max of around 120 (24 levels worth of skill points) for some Level 90 spells, aside from a couple outliers (Direwind Cliffs ports) in the 400s for whatever reason.

Difficulty = (325 at Level 90) + (spell.basediff, 120 at Level 90) - actual_skill (minimum 90 at Level 90)

So, our Difficulty = 325 + 120 - 90 = 355

Code:
	// if you have high int/wis you fizzle less, you fizzle more if you are stupid
	if(GetClass() == BARD)
	{
		diff -= (GetCHA() - 110) / 20.0;
	}
	else if (GetCasterClass() == 'W')
	{
		diff -= (GetWIS() - 125) / 20.0;
	}
	else if (GetCasterClass() == 'I')
	{
		diff -= (GetINT() - 125) / 20.0;
	}
Minus one difficulty point (0.2% fizzle chance) for every 20 points of WIS/INT/CHA(huh?) over an arbitrary threshold, depending on class.

If you have 325 INT, you're looking at ((325 - 125) / 20) = 10. A 2% improvement in fizzle rates for your stats. Sounds kinda low for that high of a stat, but whatev. Couldn't say how it compares to Live. Heh.

We're assuming our worst-case scenario character is freshly rezzed and naked, so our difficulty is still 355. Would be 345 if he had his gear on and registered 325 INT.

Code:
	// base fizzlechance is lets say 5%, we can make it lower for AA skills or whatever
	float basefizzle = 10;
	float fizzlechance = basefizzle - specialize + diff / 5.0;

	// always at least 1% chance to fail or 5% to succeed
	fizzlechance = fizzlechance < 1 ? 1 : (fizzlechance > 95 ? 95 : fizzlechance);

	// ...

		float fizzle_roll = zone->random.Real(0, 100);
fizzlechance = 10 - 0 + (355/5) = 10 + 71 = 81 %

Umm...

So... our absolute worst-case scenario of a fully naked Level 90 character with 0 skill, 0 AAs, and 0 specialization, casting a Level 90 spell with normal +120 base difficulty (aka fizzle adjust) per spells_new... is an 81% fizzle rate.

Every fifth time casting the spell on average, it'll succeed.

That really doesn't sound right to me at all. It should be easily bottoming out the 5% chance to succeed check above.

It seems pretty clear to me that the problem is the Level 49 / 235 Difficulty cap near the top.

If we remove that and walk through the math again...

par_skill = (Spell Level 90) * 5 - 10. 90 * 5 = 450, 450 - 10 = 440.

// Aborting this check -> if (par_skill > 235) par_skill = 235.

par_skill += (Spell Level 90) = 440 + 90 = 530.

actual skill = character's skill + character's level.

Difficulty = (530 at Level 90) + (spell.basediff, 120 at Level 90) - actual_skill (minimum 90 at Level 90 with 0 skill)

So, our new Difficulty = 530 + 120 - 90 = 560

fizzlechance = 10 - 0 + (560/5) = 10 + 112 = 122 %

This gets scaled down to the 95% cap to give the player a 1:20 chance to cast successfully no matter what.

This makes perfect sense to me. 122% (effective 95%) chance to fizzle a spell they have absolutely no chance of casting logically totally works for me.

Why is the 235 check in there? It seems like it should be removed.

Just thought I'd share my head scratch moment and see about getting an oversight corrected for higher-level casting.

inb4 "NOOO, fizzles r nerfed!"
Reply With Quote
  #2  
Old 05-06-2015, 02:18 AM
Shendare
Dragon
 
Join Date: Apr 2009
Location: California
Posts: 814
Default

Huh. Also not really sure how well the fizzle algorithm works as it currently is.

As I was working through various scenarios, I determined the following:
[*] Having full skill at any level yields an actual minimum fizzle chance of 7%, not counting specialization AA's.

Example: Level 20 with maxed 105 skill:

- par = Level 20 * 5 - 10 + Spell Level 20 = 100 - 10 + 20 = 110
- act = 105 skill + Level 20 leeway = 125 skill
- fizzle_chance = 10% + ((110 - 125) / 5) = 10% + -3% = 7%

Example of Level 80 with maxed 405 skill:

- par = Level 80 * 5 - 10 + Spell Level 80 = 400 - 10 + 80 = 470
- act = 405 skill + Level 80 leeway = 485 skill
- fizzle_chance = 10% + ((470 - 485) / 5) = 10% + -3% = 7%

So any character will fizzle a non-specialized spell a minimum of 1 out of 16 times on average. Cool to know.
[*] Add 0.2% fizzle chance for each point difference between max for level of spell being cast and character's actual skill level.

Example: Level 20 with 0 skill out of 105 max:

- par = Level 20 * 5 - 10 + Spell Level 20 = 100 - 10 + 20 = 110
- act = 0 skill + Level 20 leeway = 20 skill
- fizzle_chance = 10% + ((110 - 20) / 5) = 10% + 18% = 28%
- double-check: 105 skill difference / 5 = 21%. 7% base + 21% skill diff = 28%

Example: Level 50 with 0 skill out of 255:

- par = Level 50 * 5 - 10 + Spell Level 50 = 250 - 10 + 50 = 290
- act = 0 skill + Level 50 leeway = 50 skill
- fizzle_chance = 10% + ((290 - 50) / 5) = 10% + 48% = 58%
- double-check: 255 skill difference / 5 = 51%. 7% base + 51% skill diff = 58%

Even without the Level 49 cap problem above, the absolute maximum chance a Level 50 character has of fizzling a normal Level 50 spell with absolutely 0 skill for it is 58%. Almost 50/50.

A Level 20 with 0 skill is only at 28% chance to fizzle their spell. 2 out of 3 times it'll still cast.

That still sounds awfully lenient to me. I wonder if we could balance that a bit. I remember fizzling being reported as too punishing years ago, but it sounds like we've swung the pendulum a bit too far the easy way.

Caveat:

It's late at night and I've been thoroughly entertaining my left brain with superfluous mental math. I have not done any in-game testing to make sure actual experience meshes with the numbers above. It's technically possible I totally missed something and I'm way off and this whole thread is a waste of everyone's time.

Numbers seem to mesh, though. *shrug*
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 11:39 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3