Skip to content

Add touch input controller #806

Closed

Description

@manuq

Add a touch input system to make the player walk, run, and trigger an action.

It is common in mobile to add a virtual controller for moving in one screen side (left side, for example), and one or more actions in the other side (right side, for example).

For the movement controller:

  • A circle appears whenever the user press and hold the screen, with the pressed position as the center of the circle.
  • While holding, moving the finger far from the circle center makes the player walk in that direction.
  • When the finger reaches the border of the circle, the player runs.
  • Releasing the finger the player stops.

Currently the sole action for interacting (in cosy mode) and attacking (in combat mode) is "ui_accept". But that may change by this task. In that case, a tap anywhere in the right side could trigger the action.

Could an addon like Godot Virtual Joystick suit our needs, without being a big dependency to maintain? This one also gives a vector Input.get_vector(&"ui_left", &"ui_right", &"ui_up", &"ui_down") from the virtual controller.

PS Sokoban is another story, maybe we implement that one in a separate issue? One idea is to swipe up, down, left and right for moving in the player inside the sokoban.

XP Summary (total 600)

Subdomain Skill XP
Engineering: Gameplay & Systems Programming Problem Solving 150
Engineering: Gameplay & Systems Programming Creativity & Design Thinking 75
Engineering: Gameplay & Systems Programming Technical Literacy 150
Game Design: Game Feel & UX Problem Solving 75
Game Design: Game Feel & UX Creativity & Design Thinking 75
Game Design: Game Feel & UX Technical Literacy 75

Activity

  1. wjt commented on Jun 17, 2025

    @wjt
    Member

    I think we would also want to hide the input hints (at the start of Fray's End) when using touch controls.

  2. wjt commented on Jul 21, 2025

    @wjt
    Member

    I did some "research" this weekend, also known as "playing Turnip Boy Commits Tax Evasion and then realising it is free on Android so I can compare its three control schemes".

    PC, keyboard

    Image
    Image

    PC, gamepad

    Image

    Android, touchscreen

    Image
  3. wjt commented on Jul 21, 2025

    @wjt
    Member

    Some observations: because the HUD text and icons are small (18px font, 12px diameter for button icons), the input hints can be always visible without harming gameplay. I kind of like the simplicity of doing this. It would remove the need to hide and show the input hints at various points in the game. (Currently we show: directional input & interact at the bottom of Fray's End; Repel in the first ink combat scene; and Sprint at the start of the stealth scene; undo/reset/skip in Sokoban (but not directions).) Personally I think directional input is self-explanatory and we could remove the WASD bindings without any real cost to playability.

    The interact prompt is split in two:

    • An abstract inverted triangle with an ! on it is displayed above the interact target
    • The first action (A on Xbox joypad, z on keyboard) changes its label from "trip" (a kind of dash) to "interact"

    Turnip Boy can only have one item equipped at a time. In the screenshots above, I have a sword equipped, but I can also equip a watering can. If you squint you can see the hilt of the sword over Turnip Boy's back. In the touch controls it's way more obvious of course.

    There is no "run" action AFAICT so a simple joystick suffices in touch mode.

    The direction of the sword attack (or watering can pour) is based on the direction of movement: there is no separate aim function.

  4. manuq commented on Jul 21, 2025

    @manuq
    CollaboratorAuthor

    This is a great reference @wjt, thanks.

  5. moved this from Untriaged to Todo in Threadbare Developmenton Sep 3, 2025
  6. ItsGianPierre commented on Sep 5, 2025

    @ItsGianPierre

    I plan to work on this.

  7. moved this from Todo to In Progress in Threadbare Developmenton Sep 5, 2025
  8. manuq commented on Sep 24, 2025

    @manuq
    CollaboratorAuthor

    De-assigning after no response.

  9. moved this from In Progress to Todo in Threadbare Developmenton Sep 24, 2025
  10. wjt commented on Feb 17, 2026

    @wjt
    Member

    Godot 4.7 adds a built-in VirtualJoystick control: https://godotengine.org/article/dev-snapshot-godot-4-7-dev-1/#input-virtualjoystick

    I tried it and... it didn't work. Then I realised why: we handle player movement in _unhandled_input(). But the input event is handled – by the VirtualJoystick!

    func _unhandled_input(_event: InputEvent) -> void:
    var axis: Vector2 = Input.get_vector(&"move_left", &"move_right", &"move_up", &"move_down")
    var speed: float
    if player_hook.is_throwing_or_aiming():
    speed = aiming_speed
    elif Input.is_action_pressed(&"running"):
    speed = run_speed
    else:
    speed = walk_speed
    input_vector = axis * speed

    If I moved the code above in player.gd from _unhandled_input() to _process() then it worked fine.

    Assuming that this is the intended behaviour (and is also not just a consequence of emulating touch input from mouse), we will have to rework our input handling – or rather, disabling player movement during dialogue etc. – to adopt this.

  11. manuq commented on Feb 17, 2026

    @manuq
    CollaboratorAuthor

    Whoa, VirtualJoystick for free! This is great news!

  12. manuq commented on Oct 15, 2026

    @manuq
    CollaboratorAuthor

    In #3016 I have something basic working:

    Grabacion.de.pantalla.desde.2026-10-15.10-45-39.mp4

    I'm going to merge it since I was able to pass the 2 main lore quests using my phone (musician quest, void quest). The decisions I've made are explained in the PR description. I'm going to open followups for better usability and bugs. For instance:

  13. added a commit that references this issue on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions