Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple client-side autojump. Remove hardcoded Android stepheight #7228

Merged
merged 3 commits into from Nov 22, 2018

Conversation

bendeutsch
Copy link
Contributor

@bendeutsch bendeutsch commented Apr 9, 2018

During the movement phase, the client detects when an automatic jump is in order (based on collisions and such). Then, during the (next) control collection phase, a "jump" control is simulated.

The autojump is transparent for the server. It is indistinguishable from a regular jump, in fact it is a regular jump, just not triggered by the player but by the client software. The actual motion code is also unchanged.

Currently, jumps are only triggered when the player is moving forwards and is standing on solid ground and not swimming. The feature will be toggleable by a client setting (default enabled on mobile devices, disabled otherwise).
////////////
EDIT by paramat: For #6183

@bendeutsch
Copy link
Contributor Author

At the time of writing, the "collision detection" part is basically broken. I was trying to use the collision results from the movement code, but those seem to be incomplete / unusable for this purpose? Sometimes I don't even get the collision from the ground I'm standing on 🙁

Still, the jumping part works, if you want to test it, it just may need running against a wall a bit. At the moment, the wall can be more than one block high; testing this is planned, but futile until I find a good detection method in the first place.

I may have to simulate a jump and see if the player "fits better". Other suggestions welcome!

@paramat paramat added the Feature ✨ PRs that add or enhance a feature label Apr 9, 2018
@paramat
Copy link
Contributor

paramat commented Apr 9, 2018

Interesting and appreciated. I'm just wondering if there needs to be some server control over allowing this clientside option, probably yes as no having to use the jump button is inevitably a control advantage.

@rubenwardy rubenwardy added the WIP The PR is still being worked on by its author and not ready yet. label Apr 9, 2018
@bendeutsch
Copy link
Contributor Author

You can't really control this server-side, but it's less of an advantage than you think. Currently it's triggering by actually colliding with something (and hence stopping). If you manually jump before you reach the wall, you get to keep your horizontal speed. There will also certainly be situations in which autojump triggers even if you would rather not jump; again not a problem with manual control. So I would not agree to it being "inevitably a control advantage".

And even if it is: if it's available to everyone, can you call it an advantage? Or are you thinking of singleplayer / PvE games that want to make / keep the game more challenging for players? In that case I could see a use for a server turning it off, but I would caution against coding up yet another option until servers ask for it…

@paramat
Copy link
Contributor

paramat commented Apr 9, 2018

Yes i'm unsure if server control is needed or worth doing, for now i'm not asking for it, server owners can advise on this.
What i mean by 'inevitable advantage' is not any possible movement advantages it creates but simply not having to use the jump button, that itself is a type of minor control advantage.

if it's available to everyone, can you call it an advantage?

Well what i mean is most players will not want to use it, and they shouldn't feel any pressure to use it due to any slight advantages it gives to other players. So that argument is invalid in my opinion.
However i expect autojump will always be less responsive than manual jump so it will probably come with a slight movement disadvantage, which is actually good to balance not needing to use the key.

@bendeutsch
Copy link
Contributor Author

@paramat Ah, I see what you mean with "pressure to use it", thanks.

A new version is up. It appears that m_standing_node is not as reliable as I would have hoped. I've replaced the baseline for collision comparisons with getFootstepNode, which works better, but is a) semantically incorrect and b) does not "go deep enough" (it is made to return the carpet node you're standing on, which barely affects jumping).

The jump key is now "held down" for a while, and sneaking disables autojump.

@Wayward1
Copy link
Contributor

I really like this! It feels much more natural than using an increased stepheight (like on Android), and if made default on Android would remove the perceived speed advantage the increased stepheight gives Android users. There is one possible issue I spotted (though I am aware this is still WIP); when going up stairs there is an occasional higher "hop" in addition to the regular half-jump of normal stair ascent. I've made a quick video of this PR here: https://www.youtube.com/watch?v=DGVdEnrXk1E&feature=youtu.be

@bendeutsch
Copy link
Contributor Author

@Wayward1 thanks for checking this out! Yes, it's still quite rough – it still needs some work on heights and collisions. I'll be sure to study your video!

