Hi, I have two character nodes in a turn-based battle with a bunch of stats in them. I would like for them to switch places and then inherit each other's data/animation. Essentially, I want the Player1 node to become the Player2 node and vice versa.

I accomplished this in old projects by doing something like:

var temp = p1.stats
p1.stats = p2.stats
p2.stats = temp

And repeat for every value I need. It could work here, but when accounting for all the variables and animations, it sounds annoying. Plus, anything I add in the future will also need to be added to this switch code. I'm looking to save a future headache.

So I figured I could just swap the .name properties of the nodes. That would work exactly how I want. So I tested this:

var p1 = $Player1
var p2 = $Player2
print(p1.name)
p1.set_name("temp")
p2.set_name("Player1")
p1.set_name("Player2")
print(p1.name)

And it does indeed print "Player1" then "Player2." The name does change. But unfortunately, they've not actually switched in-game. Godot apparently keeps track of name changes after runtime so that any code referring to the original name gets updated accordingly. That sounds like a great QOL feature, but not for me, because that's the whole reason I changed the names in the first place!

So my question is: is there a way to turn this off? Can I just let anything referencing "Player1" instead target a different node if I switch them? Or am I doomed to rewrite anything that references the node directly?

  • If you use get_node() to re-fetch the nodes by name after changing the names, that should work. But that might require adding more calls to get_node(), and could be inefficient.

    Sushibee175 Guess I've got the rest of my night booked!

    Refactoring code a lot is normal programming. 🙂

The node name is just a descriptive tag. The engine doesn't use that to keep track of nodes.

You could define variables that reference the players:

var player1: Node
var player2: Node

Initially set player1 to the Player1 node, and player2 to the Player2 node.

player1 = $Player1
player2 = $Player2

The values could be switched later:

var temp: Node = player1
player1 = player2
player2 = temp

That should work if you always reference the nodes using the variables player1 and player2. (I would use different names, e.g. player_a and player_b, to avoid confusion.)

    DaveTheCoder I've been referring to the player nodes by calling
    get_node("/root/Player"+str(number))
    So I figured that changing their assigned names could alter the way that they're called from other nodes. Seems like a useful way to do it.

    Your method is the alternative that I thought of (putting the Player nodes into an array), but I do have a lot of existing references that use the get_node method. I was just trying to avoid rewriting/replacing them all. Guess I've got the rest of my night booked! Thanks for your answer.

      If you use get_node() to re-fetch the nodes by name after changing the names, that should work. But that might require adding more calls to get_node(), and could be inefficient.

      Sushibee175 Guess I've got the rest of my night booked!

      Refactoring code a lot is normal programming. 🙂

        DaveTheCoder If you use get_node() to re-fetch the nodes by name after changing the names

        Welp, this is the most embarrassing topic I've started. I was positive I was already doing this, but this encouraged me to check again and, yep, my uses of get_node() were indeed all called before the switch. Everything actually works fine.

        I may just rework everything into an array anyway if there's an issue of get_node being more expensive, but for testing right now, I'm all set. Thanks for your help!