Reference the actual variable and not the value of the variable

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Coenster

I don’t know how to properly ask this question. I am definitely not a programmer and still a huge noob to godot, but I am trying to learn. I need some help in reducing the amount of code I have.

I have a script that auto loads and it contains many variables. I also have several scripts that changes the values of these variables. How this works is the player clicks on a box on the screen and then some scripts will change the values of the box. The format is something like this:

extends Node2D
onready var BoxData = $"/root/BoxData"

func set_box_values():
    if selected_box == box1:
        BoxData.box1 = new_box_id
        BoxData.box1_color = new_color
        BoxData.box1_lvl += 1
    elif selected_box == box2
        BoxData.box2 = new_box_id
        BoxData.box2_color = new_color
        BoxData.box2_lvl += 1

I get the box values like this:

func _on_box1_button_up():
    selected_box = BoxData.box1
    box_color = BoxData.box1_color
    box_lvl = BoxData.box1_lvl

 func _on_box2_button_up():
    selected_box = BoxData.box2
    box_color = BoxData.box2_color
    box_lvl = BoxData.box2_lvl

This works, but I have a problem with how i wrote the code. There are more than 30 boxes and each box has about 6 values and the boxes can be interacted with in about 5 different ways. So i physically repeated the example code you see above 30 times and then 5 times more for each interaction. So I ended up with about 1300 lines of code in one script.

I want to reduce the amount of code, because I feel it is getting out of control.

So my question.

Is it possible that i can reference the actual variable, not the value, but the actual variable, for example this “BoxData.box1_color” and not the value of the boxes color. so that i don’t need to use if functions to check which box was selected, I can just set the values directly, like this:

func set_box_values():
    selected_box = new_box_id
    box_color = new_color
    box_lvl += 1

This will drastically reduce the unnecessary amount of lines.

I hope you understand my question. If you need more information to get a clearer picture about what i am trying to do please ask.

P.S. the way I currently coded things, is that called duck typing? I heard the term on youtube(gamesfromscrach). Does it mean inefficient code?

Thanks in Advance

:bust_in_silhouette: Reply From: Dlean Jeans

I would put the variables into a Box script so you can get them like this:

box_color = box.color
box_lvl = box.lvl

You only need to write one function for the button_up signal:

func _on_box_button_up(box):
    selected_box = box
    box_color = box.color
    box_lvl = box.lvl

While you’re at it, you can consider removing box_color and box_lvl entirely since you can write selected_box.color and selected_box.lvl.

If you can’t put the variables into each box, you can do this alternatively:

func _on_box_button_up(box):
    selected_box = BoxData.get(box.name)
    box_color = BoxData.get('%s_color' % box.name)
    box_lvl = BoxData.get('%s_lv' % box.name)

then connect all of the box with:

for box in get_all_the_boxes():
    box.connect('button_up', self, '_on_box_button_up', [box])

replace self with the node with the _on_box_button_up function.

Thanks for your help.

I did some more research on your second suggestion and learned that it is possible to use a combination of get and set to change the variables directly without using if functions.

 box_lvl = BoxData.get('%s_lv' % box.name)
 box_lvl += 1
 BoxData.set('%s_lv' % box.name, box_lvl)

and for all the buttons I ended up adding them to groups and connecting the signals

for box in get_tree().get_nodes_in_group("box_button"):
    box.connect("button_up", self, "_box_pushed", [box])

These reduced my code significantly. Thanks for taking the time to help.

Coenster | 2019-06-13 03:07