ZScript implementation of Quake physics (CPM not included).
|ijon 4a6e3a3dd3 Updated README (and hybrid example class) in light of me realizing that friction applies after movement in Doom too||4 years ago|
|pk3||4 years ago|
|.gitignore||4 years ago|
|README.md||4 years ago|
Compatible with GZDoom 3.7.0+
This mini-project is a modding resource that allows you to quickly and easily add Quake physics to your mod. This is more of a resource than a playable mod, although you can play it to see what it's like.
Latest package: http://jinotra.in/downloads/mods/doom/quakemovement/quakemovement-v1.2.pk3
Packaged downloads: http://jinotra.in/downloads/mods/doom/quakemovement
Above the latest-commit bar, on the very right, there's a download icon.
Click that, choose ".ZIP", then unzip the ZIP file into its own directory.
Go into the pk3/ directory, select everything in there, and zip it all up. Change the extension of the new ZIP file to ".pk3", and you should be good to go.
If, in the ZIP you created, everything's still in the "pk3/" folder, you zipped the folder, not its contents. Don't do that.
Most of this is covered in quakeaccel.txt as well.
QuakeAccelPlayer overrides the following methods:
Thinker.Tick: extended to enable/disable Quake physics when Q_UseQuakeAccel changes.
PlayerPawn.CheckCrouch: overridden to speed up crouching and uncrouching. Not strictly
necessary, but every Quake game has fast crouching, so I'd recommend keeping this.
PlayerPawn.DeathThink: extended to apply Quake style friction when dead.
PlayerPawn.HandleMovement: overridden with Quake physics and movement. Do not override
this with your own movement code. (what's the point of using this if you do that, anyway?)
There are five contexts where acceleration, max speed, friction, and stopping speed can differ.
Most of them are self-explanatory, but
CSlide is only familiar to those familiar with Quake 4,
or Slash in Quake Champions. The contexts are:
Ground: When on the ground.
Crouch: When on the ground and crouching.
Air: When freefalling.
Fly: When flying (Wings of Wrath,
Water: When swimming.
CSlide: When on the ground and crouch sliding. Crouch sliding was introduced in Quake 4, and occurs when you hit the ground from a freefall while crouching. In both Quake 4 and Quake Champions, crouch sliding has drastically reduced friction, allowing you to keep and even gain speed while rounding corners on the ground. You aren't bound to that, but it is called a slide, after all.
QuakeAccelPlayer provides the following properties:
When enabled, use Quake physics. When disabled, use Doom physics.
Your maximum acceleration in the five contexts. These values are in u/s².
Your maximum speed in the five contexts. These values are in u/s. Negative values represent no hard speed cap.
Controls how quickly your speed degenerates in the five contexts. These values are in half-times (in seconds): that is to say, the values represent how many seconds it takes for friction to reduce your velocity to half of its current value. Higher values result in less friction. A table to quickly convert Quake friction values to half-time values is at the bottom of this README.
Values equal to or less than 0 mean "no friction".
The friction functions will act like your speed is at least this value when slowing you down. For example, a value of 200 means that you'll be treated as moving at 200 u/s if you're moving slower than that, and you will be slowed down accordingly. These values are in u/s.
Scales how fast you can move in a given direction. Most of them are self-explanatory, but UpScale only applies to the thrust you gain from +moveup/+movedown/+jump/+crouch, not from flying up/down with +forward/+back. Acceleration and max speed are scaled by these properties.
Scales the above DirectionScale properties in the given contexts. They multiply together, so a ForwardScale of 1.2 and a GroundForwardScale of 1.25 gets you a net forward scale of 1.5 on the ground.
Scales your speed when wading through water (waterlevel = 1).
When Quake physics are enabled, your
Gravity value is set to this. This value
acts the same as the standard
When Quake physics are enabled, your
Player.JumpZ value is set so that you jump
as high as this value says. This value is in units.
When Quake physics are enabled and you're in midair (not when you're swimming), your
MaxStepHeight is set to this value. This value is in units.
Quake and Quake 2 have a physics quirk where jumping adds to your Z velocity if it's positive, rather than simply setting it. This setting scales how much of your starting Z velocity is added to your jump velocity. For example, 0.5 means 50% of your Z velocity gets added to your jump velocity. If you want half the distance gained, use 0.7071 (roughly √0.5).
Similarly to double jumping, jumping while moving up or down a ramp added your jump velocity to however fast you were going up/down the ramp, allowing for dramatically boosted jump heights when jumping up a ramp. This setting scales how much that factors in; for example, 0.5 means 50% of your Z velocity from running up a ramp gets added to your jump velocity.
Sets the minimum amount of time you can crouch slide when hitting the ground. This value is in tics.
Sets the maximum amount of time you can crouch slide. This value is in tics.
In Quake 4 and Quake Champions, the amount of time you fall has a positive and direct correlation to how long you can crouch slide. This value scales how much your fall time adds to your crouch slide time; for example, a value of 2 means for every tic you fall, you can crouch slide for two more tics. This rounds down when added to your crouch slide time.
Quake 1, and to my knowledge none of the other Quake games, has a nice feature where if it detects that you're about to run off a ledge, it doubles your friction in an attempt to prevent you from doing so accidentally. When set to a value greater than 0, this recreates that behavior (higher values means higher ledge friction).
Don't set this to -1; that'll cause a divide by zero error.
When off, you need to let go and re-press jump between jumps. When on, you don't.
When off, you need to let go and re-press crouch between slides. When on, you don't.
In Quakeworld and every Quake afterwards, ground friction never applies when bunnyhopping. In vanilla Quake, ground friction applies for a single frame when you hit the ground, even if you jump immediately. This boolean enables vanilla Quake behavior.
In Quake 4 and Quake Champions, your crouch slide time ticks down when holding crouch, even in midair. When this is on, crouch slide only ticks down when actually sliding.
This replicates a flaw in the Quake games where holding jump or crouch in midair lowers your air acceleration, due to the engine zeroing out the Z component of your desired movement vector and reducing its length in the process. If you ever wondered why holding jump made your strafejumping suck... this is why.
Quake 1 and Quake 2 set your Z velocity to constant values if you hit jump or crouch when in the water. Quake 3 and beyond just make your wish direction point upwards. Turning this on uses Quake 1's behavior, and keeping it off uses Quake 3's.
In Quake 2, when swimming on the surface of a body of water and holding jump, your Z velocity gets clamped, keeping you closer to the water than in other Quake games. This simulates that.
By default, QuakeAccelPlayer is configured so that all of its movement styles act similarly
to the game they first appeared in - so air movement acts like Quake 1, crouch movement acts
like Quake 2, fly movement acts like Quake 3, slide movement acts like Quake 4, among other
pk3/zscript/testclasses.txt for examples of how to make the player act like
the other games in their entirety.
Doom's default friction value is 0.90625, which at its fixed ticrate of 35 translates to a halftime value of approximately 0.2012.
In both Doom and Quake, acceleration is applied to velocity, then velocity is applied
to position, then friction is applied to velocity. Max speed (in u/tic) can be solved
easily given acceleration (in u/tic²) and friction (in percentage of velocity kept per
tic) with the equation
v = a/(1-f).
If you have a max speed you want to reach with a given acceleration, use
f = (v-a)/v.
If you have a max speed you want to reach with a given friction, use
a = v(1-f).
|Movement mode||Accel (u/tic²)||Accel (u/s²)||Max speed (u/tic)||Max speed (u/s)|
¹ Max strafe speed when using the mouse.
In general, you can convert Quake friction values to half-time values with this Python function:
halftime = lambda friction, ticrate: math.log(0.5, 1-(friction/ticrate))/ticrate
Regular friction values (such as Doom's 0.90625 friction above, and what you get from
f = (v-a)/v equation above) can be converted to half-time values with this function:
halftime = lambda friction, ticrate: math.log(0.5, friction)/ticrate
Halftime values can be converted back to regular friction values with this function:
friction = lambda halftime, ticrate: 0.5 ** (1 / (halftime * ticrate))
And to Quake friction values:
qfriction = lambda halftime, ticrate: ticrate * (1 - 0.5 ** (1 / (halftime * ticrate)))
For quick reference, here are some pre-converted values. Each row corresponds to a Quake friction value, and each column corresponds to a set framerate the engine's physics would be running at.
|QFriction||60 FPS||72 FPS||77 FPS||85 FPS||125 FPS|