In related news, autojump now has it's own setting (default off), including a checkbox in the key controls gui.

@bendeutsch
Copy link
Contributor Author

I've got a new implementation: whenever the player collides horizontally, I test the same colliding movement one node higher. If it turns out that this results in a bit more horizontal movement, I trigger an autojump. This seems to work very well; single-node obstacles are reliably cleared, more than that is not even attempted. This works equally well with slabs and stairs; regular up-stepping movement no longer triggers a jump.

I had to add a field to the collision info struct for this, to help me find "horizontal collisions". I hope that's ok. Since I imagine collision detection is quite costly, I want to limit it to such cases.

All that's left to do is to refactor the autojump into a method and add this to old_move as well. Oh, and I just remembered I still need to test what happens if you bump your head while autojumping; it would be desirable to not autojump then.

if (autojump_time <= 0.0f) {
autojump = false;
}
} else if (m_can_jump && !control.jump && !control.sneak && control.up && g_settings->getBool("autojump")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The autojump setting should be cached instead of reading it from settings frequently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point; do you have an example of a cached setting that I could copy? Just off the top of your head?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look. We can cache this because it is not a setting that will change in-game.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it will; it's part of the key change GUI.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be solved with the PlayerSettings construct.

@paramat
Copy link
Contributor

paramat commented Apr 12, 2018

I had to add a field to the collision info struct for this, to help me find "horizontal collisions". I hope that's ok. Since I imagine collision detection is quite costly, I want to limit it to such cases.

Seems ok, collisions are costly so this seems good.

@paramat
Copy link
Contributor

paramat commented Apr 12, 2018

Settings cache example in another part of clientside code:

m_cache_fall_bobbing_amount = g_settings->getFloat("fall_bobbing_amount");

^ Set the cache in the constructor.
f32 m_cache_fall_bobbing_amount;

^ Variable is a 'private' class member.

@bendeutsch
Copy link
Contributor Author

Autojumping is now in it's own method and works in the old movement code as well (and should work with joysticks, though I'll have to test this later). Since I've gotten all that I want from this PR, I'm removing the "WIP". There is still the issue with settings caching above, don't worry, I haven't forgotten! Just need to wrap my head around settings callback handlers 😛

The player will actually bang their head, repeatedly, when running against a node that is clear above, but that has a ceiling in front of it. There is a method for this in collision.cpp, but it uses helper structures internal to the collision testing, and as such is non-trivial to use. For the time being, I recommend just not banging your head so much.

@bendeutsch bendeutsch changed the title [WIP] Simple client-side autojump Simple client-side autojump Apr 13, 2018
@bendeutsch
Copy link
Contributor Author

Please see #7243 for a proposed solution to settings caching. That PR does not contain autojump, of course, but it is relatively trivial to add it to this PR once that PR is accepted.

Would this help with the settings reading concerns?

@bendeutsch
Copy link
Contributor Author

I have rebased this PR again, incorporating #7243 changes, and have added autojump to those flags cached by player settings. This should solve the caching concerns.

I haven't tried building and testing on Android, yet, has someone had a look? Specifically, I'm not sure how good the behaviour can be enabled and disabled in the client.

@Wayward1
Copy link
Contributor

I just tested this on Android, and it works great! And it's as easy as any other advanced setting to change as well

@Fixer-007
Copy link
Contributor

Provocative question, can PC users have this configurable feature too? Disabled by default

@Wayward1
Copy link
Contributor

Wayward1 commented Apr 21, 2018

@Fixer-007 this is available for all users.

@bendeutsch
Copy link
Contributor Author

