View Issue Details

IDProjectCategoryView StatusLast Update
0003716The Dark ModCodingpublic14.09.2017 03:46
ReporterSpringheel Assigned ToSteveL  
PrioritynormalSeveritynormalReproducibilityhave not tried
Status resolvedResolutionfixed 
Product VersionSVN 
Target VersionTDM 2.02Fixed in VersionTDM 2.02 
Summary0003716: Bunny Hop Exploit
DescriptionApparently, crouch-running and spamming the jump button allows you to move without making any noise?
TagsNo tags attached.

Relationships

duplicate of 0001423 resolvedangua Silent rapid travel by bunny hopping exploit 
related to 0003485 resolvedSpringheel Landing when crouched makes no noise 

Activities

SteveL

SteveL

23.04.2014 19:22

developer   ~0006551

It works! Reproduced on first attempt. Completely silent movement, both through computer speakers, and as far as AI are concerned. I put a hostile guard on a metal floor and ran past 1 foot behind him, and got nothing more than a bored "something moved?".
SteveL

SteveL

23.04.2014 19:47

developer   ~0006552

This is easy to rep. Just crouch and jump. I can't produce any sound at all from the player jumping and landing while crouching, on any surface. It sounds implausible that we might not have noticed that, but I guess we don't jump very often when crouching except to mantle. Airship conf'd it too.

At first I thought this must be another physics problem because I saw that the first thing that idPlayer::PlayFootStepSound() does is to check the physics to make sure the player is in contact with a surface, but it's not that. idPlayer::PlayFootStepSound() is not being called in the first place.
SteveL

SteveL

23.04.2014 20:33

developer   ~0006553

This is related to 0003485. That fix lowered the landing speed threshold for producing a footstep when crouched to 300, so that the player made a sound falling off a ledge. But when the player jumps from a crouching position, I'm seeing landing velocities of just 217 from a standing start, and 241 when bunny hopping, so it needs to be lowered more, but I can't work out from the previous issue whether that's a simple fix or whether stuff'll need tuning.
SteveL

SteveL

25.04.2014 19:07

developer   ~0006556

Testing on flattish surfaces gave landing velocities of 207-245 when bunny hopping. Reduced velocity at which a footstep sound is made when landing crouched to 200 instead of 300.
SteveL

SteveL

25.04.2014 19:09

developer   ~0006557

Committed at revision: 5964
Springheel

Springheel

26.04.2014 13:00

administrator   ~0006561

Last edited: 26.04.2014 13:00

View 2 revisions

What affect will this have on the volume of crouch-landing from >300? Or does it just affect when a sound is made, but not how loud it is?

SteveL

SteveL

27.04.2014 07:48

developer   ~0006562

It won't change the volume at all. It's a threshold that suppresses any sound from a crouched landing, if the player is travelling below a certain speed. As I said to grayman, I'd have liked to set it lower, but I don't know what sounds the threshold is there to avoid. Tweaking it to 200 will cure bunny hopping on the flat and when going downhill, but it'll still be silent going uphill or upstairs.

Can you remember what the silencer threshold is there for? It used to be set way up at 600 before grayman did the first tweak, meaning the player would have to land very hard when crouched to make a noise.

Perhaps we should try moving it lower still to cure bunny hopping in all directions, and see if there are problems. 2.02 is the right release to try this in as all testers will be listening carefully to sounds.
Springheel

Springheel

27.04.2014 12:59

administrator   ~0006563

No, I don't know why the threshold is there. I don't recall there ever being a discussion about it.
SteveL

SteveL

27.04.2014 18:48

developer   ~0006564

Reopened while we discuss the threshold.

What do you think of the idea of reducing it further? The smallest landing velocity I can produce is when bunny hopping up steep stairs (45 degree angle) is 105. A threshold of 100 would cut out bunny hopping entirely and might have no bad side effects while still allowing the player to step off crates silently.

