Reference · Updated 2552.07.28.11.32

Movement Feel

Base player movement: where the numbers live, what they were, what they are, and how to change them without guessing. Mobility abilities (double jump, air dash) are a separate laye

Base player movement: where the numbers live, what they were, what they are, and how to change them without guessing. Mobility abilities (double jump, air dash) are a separate layer — see MobilityAssistModule.md.


#Where the numbers live

ASLPlayerCharacter::ConfigureMovementDefaults(), called from the constructor. Not the Blueprint.

They were moved out of BP_SL_MasterChief on 2026-07-27 for the same reason the first-person camera values were: a value set on the Blueprint CDO silently wins over C++, so with settings in both places nobody can tell which is live. In C++ they diff, they have history, and the reasoning sits next to them.

⚠ Keep the character Blueprint free of movement overrides. If someone sets JumpZVelocity on the BP CDO,
it shadows this block and the code becomes a lie. Verify with a CDO read-back after any change (below).

#Baseline before this pass — every value an engine default

Captured 2026-07-27 off the BP_SL_MasterChief CDO. Nothing had ever been authored:

PropertyWasNowWhy
JumpZVelocity4206850.90 m hop → 1.30 m
GravityScale1.01.85apex in 0.43 s → 0.38 s; higher and snappier
AirControl0.050.350.05 is effectively none — you were committed the moment you left the ground
MaxWalkSpeed600600unchanged; tune last, it re-frames everything else
MaxAcceleration20482048crisp arena-shooter start
BrakingDecelerationWalking20482048stop-on-a-dime, matches both references
GroundFriction8.08.0unchanged
FallingLateralFriction0.00.0air speed is preserved, not bled
JumpMaxCount11the second jump belongs to the Mobility Module, not the Spartan

#The jump arc is arithmetic, not taste

With g = 980 × GravityScale:


apex height = JumpZVelocity² / (2g)

time to apex = JumpZVelocity / g

total airtime = 2 × time to apex

So pick the feel — "1.3 m in 0.38 s" — and solve for the pair, rather than nudging one number and re-testing. Going up in both JumpZVelocity and GravityScale together raises the jump while shortening the hang time; raising only JumpZVelocity makes it floatier.

#Tuning order

One knob per PIE run, in this order. Later knobs change how earlier ones feel, not the reverse.

  1. Jump arc (JumpZVelocity + GravityScale) — dominates everything.
  1. AirControl — 0.35 is a moderate, Halo-ish authority; ~0.5 reads Doom-ish.
  1. MaxWalkSpeed — 600 vs 700. Changing this re-frames the arc, so do it after the arc is settled.
  1. Ground friction / braking — only if the stop still feels wrong once the above are right.

#Verifying a change actually took

C++ constructor values only reach the game if the Blueprint isn't overriding them. After a rebuild, read the CDO back over the bridge:


bp = unreal.EditorAssetLibrary.load_asset("/Game/SystemLink/Characters/MasterChief/BP_SL_MasterChief")

move = unreal.get_default_object(bp.generated_class()).get_editor_property("character_movement")

print(move.get_editor_property("jump_z_velocity"), move.get_editor_property("gravity_scale"))

If it doesn't show the new values, the Blueprint has an override — clear it there, don't work around it here.

#Downstream dependency

MobilityAssistModule.md specifies DoubleJumpZVelocity = 700, described as "~+70% of base jump" — true against the old 420 base, meaningless against 685 (it would be a second identical jump). Re-derive that value once the base arc is final, before implementing the double jump ability.

#Not implemented

  • Sprint — deliberately out (decided 2026-07-27). Halo 4+ has it, Doom doesn't, and it competes with dash
  • for the same "I need to cover ground" pressure.

  • Slide, mantle, wall-run — not planned.
  • Fall damage interaction with the new arc — untested; MobilityAssistModule.md Phase 7 flags it.