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:
| Property | Was | Now | Why |
|---|---|---|---|
JumpZVelocity | 420 | 685 | 0.90 m hop → 1.30 m |
GravityScale | 1.0 | 1.85 | apex in 0.43 s → 0.38 s; higher and snappier |
AirControl | 0.05 | 0.35 | 0.05 is effectively none — you were committed the moment you left the ground |
MaxWalkSpeed | 600 | 600 | unchanged; tune last, it re-frames everything else |
MaxAcceleration | 2048 | 2048 | crisp arena-shooter start |
BrakingDecelerationWalking | 2048 | 2048 | stop-on-a-dime, matches both references |
GroundFriction | 8.0 | 8.0 | unchanged |
FallingLateralFriction | 0.0 | 0.0 | air speed is preserved, not bled |
JumpMaxCount | 1 | 1 | the 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.
- Jump arc (
JumpZVelocity+GravityScale) — dominates everything.
AirControl— 0.35 is a moderate, Halo-ish authority; ~0.5 reads Doom-ish.
MaxWalkSpeed— 600 vs 700. Changing this re-frames the arc, so do it after the arc is settled.
- 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.mdPhase 7 flags it.