先给出结论,常态下玩家的最大移动速度是 4.317m/s,该结论在 MCWiki 上已有记载,本文主要是对其结论进行证明。

特别鸣谢:水晶 在证明过程中给出的支持。

MC 环境

本文参考 forge 1.20.1 版本提供的代码,使用的反混淆为 parchment 反混淆。

证明

定义摩擦系数 f 和移动速度常量 M,其中移动速度常量在代码中由 MOVEMENT_SPEED 常量定义,为三维向量。

根据 LivingEntity#travel 中:

1
this.setDeltaMovement(vec35.x * (double)f3, d2 * (double)0.98F, vec35.z * (double)f3);

得到玩家得到移动指令时获取瞬时速度,为方便证明,不妨令方向为 z 轴正方向,即 Min = (0, 0, M * 0.98)T

而此时根据 LivingEntity#getFrictionInfluencedSpeed 代码:

1
2
3
private float getFrictionInfluencedSpeed(float pFriction) {
return this.onGround() ? this.getSpeed() * (0.21600002F / (pFriction * pFriction *pFriction)) : this.getFlyingSpeed();
}

此时,修正后的速度为: 而上一刻的速度(记为 vl)则会经过衰减给到当前刻,根据 LivingEntity#travel 的代码:

1
float f3 = this.onGround() ? f2 * 0.91F : 0.91F;

加上当前刻提供的瞬时加速度可以得知,当前的移动速度为:

在常态下,必然有 vl = vc,代入得: 通过 debug 得知将 M = 0.1, f = 0.6, 代入得 v = 4.317

而由 Entity#getInputVector 代码:

1
2
3
4
5
6
7
8
9
10
11
private static Vec3 getInputVector(Vec3 pRelative, float pMotionScaler, float pFacing) {
double d0 = pRelative.lengthSqr();
if (d0 < 1.0E-7D) {
return Vec3.ZERO;
} else {
Vec3 vec3 = (d0 > 1.0D ? pRelative.normalize() : pRelative).scale((double)pMotionScaler);
float f = Mth.sin(pFacing * ((float)Math.PI / 180F));
float f1 = Mth.cos(pFacing * ((float)Math.PI / 180F));
return new Vec3(vec3.x * (double)f1 - vec3.z * (double)f, vec3.y, vec3.z * (double)f1 + vec3.x * (double)f);
}
}

可提取出正交变换:

根据正交变换不改变模长的性质,可知稳态速度即使更换方向依然不变。

综上,玩家最大速度为 v = 4.317