On the other hand, I find the player will now make a noise when dropping off a table crouched whereas he didn't before. Stepping off a standard dining_table1.lwo while crouched produces landing velocities of 240-250.

I'll ping grayman for an opinion too.
grayman

grayman

27.04.2014 19:21

administrator   ~0006565

It seems we're now in a place where we can't have the same limit applied to bunny-hopping and normal crouch landing.

Is there a way to tell when bunny-hopping is going on?

If so, you could use a lower limit of 100 for that, and leave the lower limit of 300 in place for non-bunny-hopping (i.e. dropping crouched off a table).
SteveL

SteveL

27.04.2014 19:53

developer   ~0006566

Possibly. The threshold works by testing the player's velocity along the z-axis so perhaps the other axes could be used to distinguish careful step-downs from bunny hops. Unfortunately I'm travelling for the next couple of days, so for me the code freeze happens in a couple of hours. I'll happily look into splitting up the two situations but not in time for 2.02. Is the table situation a deal-breaker for the 200 tweak? I guess so. I'll revert it for now.
grayman

grayman

27.04.2014 21:00

administrator   ~0006567

I think we'll freeze next weekend.

And I think the table situation is a deal-breaker, because we went through a lot of experimentation to get that correct. I'd rather not undo that.
SteveL

SteveL

27.04.2014 21:03

developer   ~0006568

Already undone. Ok, I'll report back on the axes.
Springheel

Springheel

27.04.2014 23:34

administrator   ~0006569

How loud is the noise when you crouch-walk off the table? If it's below the AI's hearing threshold, then it wouldn't matter.
SteveL

SteveL

30.04.2014 19:33

developer   ~0006576

I don't know how to measure the sound, but AI can definitely hear it :-/

I've done some tests. Tables tested:
dining_table1.lwo, dining_table2.lwo, endtable_square01.lwo, endtable1.lwo, coffeetable1.lwo, ornate_table01_small.lwo, pedestal_square01.lwo, rtable1.lwo, table_set01.lwo, victorian_table.ase

I tested the columns/pedestals in the furniture/tables folder too but I won't quote the results as they're taller and dropping off them always produces a sound in 2.01 anyway.


Crashland speeds when dropping off a table:
• z-axis is always the same range, 201 to 290
• xy-speeds: running, 80 to 95; walking, 37 to 43; creeping, 11 to 17

Bunny hopping running
• z: 223 xy: 85 to 111

Bunny hopping walking:
• z: 242 xy: 23 to 51

Crouch jumping off a table, both walking and running:
• z: 308 to 378, so produces sound in 2.02 too


The z-axis landing speed range for dropping off a table is the same as for bunny-hopping, so the only way to distinguish the numbers is the xy landing speed. Unfortunately, the xy landing speed has the same problem: it's only dependent on whether the player is running or walking, not whether they are landing off a table or bunny hopping. So we can't cure walking-bunny-hopping by testing landing speeds without forcing the player to creep when they need to step off a table silently.

We could easily cure the most egregious abuse: bunny hopping while running. There's a large gap between max walking speed and min running speed, and it'll be no big deal if the player starts to make a footstep sound while landing at a run: the next step would make a sound anyway. But I'm not sure whether that's worth doing while the exploit remains open for walker-bunny-hoppers. We'll need cleverer detection methods to fix it properly.
SteveL

SteveL

01.05.2014 16:34

developer   ~0006577

Testing velocities doesn't feel like the right fix given that what we really want to distinguish is jumping from step-downs. I'm currently working my way through the info stored in the player's physics object to see whether we can do exactly that. Disappointingly, idPlayer_Physics::HasJumped() won't help in this spot.
SteveL

SteveL

01.05.2014 18:52

developer   ~0006578

Problem: evidence of the player having jumped is lost from the physics object before the landing happens. That info is only retained during the period that the player isn't allowed to jump again, and that's shorter than a bunny hop. So to distinguish the landings, information will be needed from previous frames.

