Research:Stats and Levelling

From OpenMW Wiki
Jump to navigation Jump to search

PC & NPC dynamic stats

Actions affected Recalculated when base attributes are modified
Description Health points, magicka, fatigue, and encumbrance
Implementation status partially done (magicka needs adjustment, changed to current values not implemented yet)
Analysis status Ignores all magicka multiplier GMSTs, ignores differences between PC and NPC calculations

HP

Initial HP

health = int(0.5 * (baseStrength + baseEndurance))

At every level-up

occurs after attributes have been increased by the level-up
bonusHP = fLevelUpHealthEndMult * baseEndurance


Magicka points

Every time intelligence or magicka multiplier is modified

M = total magic bonus from race, item, sign (Maximum Magicka Multiplier and Stunted Magicka effects) and magicka GMSTs
maxMagicka = M * intelligence
currentMagicka is rescaled to preserve % left


Fatigue

Every time a base stat is modified

maxFatigue = strength + willpower + agility + endurance
currentFatigue is rescaled to preserve % left


Encumbrance

Every time strength is modified

maxEncumbrance = fEncumbranceStrMult * strength


Resting

Actions affected On resting/waiting
Description Waiting also applies to time passed after training. Resting also applies to time passed during travel.
Implementation status
Analysis status Verified, but sleep interruption has bugs
if resting in an exterior cell and the region has a sleep creature levelled list:
    x = roll hoursRested
    y = fSleepRandMod * hoursRested
    if x > y:
        interruptAtHoursRemaining = int(fSleepRestMod * hoursRested)
        interruptingCreatures = max(1, roll iNumberCreatures)
        sleep will only last (hoursRested - interruptAtHoursRemaining) hours
        sleep will be interrupted with 1 creature from the region levelled list


for each hour:
    for every actor in the entire world:
        if resting, not waiting:
            health += 0.1 * endurance
            if actor does not have magic effect Stunted Magicka:
                magicka += fRestMagicMult * intelligence

        x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance)
        x *= fEndFatigueMult * endurance
        fatigue += 3600 * x


Comments

Resting allows all actors in the game to recover. There is a bug with interrupted sleep; the code only spawns the first creature it finds in the levelled list, as well as calculating the number of creatures incorrectly. interruptingCreatures should be 1 + roll iNumberCreatures, and that number of creatures should be spawned.


Player levelling

PC skill progress

Actions affected On skill level-up
Description
Implementation status not started yet
Analysis status Usable, doesn't cover how all of the counters wrap on level up

When player receive point in the skill:

int total # global counter of skill increases
int attribCounter[8] # counter of attribute bonuses
 
if skill in Major:
    total += iLevelUpMajorMult
    attribCounter [skill->basicAttribute] += iLevelUpMajorMultAttribute

if skill in Minor:
    total += iLevelUpMinorMult
    attribCounter [skill->basicAttribute] += iLevelUpMinorMultAttribute
 
if skill in Misc:
    attribCounter [skill->basicAttribute] += iLevelUpMinorMultAttriubte # note: game setting name has a typo
 
if total >= iLevelUpTotal:
    level up


Levelling up

Actions affected On resting when a level up is available
Description
Implementation status not started yet
Analysis status Requires documentation of level-up conditions and GMSTs

On level-up PC get 3 points to redistribute, bonus will be this:

if attribCounter != 0:
    bonus = iLevelUp$$Mult
else:
    bonus = 1

where $$ is value of attribute counter


Skill increases

Actions affected On exercising a skill
Description
Implementation status implemented, but untested
Analysis status Accurate, but doesn't cover how progress wraps on level up and multiple level ups per action

Based on research on leveling of the Alchemy skill (ref: http://openmw.org/forum/viewtopic.php?f=2&t=853)

level_progress = 1 / ((level + 1) * (1/skill_gain_factor) * skill_type_GMST * specialisation_bonus)

level_progress = the progress factor through a level (from 0 to 1).

level = current level of the skill.

skill_gain_factor = skill gain factor(s) that come from the skill records.

  • For alchemy only "Potion creation" (default value: 2.00) is used.
  • For other skills, please add alphabetically.

skill_type_GMST = value of the GMST corresponding skill type:

  • Major skill: GMST fMajorSkillBonus (default: 0.75)
  • Minor skill: GMST fMinorSkillBonus (default: 1.00)
  • Misc skill: GMST fMiscSkillBonus (default: 1.25)

specialisation_bonus = value of fSpecialSkillBonus (default: 0.80) when the Player has the same specialization as the skill or 1.00 if not.

On using player->setSkill
Experiments on Alchemy showed that using player->setAlchemy did change the alchemy level, but not the skill progress. Therefore, when lowering the alchemy level, the skill progress will be recalculated for that level en give a higher progress. When increasing the alchemy level, the reverse will happen, resulting in a lower skill progress.
To reset the progress, level first to the next level and then use player->setSkill to the target level.

NPC Auto-calculate stats

Actions affected On creating an NPC
Description NPCs' auto-calculated stats. Affected by race, class, faction and rank.
Implementation status Implemented, except spells
Analysis status Verified, spells incomplete


Attributes

for each attribute:
base = race base attribute (+ 10 if a class primary attribute)

k = 0
for each skill with this governing attribute:
    if skill is class major: k += 1
    if skill is class minor: k += 0.5
    if skill is miscellaneous: k += 0.2

final attribute = base + k * (level - 1)
round attribute to nearest, half to nearest even (standard IEEE 754 rounding mode)


Health

mult = 3
     + 2 if class specialization is combat
     + 1 if class specialization is stealth
     + 1 if endurance is a primary attribute

health = floor(0.5 * (strength + endurance) + mult * (level - 1))


Skills

for each skill:

    if skill is class major: base = 30, k = 1
    if skill is class minor: base = 15, k = 1
    if skill is miscellaneous: base = 5, k = 0.1
 
    if skill is in class specialization: base += 5, k += 0.5
    if skill has race bonus: base += racebonus

    final skill = base + k * (level - 1)
    round skill to nearest, half to nearest even (standard IEEE 754 rounding mode)


Reputation

if not in a faction:
    reputation = 0
else:
    reputation = iAutoRepFacMod * rank + iAutoRepLevMod * (level - 1)
    where the entry level rank in the faction means rank = 1


Spells