Research:Stats and Levelling
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 | {{{4}}} |
|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