Talk:Wallrunning

From DoomWiki.org

ZDoom Wiki says this only works with north-south walls. Can this be confirmed in the source code? (i.e. IMHO trial and error may not be convincing, since it's so hard to do in the first place) Ryan W 04:05, 24 Jun 2005 (UTC)

It only does work with north-south walls. Not sure if it is that "rarely" used in demos, btw; from the top of my head, it's used in demos for Doom E1M8, E2M3 and E2M5, and Doom II MAP01, MAP20, and MAP31. - Fredrik 10:18, 24 Jun 2005 (UTC)
Ach, I knew I wasn't really cool enough to give people advice!  :>
I do remember seeing this used e.g. on TNT 31, now that you mention it. I guess there's a fairly strong case to be made for it in a linear, squarish map like MAP01 or MAP31, where every tenth of a second can be important. To be perfectly honest, however, I have yet to figure out what really separates a 12:09 run from an 11:36 run in a big map --- is it mostly the RNG, an improvement in footwork, a new trick, or things like spinning macros and wallrunning which decrease the duration a few tenths of a second here and there?
I stand by the deathmatch part of the statement, though. It seems like [a] 90% of the time the map is some PWAD which is highly symmetrical, so nobody ever knows which way is north anyway, and [b] that slight hitch before the acceleration starts, especially when straferunning, can be enough of a delay to get one's head taken off. Ryan W 01:58, 25 Jun 2005 (UTC)
Addendum: I just did it with an east-west wall — want to see a demo?  Ryan W 07:20, 25 Sep 2005 (UTC)
I'd definitely want to see a demo of this. Janizdreg 14:38, 25 Sep 2005 (UTC)
Wallrunning can also be achieved on double sided & impassable west-east linedefs (see this wad). And BTW, isn't the correct regular wallrunning direction south-north, not north-south? Janizdreg 14:38, 25 Sep 2005 (UTC)
You seem to be suggesting that I've been imprecise.  Stunning!   :>
I'll try again.  The demo I added to this article was south-north.  This demo (file info) is west-east.  I'm not sure about other directions (but will fire up E2M3 of DARKHELL.WAD to try some at my earliest opportunity).
Obviously, if someone did extract a straight answer from the source code, that would be the ideal case.  I myself don't know enough C to do so, alas.    Ryan W 05:34, 26 Sep 2005 (UTC)
Interesting - I didn't know you could wallrun on regular west-east walls too. It seems to be harder to pull off than on south-north or double sided west-east linedefs though. Janizdreg 17:38, 28 Sep 2005 (UTC)
Here's a quote from Adam Hegyi: "On one-sided linedefs it is south->north. On two-sided linedefs it is south->north and west->east. It's also possible to do west->east wallruns on one-sided linedefs. Seems to work rarely." I think we should rewrite the article according to this. Janizdreg 19:10, 28 Sep 2005 (UTC)
Yeah, probably.  :>    I may have been able to make it work with sidedef 63 of MAP09: The Pit, but I didn't find the evidence conclusive.   Ryan W 20:32, 30 Sep 2005 (UTC)
Hmmmm-mm-m, and one also hears about things like this.  I have no idea what could be going on there.   Ryan W 22:20, 3 Oct 2005 (UTC)
Wallrunning can also be executed on "walls" made of things. The usual wallrunning directions seem to apply to thingrunning too. I have no idea about the flying stuff mentioned on that page though. Janizdreg 19:12, 5 Oct 2005 (UTC)
Update: wallrunning also works — sort of — on sidedef 110 of MAP18: The Courtyard.  I forget where I read about that, but here is a demo of it (file info).
I'm a bit confused now.  I'll have to think some more before I'm sure how to update the article (or perhaps someone less confused will do it instead).   :>     Ryan W 01:10, 5 Oct 2005 (UTC)
Further update: I changed the article to include the information in this discussion.  I hedged a little bit on the MAP18 reference, for reasons that I hope are obvious in the demo — if that wall were 10 times as long, it would contain 10 times as many snags, and I'm not sure that would do a lot for my confidence in a deathmatch game.    Ryan W 11:27, 10 Oct 2005 (UTC)

Faster or slower than straferunning?[edit]

Does anyone know if wallrunning is faster or slower than straferunning (SR40 and/or SR50)? radius 06:10, 5 Jul 2005 (UTC)

Faster. Fraggle 08:41, 5 Jul 2005 (UTC)

"Parallel to the wall" is incorrect![edit]

This demo (file info), though recorded as part of a different discussion, shows that wallrunning actually occurs at a slight angle to north-south walls.  The rocket is fired in the same direction as the wallrunning, but is clearly closer to the wall at the north end than at the south end.   Ryan W 23:43, 26 January 2006 (UTC)

Technical Explanation?[edit]

Is there some sort of explanation on why this bug happens? Why does it make you go faster? Why only North-South? Where's the code involved, and what could be changed to fix it? It seems odd that such an interesting bug is left unexplained in this article. —The preceding unsigned comment was added by 69.51.157.227 (talkcontribs) .

It's not odd, because this is a wiki, which means most things are unfinished.  Believe me, our technical articles have come a long way.  When I first arrived, there were almost no code excerpts anywhere.
To attempt to answer your question, I think this is still an unsolved problem.  It is generally believed that wallrunning is related to roundoff error in computing the player's location, which somehow creates large glitches in momentum when the engine believes that the player is moving into a wall, but the exact details have not been explained.  Although, see the remark by Graf Zahl here.    Ryan W 07:52, 7 December 2007 (UTC)
Actually, that's a pretty good explanation. I can sort of understand from that why it only goes N/S then, because I'm pretty sure one is checked before the other. -Wagi 69.51.157.227 15:10, 17 January 2008 (UTC)
I'm not entirely satisfied. Looking at the function in question, the bug should only occur when the player is moving North or East, but our article claims a speedrunner can also take advantage of the bug while moving South. The explanation given by Randy Heit also does not indicate why the bug only happens sometimes on specific walls, and not on just any wall. Zack 19:54, 17 January 2008 (UTC)
After studying the source a little bit, here is what I believe are the specific causes of wallrunning, and why it works when it does.
The function P_XYMovement first takes a look at the player's momentum. If an object should be moving in a cardinal direction at more than half of the maximum allowed speed, Doom will actually halve the momentum and then try to move the object twice. The effect is supposed to be the same, and I am guessing this logic exists as a means to improve the accuracy of collision detection.
However there are two (2) problems introduced by this. The first problem is with the function P_SlideMove, which is called to find the correct place to slide the object across an obstacle if the object is a player. The problem is, it's a shitty function. It looks like a mess and it doesn't do what it is supposed to - we know, because when you try to slide against a diagonal wall, you will start to jitter and "snag," instead of sliding smoothly.
P_SlideMove also does not care how far P_XYMovement is trying to move an object at a time. The result for a single tic looks like this:
  • P_XYMovement sees a player is moving more than half the max speed. So, as mentioned above, it tries to move the player HALFWAY there.
  • If a wall is in the way before the halfway point, P_SlideMove will only see what the player's momentum actually is and slide him "all the way," or whatever the hell P_SlideMove does.
  • P_XYMovement will then try to move the player the rest of the way. It's very likely that the wall is still there, so again P_XYMovement calls P_SlideMove to save the day.
  • P_SlideMove complies, and slides the player just as far as the player slid before. The resulting speed for the tic is up to twice what it should be.
And that's it. Randy Heit fixed the bug by escaping P_XYMovement after P_SlideMove is called one time. Although possibly not the most elegant solution, the resulting behavior is perfect: The player only slides as far as he's supposed to.
So why does this happen so rarely? Partly, it's because of the second of the two (2) problems introduced. That would be the fact that when P_XYMovement checks to see whether the X or Y movement is greater than half the maximum allowed movement, it's only checking against the positive limit. It's not checking the absolute value of the player's X or Y movement - It's only checking to see if the player is moving too fast to the North or the East! So even if the player is moving very fast to the South, for example, P_SlideMove will still only be called once, unless the player is moving very fast to the East as well.
That all means that wallrunning can only happen against walls that you can slide against while moving North or East. But wait, that includes many diagonal walls. Except P_SlideMove never worked well with diagonal walls in the first place, always snagging, sometimes "bouncing" you from the wall and usually decreasing your momentum to the point that it's less than the aforementioned threshold.
That's the last thing: P_SlideMove changes the player's momentum. This is the reason wallrunning only works when you're facing specific angles (i.e. almost parallel to a N-S or E-W wall). Say you run into a N-S wall at an angle of 30°. P_SlideMove will offset you, and then kill all of your Eastbound momentum, so you are no longer faster than the required speed in any direction. But if you were traveling at 89°, almost parallel, P_SlideMove would only deduct a tiny amount of Northbound momentum. Continuing forward that way you'll almost certainly have the required momentum the next several tics.
So theoretically it's possible to find an angled wall that allows wallrunning. You just need to be able to overcome "snag" (where P_SlideMove screws up and you don't slide smoothly). For example, I found that the south wall of the point of the star with invisibility in E1M8 still snags a bit, but I find myself at the end a little bit quicker than if I ran straight. (This is the outer wall, before it drops, and from the outside, so you would need to use noclip to get there. It's also a completely useless wall and would provide no advantage...but maybe there's something out there...) Zack 23:06, 17 January 2008 (UTC)
Now THAT is a good explanation. So what can be done to not only fix this wallrunning but all the behavior involved is to: (?)
1) Make it so that P_SlideMove checks the halved momentum instead of the real momentum.
2) Use Pythagorean theorum to check if momentum should be cut. (So collision detection is more accurate in all directions)
3) Maybe instead of having a static momentum threshold, make it check to see if the Momentum is larger than the object's radius.
I'm not so sure about how to fix the snagging, but I'm definetely no genius when it comes to that stuff. -Wagi 69.51.157.227 19:19, 18 January 2008 (UTC)
Essentially, to fix wallrunning and snagging, I would just rewrite P_SlideMove entirely. As much as I love our programmers at id, this was just very poor code. Zack 21:48, 18 January 2008 (UTC)
Well, I think they were kind of in a hurry.   :>     Ryan W 22:36, 18 January 2008 (UTC)
Messing around with the code, I found out that you were right, Zack. I changed it so that it only calls P_SlideMove() once, and sure enough, wallrunning was completely eliminated. Really though, P_SlideMove is such a "kludgy mess" that I can't even read what it's doing or what the problem really is. -Wagi 71.205.26.227 20:04, 20 January 2008 (UTC)
With specific regards to wallrunning, the problem with P_SlideMove is that it's paying no attention to how far P_XYMovement wanted to move the player. What you may want to do next is change the following line in P_XYMovement so that you are testing the absolute values of xmove and ymove against MAXMOVE/2:
if (xmove > MAXMOVE/2 || ymove > MAXMOVE/2)
If nothing else this is for the sake of consistency. I don't know why we are testing P_TryMove twice, though it might improve collision detection at higher speeds, so it's best to make sure it happens when the player is traveling South and West. (Incidentally, if you were to allow P_SlideMove again to be called twice, wallrunning should then occur in any cardinal direction.)
Regarding wall snagging with angled walls, yeah, I can't tell what the hell P_SlideMove is doing either. That's why I'd want to rewrite it. It should NOT be difficult to calculate a player's "sliding" destination. If you want to talk about some geometry you can reach me as Zaquer Craquer on AIM, or zack18 at comcast dot net. Zack 22:08, 20 January 2008 (UTC)
Oh - The MAP18 demo Ryan points to in the original discussion on this talk page is a much better example of wallrunning on "angled walls." I missed that before. Much nicer than the E1M8 linedef I mentioned. Zack 01:45, 21 January 2008 (UTC)
Yeah, I did the absolute value thing too. Of course, it doesn't really affect much. However, if you do that without fixing wallrunning, you can go S->N too! Yes, I believe that the cut and double technique is used to add accuracy. Things that move very fast are likely to end up skipping important objects and checks. (Although, I'm not sure how effective this is because I don't notice any kind of accuracy defecit going South as opposed to going North)
-Wagi 71.205.26.227 21:05, 21 January 2008 (UTC)
Zaximus, if you're casting about for other approaches, note that MBF and EDGE also changed this function. [1]    Ryan W 19:09, 26 January 2008 (UTC)