Is there a specific way to structure godot scripting to be more clean or clear?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By zzxyr88
:warning: Old Version Published before Godot 3 was released.

Hey guys back again with another question. I know I ask far too many but I was wondering how it works with godot. I’ve gone through some tutorials and it seems people do many things in one script. Wouldn’t it be better to kind of spread it out so the code or script rather is more clear?

The thing is I’m learning programming(java atm) and OOP concepts. Usually things seem to be split off to do different task. I’m guessing each node acts like a class and the script is just the instructions for that class when attached to a node/object?

Nodes and Scenes are classes, also scripts, you can instance those and add to the tree.
When you attach a script you are like overriding the base class for that node (Node scripts extends that node class, you can extend script too).

In games you won’t have classic OOP models but game design patterns you can use (like singleton, FSM), patterns will assist on taking form your game ideas/concepts and can be used with any paradigm, and they can help to get a clean and easy to mantain or extend game.

Keep in mind that most games die in prototypes and just a few are mantained or extended after release, that is why most code you will see have everything on a single place without using almost any OO features (if available on the engine) just to make something fast.

eons | 2016-10-24 16:50

Thanks for the reply, I was getting the idea that nodes were classes. I’ll read up on those different design patterns though to get an idea of how they work. I guess your right that people usually just make a test only to see that it may or may not work. If it makes things less of a hassle to split up I can see the point.

zzxyr88 | 2016-10-24 20:39

:bust_in_silhouette: 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:

  • Nodes:

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).

  • Standalone scripts:

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)
  • Singletons:

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.

  • Subclasses:

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. :slight_smile: This community is great.

JymWythawhy | 2016-11-02 12:40