This is a problem that's been faced before. The CrashLand code already needs to be given the player's origin and velocity from the *previous* frame so that it can decide whether to play a footstep or damage the player. By the time CrashLand runs on landing, the velocity and direction have changed, so the code that calls CrashLand saves those values from the previous frame and passes them to CrashLand.

Unfortunately we can't fix bunny hopping using that method. During bunny hopping, we need information from up to 31 frames ago to detect whether the player jumped. The existing method relies on saving the old numbers before running the physics for the current frame, but that can only work where you need info from the previous frame, not 31 frames ago.


Suggested solution

idPlayer_Physics has a private member variable lastJumpTime which it uses to keep track of when the player last jumped so it can calculate stamina etc and so it knows when to turn its jump flags off. If we add an accessor function for that variable, we'll be able to test on CrashLand whether the player was jumping or not. The time doesn't get reset when the player drops off something: only when he or she actively leaps.


FWIW, I do think this is worth the effort of fixing. Ever since I tested it and found how easy it was, I find I now have to consciously resist using it when I get into danger in maps :-/ It's not that I want to cheat -- I've *never* been tempted to use noclip when playing, for example -- it's just that it's weird how easily something like this becomes integrated into your unconscious reactions when playing. When you misstep and panic a bit, you can apparently do it by accident even though you're sure you never did it by accident before testing it!
grayman

grayman

01.05.2014 19:01

administrator   ~0006579

Sounds good.
SteveL

SteveL

01.05.2014 19:18

developer   ~0006580

Cheers. My proposed patch to Physics_Player.h/cpp is straightforward:

/*
================
idPhysics_Player::GetLastJumpTime
================
*/
int idPhysics_Player::GetLastJumpTime() const {
    return lastJumpTime;
}


For the patch to Player.cpp, I need a steer. The existing code that decides whether to play a footstep looks like this:

if ( result.hasLanded && (savedVelocity.z < -300) )


We now have to choose between performance and readability. This code runs every frame, not just when the player lands. An easy to read version would look like this:

// SteveL 0003716: Fix bunny hopping exploit. Jumps lasting longer than 1 second don't need
// to be detected, since their landing velocity will be well above the 300 threshold anyway.
bool isJumping = (gameLocal.time - physicsObj.GetLastJumpTime()) < 1000;

if (result.hasLanded && ( savedVelocity.z < -300 || isJumping ) )


But that means the jumping test gets run every frame. A more performant version would look like this;

if (result.hasLanded && ( savedVelocity.z < -300 || ( (gameLocal.time - physicsObj.GetLastJumpTime()) < 1000 ) ) )


Less clear, although it could be supported by a good comment.


A new member function would feel like overkill to me. What do you think?
SteveL

SteveL

01.05.2014 20:08

developer   ~0006581

Tested readable version and it works as desired. I guess I'm being a bit overscrupulous when we're only talking about 2-3 int-sized operations per frame.
SteveL

SteveL

02.05.2014 17:12

developer   ~0006583

Committed in revision: 5967

The sound propagated to AI is too low compared with crouch-running, but I'm committing now as I assume we'll be tweaking specifically that parameter during the 2.02 code freeze anyway. And the fix is still preferable to no sound.

I'll leave the tracker open till we tune it.
SteveL

SteveL

02.05.2014 17:27

developer   ~0006584

Actually we can likely fix this now. The quietness of crouch-landing is by design and was introduced in the related issue. That logic needs to be able to distinguish between normal landing and bunny hopping too.
SteveL

SteveL

02.05.2014 17:40

developer   ~0006585

Last edited: 02.05.2014 17:55

View 2 revisions

Unfortunately the tests are in different functions so to avoid repeating a constant literal in the code (the 1 second timer limit) I think I should add another constant to Player.cpp. Something like JUMP_DETECTION_TIME. That's the way this is handled in the module. There are quite a few. @grayman: does that sound ok?

