How do I design a hand of cards (a row of cards), where cards can be clicked, dragged, and reordered? (Includes video and demo project)

Godot Version

4.2.1

Question

I’ve explained my question in the above video. The video is about 12 minutes long, but the first 2 minutes will show the issue I am having, and then I go into further and further detail about my project code and the bug / design challenge I’m facing.

You can also check out my small demo project from GitHub - DevJac/godot_100: Learn Godot with 100 independent demos . Import folder 015_card_order_problem into Godot to experiment with the code yourself. Or view it on GitHub, there’s about 60 lines of script, 2 scenes, and 3 nodes total in the project.

In text form though:

I’m creating a card game and I want a row of cards where players can click and drag cards and change the order of the cards. If anyone has seen Balatro, I love the UI of that game and it is a good example of the UI I’m trying to create for my game (at least in regards to the cards in hand).

I’m using Control nodes and signals for a lot of the interactions with cards. Each card scene has a Control node, and I use the signals from the Control nodes to detect which card the player is clicking or hovering over.

The problem is sometimes I need to change the render order of the cards, and once I change the render order of the cards (with the z_index), then the Control nodes no longer work as expected, because the render order of the nodes and the control order of the nodes is not the same.

As far as I know there is no way to change the control order of nodes without actually changing the order of the nodes in the scene tree. I’m also using the scene tree to keep track of the card order as related to the in-game rules. This is a lot of concerns to be handled by a single sequence of cards in the scene tree; I’m looking for a way to have better “separation of concerns”.

I’ve considered using a separate data structure, but then I would have to keep my own data structure and the scene tree in a semi-synced state; sometimes they would need to be the same, sometimes they would need to be different. It seems complicated and error prone, but maybe it’s my best option?

I’ve also considered not using Control nodes and writing my own event handling logic. This would give me a lot of flexibility, but I would be throwing away Godot’s default Control nodes and all the convenience they bring.

I don’t know how to approach this fairly basic design with Godot. Godot is the only game engine I have used.

I wish it was possible to decouple the control order (with respect to Control nodes) from the order of nodes in the scene tree. I don’t think this is possible though? It’s possible with render order using z_index, but not possible with control order. I’ve seen a lot of conflicting information related to node order and Control nodes and rendering order, etc; some of it is out of date, I think some of it was never correct to begin with, I don’t know, but I would like to discuss how these parts of Godot can help (or not help) me solve this simple UI design I’m going for.

It’s hard to explain the UI effect I’m going for in words, so at least watch the first 2 minutes of the video.

Thanks for your help.

1 Like

I understand you situation ( I liked the vid), did you ever try object picking with area2d over a control node? Maybe also raycast to sense cards.

Then you could have different collision layers for card in hand and on table separately. Or have multiple rays. A highlight ray. And you can turn on or off your rays depending on the hand state.

1 Like

Thanks for providing a lot of context for your issue, the video helped a lot.

You can try to have different states for the cards if you are Dragging a card the other cards can change to a state that doesn’t have this hover animation, or block this animation for the cards that are not being dragged.

Here I saw one video for the Balatro animations recreation in Godot, he has the same hover design maybe you can get the idea, but he doesn’t explain this ordering.