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.
Would like to know how to avoid using too many if statements.
- Edited
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.
- Best Answerset by NayNay_0204
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
- Edited
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.
- Edited
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
- Edited
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__()
- Edited
xyz i know what constructor is, im not that dumb, i just thought in godot its called ready
Hmm
https://forum.godotengine.org/t/functions-init-or-ready/14461/3
This could be useful, thanks
- Edited
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.
- Edited
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!