The alternatives are awkward: adding a parameter to PlayFootStepSound() would be confusing for readers, and adding a "global" member flag for jumping status would be ugly and brittle.

grayman

grayman

02.05.2014 19:11

administrator   ~0006586

That's okay.
SteveL

SteveL

02.05.2014 20:00

developer   ~0006587

Sound increase committed in revision 5968. The sound adjustments for crouched drops (which give the player a means to step silently off furniture etc) are now completely distinct from what happens when the player deliberately leaps à la bunny hopping, which now has no adjustment. Crouched jumping (bunny hopping) is now quieter than standing jumping but much louder than just running crouched, which is logical.
grayman

grayman

02.05.2014 20:05

administrator   ~0006588

Excellente!
Springheel

Springheel

03.05.2014 12:51

administrator   ~0006589

Sounds great!
SteveL

SteveL

04.05.2014 08:32

developer   ~0006592

Resolved subject to 2.02 testing of prop sounds

Issue History

Date Modified Username Field Change
22.04.2014 01:54 Springheel New Issue
23.04.2014 19:22 SteveL Note Added: 0006551
23.04.2014 19:22 SteveL Status new => confirmed
23.04.2014 19:47 SteveL Note Added: 0006552
23.04.2014 20:24 SteveL Relationship added related to 0003485
23.04.2014 20:33 SteveL Note Added: 0006553
25.04.2014 18:55 SteveL Assigned To => SteveL
25.04.2014 18:55 SteveL Status confirmed => assigned
25.04.2014 19:07 SteveL Note Added: 0006556
25.04.2014 19:07 SteveL Status assigned => resolved
25.04.2014 19:07 SteveL Fixed in Version => TDM 2.02
25.04.2014 19:07 SteveL Resolution open => fixed
25.04.2014 19:09 SteveL Note Added: 0006557
26.04.2014 13:00 Springheel Note Added: 0006561
26.04.2014 13:00 Springheel Note Edited: 0006561 View Revisions
27.04.2014 07:48 SteveL Note Added: 0006562
27.04.2014 12:59 Springheel Note Added: 0006563
27.04.2014 18:48 SteveL Note Added: 0006564
27.04.2014 18:48 SteveL Status resolved => assigned
27.04.2014 19:21 grayman Note Added: 0006565
27.04.2014 19:53 SteveL Note Added: 0006566
27.04.2014 21:00 grayman Note Added: 0006567
27.04.2014 21:03 SteveL Note Added: 0006568
27.04.2014 23:34 Springheel Note Added: 0006569
30.04.2014 19:33 SteveL Note Added: 0006576
01.05.2014 16:34 SteveL Note Added: 0006577
01.05.2014 18:52 SteveL Note Added: 0006578
01.05.2014 19:01 grayman Note Added: 0006579
01.05.2014 19:18 SteveL Note Added: 0006580
01.05.2014 20:08 SteveL Note Added: 0006581
02.05.2014 17:12 SteveL Note Added: 0006583
02.05.2014 17:27 SteveL Note Added: 0006584
02.05.2014 17:40 SteveL Note Added: 0006585
02.05.2014 17:55 SteveL Note Edited: 0006585 View Revisions
02.05.2014 19:11 grayman Note Added: 0006586
02.05.2014 20:00 SteveL Note Added: 0006587
02.05.2014 20:05 grayman Note Added: 0006588
03.05.2014 12:51 Springheel Note Added: 0006589
04.05.2014 08:32 SteveL Note Added: 0006592
04.05.2014 08:32 SteveL Status assigned => resolved
14.09.2017 03:44 nbohr1more Product Version => SVN
14.09.2017 03:44 nbohr1more Target Version => TDM 2.02
14.09.2017 03:45 nbohr1more Relationship added related to 0001423
14.09.2017 03:45 nbohr1more Relationship deleted related to 0001423
14.09.2017 03:46 nbohr1more Relationship added duplicate of 0001423