How to modularize the script code ?

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

Hello,

I’m creating a game and my player.gd script has a lot of functions to manage a lot of things.

I have some functions and parts of the code I would like to externalize, I’m used with python import/export but here with Godot I don’t know if I can do this.

  • Is there a way to have a file like utils.gd where I have some generic functions and import them in my player.gd script ?

I thought about create a parent class playerParent.gd that extends from KinematicBody2D and then make my player.gd extends for the playerParent.gd but this wouldn’t be enough.

Any help would be appreciated !

:bust_in_silhouette: Reply From: eons

Scripts are (like) resources, you can load or preload them to use where you need them

Thanks, I didn’t see that info on the docs, I may be blind

AlvaroAV | 2017-03-16 19:45

:bust_in_silhouette: Reply From: keke

What relation does your player have to the part of the code you want to externalize? It it a “has a” or an “is a”?

For example, if you have code that gives your player a health bar, you might say that it “is a” ‘health object’. In that case, you would want to have something like your playerParent.gd example - or rather healthObject.gd. That way you could also derive enemies from that class, and they would have health bars, too.

If instead the relationship is a “has a” - like the player “has a” weapon, they maybe you want to do something like eons suggested - load the script/class as an object. This way you could, say, give the player multiple weapons by instancing the weapon object multiple times. Also do this if the code is just a bunch of utility functions, with no persistent variables/internal state.

I hope this explanation doesn’t complicate things unnecessarily (this is the way it was explained to me)

Could you elaborate when you say, load the script/class as an object?

mawesome4ever | 2021-05-28 22:50

See the documentation eons linked in the other answer for elaboration.

keke | 2021-05-29 02:02

:bust_in_silhouette: Reply From: idbrii

You could make a script full of static functions.

For example, I have random.gd:

static func _sum_weights(choices) -> float:
    var sum := 0.0
    for key in choices:
        var weight = choices[key]
        sum += weight
    return sum

# Usage:
#   weighted_choice({'epic': 1, 'rare': 3, 'common': 6})
static func weighted_choice(choices):
    var sum := _sum_weights(choices)
    var threshold := decimal(0, sum)
    for key in choices:
        var weight = choices[key]
        threshold -= weight
        if threshold <= 0:
            return key

    push_error("weighted_choice failed to return a value.")
    return null

I want to use the code in other modules:

const Random = preload("res://code/util/random.gd")
var rarity

func _ready():
    rarity = Random.weighted_choice({'epic': 1, 'rare': 3, 'common': 6})

Or if you use class_name in random.gd, then you don’t need the preload statement when using it elsewhere.