Research:Movement
Movement
Actions affected | Movement |
Description | Describes an actor's movement speed for each mode of movement. Uses common term normalizedEncumbrance. |
Implementation status | changed since last implementation |
Analysis status | Still has further interactions with physics |
Actor target speeds
Passed to the animation system, as well as used for AI target leading.
if actor is a npc:
walkSpeed = fMinWalkSpeed + 0.01 * speedAttribute * (fMaxWalkSpeed - fMinWalkSpeed)
walkSpeed *= 1 - fEncumberedMoveEffect * normalizedEncumbrance
walkSpeed = max(0, walkSpeed)
if sneaking: walkSpeed *= fSneakSpeedMultiplier
elif actor is a creature:
walkSpeed = fMinWalkSpeedCreature + 0.01 * speedAttribute * (fMaxWalkSpeedCreature - fMinWalkSpeedCreature)
runSpeed = walkSpeed * (0.01 * athleticsSkill * fAthleticsRunBonus + fBaseRunMultiplier)
if encumbrance > maxEncumbrance:
moveSpeed = 0
elif flying or levitating:
flySpeed = 0.01 * (speedAttribute + levitationBonus)
flySpeed = fMinFlySpeed + flySpeed * (fMaxFlySpeed - fMinFlySpeed)
flySpeed *= 1 - fEncumberedMoveEffect * normalizedEncumbrance
flySpeed = max(0, flySpeed)
moveSpeed = flySpeed
elif swimming:
if running mode is on:
swimSpeed = runSpeed
else:
swimSpeed = walkSpeed
swimSpeed *= 1 + 0.01 * swiftSwimBonus
swimSpeed *= 0.01 * athleticsSkill * fSwimRunAthleticsMult + fSwimRunBase
moveSpeed = swimSpeed
elif walking or sneaking:
moveSpeed = walkSpeed
elif running:
moveSpeed = runSpeed
else:
moveSpeed = 0
if strafing (not including diagonally): moveSpeed *= 0.75
if actor is a werewolf and running and has no weapon ready: moveSpeed *= fWereWolfRunMult
moveSpeed is stored for later use.
Animation system
Determines movement of the model root bone which feeds back to the physics system.
anim = the relevant movement mode animation: # diagonal strafe uses the forward/back animations
Walk, Fly -> Walk<direction>[+weapon]
Run<direction>[+weapon]
Sneak<direction>[+weapon]
SwimWalk<direction>
SwimRun<direction>
if actor is a creature:
moveSpeed is re-calculated as if the creature was not running (as walking)
referenceAnim = choose the walking equivalent of the current movement mode:
Walk, Fly, Run -> Walk<direction>
SwimWalk, SwimRun -> SwimWalk<direction>
if actor is an NPC:
referenceAnim = anim
dist, dt = distance and time between the root bone positions at the "Loop Start" (or "Start" if it doesnt exist)
and "Loop Stop" (or "Stop" if it doesnt exist) animation notes for 'referenceAnim'
# note: if there are multiple matching animation notes, the last occurring one is used
# note: if the "Loop Stop" key occurs after the "Stop" key, the "Stop" key is used
animBaseSpeed = int(dist / dt)
animationScale = moveSpeed / animBaseSpeed
animationScale = min(animationScale, 10)
The animation system plays 'anim' with a rate multiplier animationScale. The root bone movement is passed to the physics system.
Physics movement
Provides three-dimensional movement like jumps, falls, navigating stairs, levitation.
The actor reference is updated with the root bone movement from the current frame.
fStromWindSpeed and fStromWalkMult both affect movement, slowing movement into the wind and faster with the wind.
fStromWindSpeed is used with the current wind speed in all weathers. fStromWalkMult is used with storms.
These are not applied when NPCs are underwater, but do seem to apply to slaughterfish.
Comments
Creatures have generalized combat, magic and stealth stats which substitute for the specific skills (in the same way as specializations). Creatures do not suffer slow down from encumbrance (fEncumberedMoveEffect). They will only completely stop dead, once they exceed their encumbrance limit.
Note the 10x cap on the animation scaling. This causes an upper limit on the movement rate of actors, which will be at a speed attribute of approximately 1030.
Acrobatics
Actions affected | Jumping, landing, and midair control |
Description | Uses common terms fatigueTerm, normalizedEncumbrance. |
Implementation status | implemented |
Analysis status | Initial velocity verified; requires testing in combination with physics system |
On jumping
encumbranceTerm = fJumpEncumbranceBase + fJumpEncumbranceMultiplier * (1 - normalizedEncumbrance)
if acrobaticsSkill <= 50:
a = acrobaticsSkill, b = 0
else:
a = 50, b = acrobaticsSkill - 50
x = fJumpAcrobaticsBase + pow(a / 15.0, fJumpAcroMultiplier)
x += 3 * b * fJumpAcroMultiplier
x += jumpSpellBonus * 64
x *= encumbranceTerm
if actor is running: x *= fJumpRunMultiplier
x *= fatigueTerm
x -= gravityAcceleration [constant; -627.2 exactly]
x /= 3
if actor is standing still:
set kinematic velocity to {0, 0, x}
if actor is moving:
groundVelocity = normalize({actorVelocity.x, actorVelocity.y})
set kinematic velocity to 0.707 * x * {groundVelocity.x, groundVelocity.y, 1.0}
decrease fatigue by fFatigueJumpBase + normalizedEncumbrance * fFatigueJumpMult
Midair
Airborne velocity can be offset from the initial jump vector based on ground speed and Acrobatics skill.
jumpMoveTerm = fJumpMoveBase + 0.01 * acrobaticsSkill * fJumpMoveMult
total velocity = kinematic velocity + ground movement velocity * jumpMoveTerm
On landing
fallingDist = distance from peak height
if fallingDist <= fFallDamageDistanceMin: soft landing; skip the rest of the function
x = fallingDist - fFallDamageDistanceMin
x -= 1.5 * acrobaticsSkill + jumpSpellBonus
x = max(0, x)
a = fFallAcroBase + fFallAcroMult * (100 - acrobaticsSkill)
x = fFallDistanceBase + fFallDistanceMult * x
x *= a
if x > 0: damage health by x * (1 - 0.25 * fatigueTerm)
if acrobaticsSkill * fatigueTerm < x: actor falls over
if actor is not incapacitated: acrobatics skill exercised (skill gain from fall damage)
Comments
Note that initial actor velocity is taken into account. Animation-driven kinematics mean the jump direction can be offset from the player facing if there is root bone movement. Agility does not appear to be involved in this calculation.