I started using Godot earlier this year and I made my first game with it. In the game there is a shop in which you can purchase upgrades to buff the player. The script I wrote (or copy and pasted) used a lot of if statements. Below is a picture displaying a portion of the code.
I would like to know how I could do this more efficiently next time, because I feel 500+ lines of copy paste is a bit too much...
Thanks.

    NayNay_0204 Whenever you see same or similar pieces of your code repeating multiple times, it's a sure sign you're doing something wrong. To eliminate repetition, you need to (re)organize your data into data structures like arrays and dictionaries and use loops to iterate over that data and/or indexing to access particular elements. Putting reusable pieces of code into functions can also help with this. If the same code needs to run multiple times (but with different data), turn it into a function that takes this data as arguments.

      xyz that is the most difficult part of programming. Figuring out how to tell program what you want to achieve.

      But like @xyz said, its pretty much up to figuring out the correct structure and data flow of your project.

      Look at this https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html many times there is good info how to achieve certain things more efficiently

      Match is pretty useful, and they say its faster under some scenarios.
      https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html#basic-syntax

      • xyz replied to this.

        kuligs2 The emphasis should always be on good data "architecture". When the data is properly structured it can save you from having to write a lot of excess code. The structure itself will "do the work".

        There's an old Fred Brooks wisdom I like to quote. It's from The Mythical Man Month, a book on software engineering written in the stone age of computing but as relevant today as when it first came out.

        Show me your flowcharts and conceal your tables, and I shall continue to be mystified. Show me your tables, and I wonโ€™t usually need your flowcharts; theyโ€™ll be obvious

        "Flowcharts" here refers to code/algorithms and "tables" refer to data structures.

        Linus Torvalds put the same wisdom it in a bit modernized manner:

        Bad programmers worry about the code. Good programmers worry about data structures and their relationships.

        kuligs2 Match is pretty useful, and they say its faster under some scenarios.

        Not in the scenario shown in the OP though ๐Ÿ˜ƒ

        NayNay_0204 To make things more practical, here's how this should be handled properly. Note that code is not for you to copy paste, it's to study and understand the approach.

        class_name Resources
        var coins = 0
        var iron = 0
        var gold = 0
        func _init(coins: int, iron: int, gold: int): 
        	self.coins = coins
        	self.iron = iron
        	self.gold = gold
        func can_afford(amount: Resources):
        	return self.coins >= amount.coins and self.iron >= amount.iron and self.gold >= amount.gold
        func spend(amount: Resources): 
        	self.coins -= amount.coins
        	self.iron -= amount.iron
        	self.gold -= amount.gold
        var player_resources = Resources.new(1000, 100, 10)
        var bettery_level = 0
        
        var battery_cost = [ 
        	Resources.new(100, 10, 2), 
        	Resources.new(200, 15, 3),
         	Resources.new(400, 25, 4),
        	# etc
        ]
        
        func _on_battery_button_pressed():
        	var battery_level_max = battery_cost.size()-1
        	if bettery_level+1 <= battery_level_max:
        		var upgrade_cost = battery_cost[bettery_level+1]
        		if player_resources.can_afford(upgrade_cost):
        			player_resources.spend(upgrade_cost)
        			bettery_level += 1

        And poof, just like that, 500 lines of code gone, replaced by two dozen lines. Much easier to read and debug, and more importantly, makes tweaking the numbers that affect the gameplay actually quite painless, as opposed to your initial code when such a task becomes a nightmare.

        Now adding a new battery level requires merely appending a single line of data to battery_cost array. Likewise, changing the cost for a particular level can be done simply by altering the three numbers for that level.

        The rest is "automatically" taken care of by a few lines of code that contain no repetition whatsoever and read like a short story... courtesy of appropriately structured data ๐Ÿ™‚

          xyz i never seen the init function before.. is it different from ready?

          • xyz replied to this.

            kuligs2 i never seen the init function before.. is it different from ready?

            I'd wager there are great many things you've never seen ๐Ÿ˜‰
            Yes it's different. It's the class' constructor invoked when the object is created. It works like Python's __init__()

              kuligs2 _ready is implemented in Node, hence it cannot be the object constructor as that would mean that all objects in the class hierarchy upstream of Node would not be able to implement a constructor. That wouldn't be all that good ๐Ÿ˜ƒ

              _ready is called when a node is added to the scene tree. This always happens after the node object has already been constructed (and its constructor called). This may never happen at all though. You can create a node and never add it to the tree. In that case the node will have existed without its _ready ever been called.

              6 days later

              xyz
              I now see why arrays can be very useful for tasks like thisโ€ฆ and why structuring my code like this could help prevent headaches.
              Thanks for your help. Very appreciated!