Skip to content

Player abilities#2032

Draft
manuq wants to merge 14 commits intomainfrom
player-abilities
Draft

Player abilities#2032
manuq wants to merge 14 commits intomainfrom
player-abilities

Conversation

@manuq
Copy link
Collaborator

@manuq manuq commented Mar 6, 2026

New input controls mapping

For keyboard + mouse (best experience):

  • WASD for moving
  • Shift for sprint
  • Space bar to interact
  • Mouse move for aiming
  • Left click to grapple
  • Right click to repel (new)

For just keyboard:

  • Arrows for moving + aiming
  • Shift for sprint
  • Z to grapple (new)
  • X to repel (new)
  • Space bar to interact

For joypad (let's say XBox):

  • Left stick or D-pad for moving
  • Right stick for aiming
  • LB for sprint
  • RB to repel (new)
  • RT to grapple
  • A to interact

Resolve #1375

@github-actions
Copy link

github-actions bot commented Mar 6, 2026

Play this branch at https://play.threadbare.game/branches/endlessm/player-abilities.

(This launches the game from the start, not directly at the change(s) in this pull request.)

@manuq
Copy link
Collaborator Author

manuq commented Mar 6, 2026

For now the draft ignores player modes at all (except for "defeating"), and makes the 2 abilities "repel" and "grapple" active all the time. Interact is not considered an ability.

recording.webm

I did a few changes in the input mapping. But I really welcome alternatives:

For keyboard + mouse:

  • WASD for moving
  • Shift for sprint
  • Space bar to interact
  • Mouse move for aiming
  • Left click to grapple
  • Right click to repel (new)

For just keyboard:

  • Arrows for moving + aiming
  • Shift for sprint
  • Z to grapple (new)
  • X to repel (new)
  • Space bar to interact

For joypad (let's say XBox):

  • Left stick or D-pad for moving
  • Right stick for aiming
  • LB for sprint
  • RT to grapple
  • B to repel (new)
  • A to interact

(While doing this I noticed that the Champ quest introduced input maps to the project).

What about the mouse cursor? Should it always be a crosshair except while interacting with dialogue or the game menu?

We should think about: How would this affect the lore quests and the StoryQuests? Some ideas:

  • "Repel" and "grapple" abilities should be part of the player progression and persisted in game state.
  • But StoryQuests should not obey the lore progression and Player instances in SQs.
  • Ideally each SQ has their own copy of player.tscn (like the existing NO_EDIT_projectile.tscn) and could even have their own custom abilities.

Some other changes needed:

  • Replace the existing player modes. Maybe think in new ones? For the sake of input handling, at least player defeated is a mode.
  • When the player goes through the grappling line, the PlayerHook takes control over the player walking. This is a bit hacky and could be refactored. Maybe another mode?
  • I noticed that PlayerRepel also handles player harm for projectiles. This should be rearranged.
  • A StoryQuest "After the Tremor" was using player scripts that I refactored here. Is probably broken.
  • The input hints will need to be updated.

@wjt
Copy link
Member

wjt commented Mar 9, 2026

For now the draft ignores player modes at all (except for "defeating"), and makes the 2 abilities "repel" and "grapple" active all the time. Interact is not considered an ability.

recording.webm
I did a few changes in the input mapping. But I really welcome alternatives:

For keyboard + mouse:

  • WASD for moving
  • Shift for sprint
  • Space bar to interact
  • Mouse move for aiming
  • Left click to grapple
  • Right click to repel (new)

Great combination of actions.

For joypad (let's say XBox):

  • Left stick or D-pad for moving
  • Right stick for aiming
  • LB for sprint
  • RT to grapple
  • B to repel (new)
  • A to interact

I tested these - it's great to have the combination of actions available at the same time!

It is very hard to repel while also aiming the grappling hook with the right stick because the same thumb is used for both. We could perhaps move the repel action to a shoulder button.

I was trying to think of bindings that I thought were good. It's a bit hard to google for the bindings for the game "control" for obvious reasons but they're here. In that game the right stick moves the camera, and the left stick moves the character - sort of similar. They use:

  • Sprint: Push the left stick (we use LB)
  • Shield (a defensive action like repel): LB
  • Dodge (another defensive action): B

But this is something we don't have to get right first time...

(While doing this I noticed that the Champ quest introduced input maps to the project).

This seemed the simplest way they could do what @jgbourque was asking for: a custom player script with gaps for multiple new special abilities. If we had had the changes you're drafting here with 4 actions with distinct bindings, maybe champ could have instead have (ab)used those, e.g. use the grapple action for the teleport special ability.

What about the mouse cursor? Should it always be a crosshair except while interacting with dialogue or the game menu?

I would say:

  • Pointer when in the game menu or when the cursor is moved during dialogue
  • Crosshair when grappling is available
  • Otherwise hidden
  • "Repel" and "grapple" abilities should be part of the player progression and persisted in game state.
  • But StoryQuests should not obey the lore progression and Player instances in SQs.

Great point. And you could imagine a storyquest where the player-character gains one of these abilities during the course of the storyquest... So the persistence/restoring of these abilities needs to be factored out in some way.

  • Ideally each SQ has their own copy of player.tscn (like the existing NO_EDIT_projectile.tscn) and could even have their own custom abilities.

I think ultimately we will need this but ironically the reason I was starting small with the combat projectile scene, and the sequence puzzle object scene, is that those scenes are unlikely to change dramatically & need updating in every storyquest, unlike the player scene where we knew that exactly this refactoring would be needed!

manuq added 7 commits March 9, 2026 15:10
Let them happen all at once without changing the actual modes for now.
Only leave the mode "defeating" to disable player interaction and
abilites (repel, grapple). This prevents refactoring the modes right
now.
This was introduced a while ago and left invisible. It has the shape of
StoryWeaver so it won't work when replacing the SpriteFrames in
StoryQuests.
This could be a const, or the "repel" string can be used directly.

This is only preparation for upcoming animations refactor.

Note: There are references in StoryQuest "After the Tremor" that
this change may break.
Rename the node that provides this ability to PlayerRepel. Adjust the
scripts accordingly.
And the Area2D nodes that had this script. In 2 scenes from Void quest.
Add a signal to the repel ability and use it to play the animation when
the property changes, instead of checking it constantly in _process().

Loop the repel animation in the script by adding a handler to the
animation finished signal, and remove the loop mode from the animation
itself.

Give a class name to PlayerRepel.
For keyboard + mouse: Use right click to repel.

For keyboard only: Use Z to repel and X to grapple. This is on the basis
that the player will use arrow keys for moving in this case.

Interact continues being Space in both setups.
@manuq manuq force-pushed the player-abilities branch from 4eb0eb2 to f03d044 Compare March 9, 2026 18:10
manuq and others added 4 commits March 9, 2026 18:53
To the right shoulder (RB in XBox). So it doesn't collide with A for interaction. And so it can be used
at the same time as aiming the grappling hook with the right stick.

Co-authored-by: Will Thompson <wjt@endlessaccess.org>
Into a new PlayerHarm node inside the Player scene. There is no actual harm today, but the "got hit" animation and handling of the
projectiles entering the player hitbox are here now, split from the PlayerRepel ability.

Also, connect the signals from the editor, not in the _ready() function.
@manuq manuq force-pushed the player-abilities branch from 5ff7cf4 to e0ce806 Compare March 9, 2026 21:53
manuq added 3 commits March 9, 2026 19:24
During dialogue, set the cursor to the arrow. When dialogue ends,
set it to the cross.
When the game is paused set the cursor to the arrow. And when unpaused,
set it to the cross shape.
@manuq
Copy link
Collaborator Author

manuq commented Mar 9, 2026

It is very hard to repel while also aiming the grappling hook with the right stick because the same thumb is used for both. We could perhaps move the repel action to a shoulder button.

Good idea! I have updated it to be the right shoulder button. I added the input mapping to the PR description. I also started a wiki page in which we can document this. I wonder since we are not targetting consoles if the joypad experience for aiming can be left as-is for now? And we consider mouse + keyboard the best experience? Up for discussion!

I was trying to think of bindings that I thought were good. It's a bit hard to google for the bindings for the game "control" for obvious reasons but they're here. In that game the right stick moves the camera, and the left stick moves the character - sort of similar. They use:

  • Sprint: Push the left stick (we use LB)
  • Shield (a defensive action like repel): LB
  • Dodge (another defensive action): B

But this is something we don't have to get right first time...

Interesting! I think is worth trying moving sprint to "push left stick" and LB for the repel action.

(While doing this I noticed that the Champ quest introduced input maps to the project).

This seemed the simplest way they could do what @jgbourque was asking for: a custom player script with gaps for multiple new special abilities. If we had had the changes you're drafting here with 4 actions with distinct bindings, maybe champ could have instead have (ab)used those, e.g. use the grapple action for the teleport special ability.

OK!

What about the mouse cursor? Should it always be a crosshair except while interacting with dialogue or the game menu?

I would say:

  • Pointer when in the game menu or when the cursor is moved during dialogue
  • Crosshair when grappling is available
  • Otherwise hidden

I agree, I started doing so in the last 3 commits but I'm not sure I'm doing it in the right places. I did:

  • Pause overlay: Set cursor to arrow and back to cross when paused/unpaused
  • Dialogue balloon: Set cursor to arrow and back to cross when started/ended
  • Mouse manager: Set cursor to cross by default

I'm still thinking about the rest of your feedback (player progression). Thanks!

@wjt
Copy link
Member

wjt commented Mar 10, 2026

Interesting! I think is worth trying moving sprint to "push left stick" and LB for the repel action.

I think this also gets back to our "who is the player" question. In my experience trying to teach people how to play Katamari Damacy (which is controlled basically entirely with the two sticks), the "click both joysticks to do a 180° turn" control is really surprising to people at first: less experienced gamers don't see the joysticks as being buttons as well as joysticks. But you only have to teach it once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revisit player modes

2 participants