Is walljump just coded wrong?
Typhon
Join Date: 2002-11-01 Member: 1899Members
Having played with walljump a bit trying to improve it over the past few days to varying success, I think I've just stumbled upon the possibility that it may simply be coded wrong.
I've always been under the impression that a walljump is executed by timing your jump from the wall to be as close as possible to some target time span after you contact the wall. A common complaint with walljump though is 'if you jump too early, you get nothing', which is that the quality of the jump as plotted against time in contact with the wall is 0, then jumps to 1 at the target time, then decays back down to 0 gradually. So if you're late, you get some fraction of an ideal walljump, but if you're at all early, you get nothing. Not intuitive to learn. Additionally, with the detailed geometry its hard to tell when the engine considers you to have actually contacted the wall and started this walljump timer.
I now see that these impressions are correct and are a result of how its coded, but comments in the code seem to imply a different behavior was intended.
Here's the essential bit:
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->function Skulk:GetJumpTiming()
local t = Shared.GetTime() - self.timeOfLastJumpLand
local fraction = Clamp( t / Skulk.kJumpTimingDuration, 0, 1)
return 1 - fraction
end<!--c2--></div><!--ec2-->
The return value is multiplied by the force the walljump delivers, so as the results here vary from 0 to 1 you go from a terrible to perfect walljump. Skulk.kJumpTimingDuration is defined here:
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->// the duration of the bound (time from landing, to deepest point, to top)
Skulk.kJumpTimingDuration = 0.65<!--c2--></div><!--ec2-->
This would seem to imply that the 'bound' (the time while contacting the wall) starts at some time, then gets 'deeper' (like compressing a spring?), then returns to a top value over the course of .65 seconds.
So as we take the time difference between now (when we're attempting to walljump) and when we last contacted the wall, then divide by .65, we get a line that starts at 0 and increases to 1 at .65 seconds after touching the wall. This value is then subtracted from 1 to get our walljump quality.
But wait, that means a perfect walljump is when you jump exactly as you land (0/.65 is 0, 1-0 is 1, perfect jump), not when you jump very close to some ideal time after landing. And if you jump early, that means you're jumping in the air, so you don't get a walljump at all. But its impossible to give any sort of visual or auditory feedback that would be useful here, since you have to jump the instant you touch the wall, by the time you're giving the feedback and the player can see or hear it, its already too late. In order to get a perfect jump you have to guess at when the engine is going to decide when you attached to the wall.
The comment on kJumpTimingDuration seems to imply though that the quality should start at 0 when you contact the wall, increase to 1, and then decrease back to 0 over some duration, which makes a whole lot more sense.
Thoughts?
I've always been under the impression that a walljump is executed by timing your jump from the wall to be as close as possible to some target time span after you contact the wall. A common complaint with walljump though is 'if you jump too early, you get nothing', which is that the quality of the jump as plotted against time in contact with the wall is 0, then jumps to 1 at the target time, then decays back down to 0 gradually. So if you're late, you get some fraction of an ideal walljump, but if you're at all early, you get nothing. Not intuitive to learn. Additionally, with the detailed geometry its hard to tell when the engine considers you to have actually contacted the wall and started this walljump timer.
I now see that these impressions are correct and are a result of how its coded, but comments in the code seem to imply a different behavior was intended.
Here's the essential bit:
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->function Skulk:GetJumpTiming()
local t = Shared.GetTime() - self.timeOfLastJumpLand
local fraction = Clamp( t / Skulk.kJumpTimingDuration, 0, 1)
return 1 - fraction
end<!--c2--></div><!--ec2-->
The return value is multiplied by the force the walljump delivers, so as the results here vary from 0 to 1 you go from a terrible to perfect walljump. Skulk.kJumpTimingDuration is defined here:
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->// the duration of the bound (time from landing, to deepest point, to top)
Skulk.kJumpTimingDuration = 0.65<!--c2--></div><!--ec2-->
This would seem to imply that the 'bound' (the time while contacting the wall) starts at some time, then gets 'deeper' (like compressing a spring?), then returns to a top value over the course of .65 seconds.
So as we take the time difference between now (when we're attempting to walljump) and when we last contacted the wall, then divide by .65, we get a line that starts at 0 and increases to 1 at .65 seconds after touching the wall. This value is then subtracted from 1 to get our walljump quality.
But wait, that means a perfect walljump is when you jump exactly as you land (0/.65 is 0, 1-0 is 1, perfect jump), not when you jump very close to some ideal time after landing. And if you jump early, that means you're jumping in the air, so you don't get a walljump at all. But its impossible to give any sort of visual or auditory feedback that would be useful here, since you have to jump the instant you touch the wall, by the time you're giving the feedback and the player can see or hear it, its already too late. In order to get a perfect jump you have to guess at when the engine is going to decide when you attached to the wall.
The comment on kJumpTimingDuration seems to imply though that the quality should start at 0 when you contact the wall, increase to 1, and then decrease back to 0 over some duration, which makes a whole lot more sense.
Thoughts?
Comments
it was changed to its current form due to public feedback.
Who was advocating for this change? It is arbitrary and extremely unintuitive.
No-one, the wall-jumping mechanic is an atrocity.
It seems UWE are at a loss as to how to make skill based movement for aliens. I don't think we are going to see anything worth while until after 1.0 now though.
It seems UWE are at a loss as to how to make skill based movement for aliens. I don't think we are going to see anything worth while until after 1.0 now though.<!--QuoteEnd--></div><!--QuoteEEnd-->
i gave it another pass this week and got rid of the timing. im not 100% sure if we will release that with next patch, that's why i don't want to write the exact details now. and before somebody posts this: no, it's not dumbed down. there is another mechanism in place to allow dynamic increase of speed
<a href="http://www.unknownworlds.com/ns2/forums/index.php?showtopic=121022&st=120&p=1977798&#entry1977798" target="_blank">http://www.unknownworlds.com/ns2/forums/in...p;#entry1977798</a>
Looking forward to it.
I'm a newer NS2 player, and as someone mentioned above, wall-jumping seems "broken" for me. It seems to not work most of the time, and I try it quite frequently lately.
I think the biggest issue for me is to know (again same feedback as above) when the game considers me to have "touched the wall." It's pretty hard to tell at the moment, so maybe the timing should be more forgiving?...
It is great to hear you are so dedicated to trying to make wall-jumping work.
My criticisms were not intended to be personal. I consider making a skill based movement system for aliens that is intuitive, easy to learn and difficult to master to be a near impossible task.
I feel a little bit better knowing you are so dedicated to making it work though, thank you!
Add a +1 from me. I would look much more favorably on a mechanic that relies on hitting some button after landing on a surface if there's any clue to warn me when I've landed on said surface. Right now is extremely difficult or downright impossible to tell.