There was still a linting problem outstanding; I must have missed this. Fixed (and rebased while we're at it).

@paramat
Copy link
Contributor

paramat commented Sep 2, 2018

This is high in my priority queue, i'll review and hopefully add the 2nd approval soonish.

@SmallJoker
Copy link
Member

SmallJoker commented Nov 19, 2018

@paramat Just wondering - how long is your priority queue?

EDIT: Can we please finally get this PR into the game?

@SmallJoker SmallJoker added the Rebase needed The PR needs to be rebased by its author. label Nov 19, 2018
@paramat
Copy link
Contributor

paramat commented Nov 19, 2018

LOL sorry. This should certainly be in for 5.0.0.

@paramat
Copy link
Contributor

paramat commented Nov 20, 2018

Apart from my line comment code looks good.
Settingtypes needs rebasing.
As a general tip: don't bother editing conf.example in PRs, we auto-generate that occasionally to update it.
So i'm very close to +1 on this @bendeutsch

// jumped
v3f run_delta = position_before_move - m_position;
run_delta.Y = 0.0f;
v3f jump_delta = position_before_move - jump_pos;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and above. Mathematically works but the order of terms bothers me because a movement vector is 'final pos' - 'start pos'.

Works by detecting a collision while moving forward and then
simulating a jump. If the simulated jump is more successful,
an artificial jump key press is injected in the client.

Includes setting and key change GUI element for enabling and
disabling this feature.
@SmallJoker SmallJoker removed the Rebase needed The PR needs to be rebased by its author. label Nov 21, 2018
run_delta.Y = 0.0f;
v3f jump_delta = position_before_move - jump_pos;
v3f jump_delta = initial_position - jump_pos;
Copy link
Contributor

@paramat paramat Nov 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might as well swap the terms too, i'm +1 and you can merge this if you do.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a 1D example:
Moving from 2 to 5 is a movement of +3, which is '5 - 2', 'final - initial'.
These deltas are wrong (inverted), they only work because getting the length of a vector is unaffected by the sign.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whether it's correct or wrong depends on the viewpoint. Deltas can be measured in all directions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somewhat true, but a delta is usually measured going forwards in time from initial to final position.

@@ -1147,9 +1147,9 @@ void LocalPlayer::handleAutojump(f32 dtime, Environment *env,

// see if we can get a little bit farther horizontally if we had
// jumped
v3f run_delta = position_before_move - m_position;
v3f run_delta = initial_position - m_position;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swap terms.

@stujones11
Copy link
Contributor

Tested and working nicely on android 👍

@bendeutsch
Copy link
Contributor Author

bendeutsch commented Nov 22, 2018

Hi there, sorry I took so long before reacting. Thanks @SmallJoker for stepping in – I take it it's been rebased now, too?

@paramat I got an email that you have a question about "always jumping", but I can't find it above any more. I'd have to review the code again, but I'm pretty sure the "simulate the jump key" feature only works if you're moving into something while on the ground, so it's "released" as soon as you're airborne at least. But I'll have another look.

Edit: I've checked, the key is "held" for 100ms, then released again and could be re-pressed.

@SmallJoker
Copy link
Member

@bendeutsch Yes, I rebased the PR on the fly because I wanted to make sure that it works on the current HEAD as well (it does).

@paramat
Copy link
Contributor

paramat commented Nov 22, 2018

@bendeutsch

I got an email that you have a question about "always jumping", but I can't find it above any more.

I deleted the comment soon after because i realised i was wrong, there's no problem.
👍

@paramat paramat merged commit 93bccb3 into minetest:master Nov 22, 2018
@gaelysam gaelysam mentioned this pull request Nov 23, 2018
Wuzzy2 pushed a commit to Wuzzy2/minetest that referenced this pull request Dec 11, 2018
…st#7228)

Works by detecting a collision while moving forward and then
simulating a jump. If the simulated jump is more successful,
an artificial jump key press is injected in the client.

Includes setting and key change GUI element for enabling and
disabling this feature.
osjc pushed a commit to osjc/minetest that referenced this pull request Jan 23, 2019
…st#7228)

Works by detecting a collision while moving forward and then
simulating a jump. If the simulated jump is more successful,
an artificial jump key press is injected in the client.

Includes setting and key change GUI element for enabling and
disabling this feature.
luk3yx pushed a commit to luk3yx/minetest that referenced this pull request Feb 12, 2019
…st#7228)

Works by detecting a collision while moving forward and then
simulating a jump. If the simulated jump is more successful,
an artificial jump key press is injected in the client.

Includes setting and key change GUI element for enabling and
disabling this feature.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants