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

Expose analog joystick input to the Lua API #14348

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

grorp
Copy link
Member

@grorp grorp commented Feb 4, 2024

This PR exposes analog joystick input to the Lua API. This allows games like PRANG! to have better movement. It adds two new fields, movement_x and movement_y, to player:get_player_control().

These fields are set according to keyboard input when not available:

  • when an old client connects, this happens on the server
  • when a new client connects and the player uses the keyboard, this happens on the client

To do

This PR is a Ready for Review.

How to test

Verify that keyboard input still works.

Install PRANG! from ContentDB on an Android device and apply this patch:

diff --git a/mods/prang/init.lua b/mods/prang/init.lua
index e45550a..aadd301 100644
--- a/mods/prang/init.lua
+++ b/mods/prang/init.lua
@@ -586,11 +586,8 @@ function Player:tick(game, dtime, controls)
         speed = speed * (8/3)
     end
 
-    local dx = get_direction(speed, controls.left, controls.right)
-    local dy = get_direction(speed, controls.up, controls.down)
-    if dx ~= 0 and dy ~= 0 then
-        dx, dy = dx / sqrt_2, dy / sqrt_2
-    end
+    local dx = controls.movement_x * speed
+    local dy = -controls.movement_y * speed
     self:move(dx, dy)
 end
 

Play PRANG! and enjoy the virtual analog joystick. (Should probably use math.ceil here.)

@Zughy Zughy added the Supported by core dev Not on the roadmap, yet some core dev decided to take care of this PR label Feb 5, 2024
@v-rob
Copy link
Member

v-rob commented Feb 6, 2024

In general, I think it might be more desirable to make this work similar to how a physical joystick does in code by having two axes, X and Y, that range from [-1, 1]. It makes it consistent with how these things usually work, and you already effectively convert to that anyway by using sin and cos in your code example.

@grorp
Copy link
Member Author

grorp commented Feb 6, 2024

In general, I think it might be more desirable to make this work similar to how a physical joystick does in code by having two axes, X and Y, that range from [-1, 1]. It makes it consistent with how these things usually work, and you already effectively convert to that anyway by using sin and cos in your code example.

The problem with this approach is that for making it intuitive/understandable, we'd have to name the new fields joystick_x and joystick_y. However, modders would then incorrectly assume that they are for joysticks only and don't support keyboard input.

To avoid this, you could call them movement_x and movement_y, but then they could be misunderstood as absolute movement. Do you have an idea how we could get the intuitiveness of the joystick scheme and avoid both problems?

@v-rob
Copy link
Member

v-rob commented Feb 7, 2024

I think that having movement_x and movement_y is more ideal, but document it well that it may be a float for (virtual) joystick devices. If modders assume that it's a discrete -1, 0, or 1, then they'll probably end up with code that's sub-optimal, but no worse than the current up/left/etc. keys.

@grorp
Copy link
Member Author

grorp commented Feb 9, 2024

TBH, I'm still not sure which API is better - the current one forces modders to think, so maybe they're less likely to make the mistake you're describing. Both API designs, the current one or your suggestion, would be fine for me.

@rubenwardy
Copy link
Member

I think that movement_x and movement_y is better. Euler angles are meh and having movement_speed will be misinterpreted as being the actual desired speed, not the commanded 0-1 value.

@grorp
Copy link
Member Author

grorp commented Feb 9, 2024

I've updated the API, thanks for your input.

@sfan5
Copy link
Member

sfan5 commented Feb 15, 2024

Haven't looked at the code but I wanted to note that it's important that across all combinations of old/new servers/clients the server sees the direction keys being "pressed" if the player uses the analog stick to move.
You can check this using the test code from #11924.

And I suppose with this PR there's a new requirement: If I move using direction keys the server should still see matching values for the analog stick.

@y5nw
Copy link
Contributor

y5nw commented Feb 15, 2024

It would also be nice for mods to be able to read whether the input was made with a keyboard or using a touchscreen/joystick; then mods/games that (ab)use movement input for other purposes would be able to set up different control schemes based on whether the player uses keyboard or touchscreen input.

@grorp
Copy link
Member Author

grorp commented Feb 15, 2024

sfan5: I think both requirements are fulfilled by this PR and I have done some testing with different old/new server/client combinations, but I'd be thankful if you or someone else could also verify that this works as expected.

y5nw: That's a different issue, see #12264.

@grorp grorp added the Rebase needed The PR needs to be rebased by its author. label Feb 24, 2024
@grorp grorp removed the Rebase needed The PR needs to be rebased by its author. label Feb 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@ Client / Controls / Input Feature ✨ PRs that add or enhance a feature @ Script API Supported by core dev Not on the roadmap, yet some core dev decided to take care of this PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants