Adding airsteps to Ironwail 0.8.1
Posted by Cameron Vanderzanden on
in
notes.
Tags:
quake 1,
software,
video games.
The Quake game engine does not distinguish between stair steps and walls. If the player runs into a wall (or a step) the movement code will re-try the move with the starting position one stepheight up then move the player one stepheight down to put them back on the floor. Quake 1 as shipped in 1996 only attempts this stepped move if the player is on the ground. This means that if you jump into a set of stairs and hit the vertical part of a step without landing on ground first you lose your momentum.
Later Quake games allow the player to step up even if they're in the air.
Some Quake 1 sourceports implement this feature as well, often disabled
by default. The feature is called an "airstep" in these engines and is
typically enabled by setting the pm_airstep cvar to 1. The Quakespasm
lineage of Quake engines (notably: Ironwail) do not, from what I
can tell, implement airsteps.
That's an issue for me because I'd like to play the new cool singleplayer Quake mods but I don't want to get stuck on stairs. Fortunately this is easy to fix. Ironwail is used for most of these new mods & it's just a couple lines of code. Here's a quick patch for Ironwail 0.8.1 that adds rudimentary good-enough airsteps:
ironwail-0.8.1-airsteps.patch
diff --exclude Makefile -Nru ironwail-0.8.1-orig/Quake/sv_phys.c ironwail-0.8.1-hacked/Quake/sv_phys.c
--- ironwail-0.8.1-orig/Quake/sv_phys.c 2026-01-01 13:04:04.000000000 -0800
+++ ironwail-0.8.1-hacked/Quake/sv_phys.c 2026-01-20 19:17:37.866332969 -0800
@@ -865,9 +865,6 @@
if ( !(clip & 2) )
return; // move didn't block on a step
- if (!oldonground && ent->v.waterlevel == 0)
- return; // don't stair up while jumping
-
if (ent->v.movetype != MOVETYPE_WALK)
return; // gibbed by a trigger
@@ -888,7 +885,6 @@
VectorCopy (vec3_origin, upmove);
VectorCopy (vec3_origin, downmove);
upmove[2] = STEPSIZE;
- downmove[2] = -STEPSIZE + oldvel[2]*host_frametime;
// move up
SV_PushEntity (ent, upmove); // FIXME: don't link?
@@ -914,16 +910,26 @@
if ( clip & 2 )
SV_WallFriction (ent, &steptrace);
+ downmove[2] -= ent->v.origin[2] - oldorg[2];
+
// move down
downtrace = SV_PushEntity (ent, downmove); // FIXME: don't link?
- if (downtrace.plane.normal[2] > 0.7)
+ if (downtrace.allsolid)
+ {
+ VectorCopy (nosteporg, ent->v.origin);
+ VectorCopy (nostepvel, ent->v.velocity);
+ }
+ else if (downtrace.plane.normal[2] > 0.7)
{
if (ent->v.solid == SOLID_BSP)
{
ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
ent->v.groundentity = EDICT_TO_PROG(downtrace.ent);
}
+
+ if (oldvel[2] > 0)
+ ent->v.velocity[2] = oldvel[2];
}
else
{
Responses
If you've written a response to this post then please let me know the URL:
You can also submit a "comment" webmention by pressing the button below. It may take a day or two for your comment to appear here and a copy of your comment will be stored at commentpara.de.