|
|
|
|
Reply From: |
Zylann |
As soon as you know which parts of your code can work as distinct components, then you can start splitting it (your first refactoring step). It’s true you can start a game prototype as a single messy script, but after some time it’s good to start organizing stuff, if you know you are going to work more on it.
In Godot, splitting stuff is done through different ways:
Usually, scenes are made of more than one node, and some of them can have a script dedicated to do one task. I usually use the root node as the “master” script, and other specific tasks get delegated to child nodes (particles, sound, animations… even debugging).
You can put only one script per node, but you can still use a simple Node
and add it as a child to use it as modular component. Finally, communication is done through signals (equivalent of events that you can connect to listeners), functions, groups, or the tree itself (get_parent() or iteration on children for example).
Scripts don’t have to be on a node, they can also be standalone, and used as classes.
For example, you can create a thing.gd
and use it as a class in another script, like that:
const Thing = preload("thing.gd")
func _ready():
var thing = Thing.new()
# Do stuff with it...
Scripts can also have static methods, so you can put helper functions in them:
var i = Thing.calculate_stuff(5)
In Godot, global variables don’t exist. Instead, what you can do is put a script in the “auto-load” section of your project: http://docs.godotengine.org/en/stable/tutorials/step_by_step/singletons_autoload.html
When given names, these scripts will act like nodes that are accessible from anywhere, and stay alive even if the scene tree is reloaded or the scene changes. IMO this is only useful for storing information that is persistent across scenes for the whole game. Be careful with them because something accessible from anywhere can be messed up more easily on the long term.
Finally, it’s also possible to declare classes within a script. It’s not like inner classes of Java, though (they don’t have access to the parent instance through this
):
class Thing:
var name = ""
func _init(n):
name = n
func _ready():
var thing = Thing.new("Hello")
Thank you for the reply, that is rather interesting. Didn’t really know you can do things like subclasses. Going to definitely read up on the design patterns to get an idea. The singletons method sounds nice but it seems like if those scripts are always present upon reloading or changes to a scene, wouldn’t that hit performance a bit?
zzxyr88 | 2016-10-24 20:44
Singletons don’t hit performance at all, it just depend on what you do with them.
Zylann | 2016-10-24 22:29
Great comment! Do you have any links for more info about how to write standalone scripts? Do they just inherit from Script?
JymWythawhy | 2016-11-01 13:35
You don’t have to inherit anything (well, technically, they inherit Reference, but you don’t need to worry about that).
What I called “standalone” scripts are .gd files like any other, but you can omit the extends XXX
. You can use them as classes, like the example in my post.
I mean, that, put in a file, is enough to create a basic class:
greeter.gd
var message = "Hello"
func greet():
print(message)
Then in another script you can instance it like this:
# Note: you can also write the preload() directly,
# but putting it in a const makes the code easier to maintain
const Greeter = preload("greeter.gd")
func _ready():
var g = Greeter.new()
g.greet()
Unfortunately I don’t remember where in the doc this feature is mentionned, I think I was told that by discussing on IRC, Discord or on Q&A ^^
Zylann | 2016-11-01 20:18
Thank you. This community is great.
JymWythawhy | 2016-11-02 12:40