ToME: the Tales of Maj'Eyal http://forums.te4.org/ 

Improved checkHit function http://forums.te4.org/viewtopic.php?f=36&t=35229 
Page 1 of 1 
Author:  Hachem_Muche [ Tue Nov 20, 2012 10:03 pm ] 
Post subject:  Improved checkHit function 
Improved checkHit function TOME currently uses two different functions to check for success in opposed roll situations, such as one skill countering another. These cases come up extensively in such things as melee attacks, spell saving throws, stealth and invisibility, detecting and disarming traps, etc. For most tohit checks, the function checkHit compares offense (atk) verses defense (def) with the following formula: HitChance = 50 + 2.5 * (atk  def) This function is simple and linear, but needs hard limit checks to be robust, and is unforgiving of wide differences in offense versus defense. That is, the chance of success quickly vanishes or tops out once the difference between atk and def approaches +/20 (subject to hardcoded limits). This is an important limitation because it allows certain combinations of npc (and player) talents to become nearly invincible. A random boss with several defense bonuses can become almost completely unhittable by a meleebased character, for example. The second function, checkHitOld works in almost the same way, but uses an exponential function to compute success chance: a = 1/(1 + exp((atk  def)/7)) b = atk/(atk + def) HitChance = 50 * (a + b) with limit checks to avoid singularities when atk = def. This function is smoother and more forgiving, but is computationally more expensive (not really an issue here) and starts to break down at low defense values  it cannot tolerate atk and def <= 0. The function behaves differently in the early game than in the late game because the balance between atk and def is significantly affected by the magnitude of the values involved. Both functions require limit checks (default 5% and 95%) to keep success probabilities reasonable throughout the normal range of play. As an alternative to these functions, I propose a new checkHit function (that I call checkHitSmooth) that combines the best features of both of the current formulas: HitChance = 50 + 50 * (atk  def)/(abs(atk  def) + m) m = constant > 0 (default 10) This function is simple, both mathematically and computationally, is inherently bounded (it always gives a hit chance between 0% and 100% without limit checks needed, and scales well with all character levels. The tuning paramer, m, directly affects the slope of the line passing through (50%,0). Higher values flatten out the curve, while smaller ones steepen it near the middle. The following charts plot a comparison of the three functions (with the limit checks in place for checkHit and checkHitOld): Attachment: Charts14.jpg [ 160.72 KiB  Viewed 3400 times ] The stability of the new function is obvious. Since it depends only on the difference between atk and def, and not their absolute values, it maintains its integrity at any level, preserving game balance from character level 1 to level 50 (or beyond). It tolerates any conceivable range of values. (Since everyone really wants to know that 1,000,000 atk versus +10,000 def has a 0.000495% chance to succeed, when m = 10.) By tolerating negative numbers, it opens up the option of having negative offensive stats, particularly in the early game where debuffs are currently limited by small combat values. Further, the new routine (below) is a completely compatible dropin replacement for the current checkHit function, without any other changes required in the game: Code:  I5 updated to smooth out hit probabilities and to be more forgiving of level differences function _M:checkHit(atk, def, min, max, factor) local min = min or 0 local max = max or 100 if game.player:hasQuest("tutorialcombatstats") then min = 0 max = 100 end ensures predictable combat for the tutorial local hit = 50+50*(atkdef)/(math.abs(atkdef)+10)  tunable parameter in denominator 10> ~ 16.7% hit at 20 atkdef hit = util.bound(hit, min, max)  Limit checks aren't needed with the new formula. Left in for compatibility print("checkHit(smooth)",atk,def,"=> chance to hit", hit) return rng.percent(hit), hit end The "factor" argument is a holdover from a previous version of checkHit that is still included (though not used) in some of the game's older routines. (It would be desirable to use this as a dynamic tuning parameter for the new function, but all of the legacy function calls would need to be updated.) By changing the constant, m, checkHitSmooth can be tuned to more closely mimic either of the existing checkHit and checkHitOld functions. With m=20, it gives nearly identical results to checkHitOld, but without the deterioration at low values: Attachment: Chart5.jpg [ 42.44 KiB  Viewed 3400 times ] I have tested this function extensively in my Infinite500 addon, which requires that a large range of values be tolerated, sometimes as much as +/100 deep in the I.D. Replacing both existing functions with this one, I have used m=10 as the tuning parameter as a compromise between the more forgiving checkHitOld and maintaining consistency in game play with the more widely used existing (linear) checkHit function. I think this has worked out especially well, since tactical uncertainty is increased: improbable events do occur requiring you to stay on your toes and you always have a reasonable chance to land an attack. 
Author:  supermini [ Tue Nov 20, 2012 10:42 pm ] 
Post subject:  Re: Improved checkHit function 
Wow. Nice work. 
Author:  bricks [ Tue Nov 20, 2012 10:42 pm ] 
Post subject:  Re: Improved checkHit function 
+1000 Also, could this be applied to power vs. save checks? 
Author:  supermini [ Tue Nov 20, 2012 10:45 pm ] 
Post subject:  Re: Improved checkHit function 
bricks wrote: +1000 Also, could this be applied to power vs. save checks? That would be good. 
Author:  Hachem_Muche [ Tue Nov 20, 2012 10:58 pm ] 
Post subject:  Re: Improved checkHit function 
supermini wrote: bricks wrote: +1000 Also, could this be applied to power vs. save checks? That would be good. That's the default behavior. 
Page 1 of 1  All times are UTC 
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ 