Struct Embedding in GDScript

GDScript supports composition through inheritance and inner classes, which can be used to achieve similar functionality to struct embedding in other languages. Here’s an example demonstrating this concept:

extends Node

class Base:
    var num: int

    func _init(n: int):
        num = n

    func describe() -> String:
        return "base with num=%d" % num

class Container:
    var base: Base
    var str: String

    func _init(n: int, s: String):
        base = Base.new(n)
        str = s

    func describe() -> String:
        return base.describe()

func _ready():
    # When creating instances, we initialize the base explicitly
    var co = Container.new(1, "some name")

    # We can access the base's fields through the base property
    print("co={num: %d, str: %s}" % [co.base.num, co.str])

    # We can also access the base's fields directly if we want
    print("also num:", co.base.num)

    # Since Container has a describe method that calls base.describe,
    # we can call it directly on co
    print("describe:", co.describe())

    # GDScript doesn't have interfaces, but we can use duck typing
    # to achieve similar functionality
    var d = co
    print("describer:", d.describe())

In this GDScript example:

  1. We define a Base class with a num property and a describe method.

  2. We then define a Container class that has a Base instance as a property, along with its own str property.

  3. In the _ready function (which is called when the node is added to the scene), we create an instance of Container.

  4. We can access the base’s fields through the base property of Container.

  5. The Container class has its own describe method that calls the base.describe method, demonstrating method forwarding.

  6. GDScript doesn’t have interfaces, but we can use duck typing to achieve similar functionality. Any object that has a describe method can be used where a “describer” is expected.

To run this script:

  1. Create a new script in Godot and paste this code.
  2. Attach the script to a Node in your scene.
  3. Run the scene.

The output will be similar to:

co={num: 1, str: some name}
also num: 1
describe: base with num=1
describer: base with num=1

This example demonstrates how GDScript can use composition and method forwarding to achieve functionality similar to struct embedding in other languages.