Hour 25. Native Code
    What You’ll Learn in This Hour:
    Using GDNative to replace slow GDScript code
    Using third-party code via GDNative
    How the Godot source code is structured
    What common datatypes are used in the engine’s source
    Creating custom modules
    Godot’s open source nature lends itself to customization and letting users add their own code. There are a few documented ways of using
    native code in composition withGodot, making it possible to shape Godot the way you want it to be.
    In this hour, you’ll learn how to set up a basic shared library that can be used from withinGodot using GDNative. This shared library contains
    code that performs calculations that are more complicated inGDScript than they are in direct machine code. In another example, you’ll see
    how to link this library to another dynamic library, making GDNative a gateway for third-party code.
    After that, you’ll see how Godot source code is structured and where to find parts of the code. This is also an introduction to modules, which
    are extensions to the engine that get statically compiled into the binary.
    NOTE
    Development Environment
    Most of Godot’s core development happens in Linux, Windows and macOS, as the build environment is more mature in Linux systems. This
    chapter shows how to build GDNative libraries and Godot itself in Linux systems. The process is similar for other platforms, but Linux is the
    easiest to get into. To learn about the differences of these platforms, please visit the official documentation, as it has more information on that.
    GDNative
    GDNative is the C API that interfaces withGodot. This C API is used from external dynamic libraries. Because it is written in C, it uses a
    variety of languages, like C++, D, Rust, Nim, Go, or even Python. There is also the GDNative class inGodot’s API, which lets any scripting
    language load and call dynamic libraries. This is the simplest way to m
    a
    ke use of dynamic libraries, but things like NativeScript (explained in
    the second section) let you integrate the code from these libraries even more into Godot.
    Replacing Slow GDScript Code
    GDScript is an interpreted scripting language that gives it a lot of flexibility, but the downside is that the raw computing performance is worse
    than running straight native code.
    Consider the GDScript code in Listing 25.1 that writes values into a multi-dimensional array.
    LISTING25.1 Values in a Multi-Dimensional Array
    Click here to view code image
    extends Node
    var field_height = 21
    var field_width = 21
    var circle_center = Vector2(11, 11)
    var circle_radius = 5
    func _ready():
    printraw(“————————\n”)
    var data = []
    data.resize(field_height)
    for i in range(field_height):
    data[i] = []
    data[i].resize(field_width)
    for j in range(field_width):
    data[i][j] = field_value(i, j)
    printraw(data[i][j])
    printraw(“\n”) # newline
    printraw(“————————“)
    func field_value(y, x):
    var pos = Vector2(x, y)
    var distance = circle_center - pos
    if abs(distance.length()) <= (circle_radius / 2):
    # inner layer
    return ‘#’
    111111111
    22222222if abs(distance.length()) <= circle_radius:
    # outer layer
    return ‘/‘
    # not inside the circle
    return ‘ ‘
    Also consider the output in Listing 25.2. This code creates a “circle” with two layers. The outer layer has all #s in it and the inner layer has all
    /s.
    LISTING25.2 Circle Output
    Click here to view code image
    /
    ///////
    /////////
    ////#////
    ///###///
    ///#####///
    ///###///
    ////#////
    /////////
    ///////
    /
    The _ready method creates a 2D array by resizing an array and adding a new array (which gets resized as well). Each element in that array
    gets a value assigned that is determined by the field_value method.
    The field_value method takes both indices of the current element position inside the array as arguments. It calculates the distance to the
    center of the circle to determine the kind of symbol to input.
    Iteration can be slow inGDScript sometimes, making it unsuitable for huge procedural generation algorithms. If we wanted to write the same
    code in C using GDNative, we would come up with something like what is shown in Listing 25.3.
    LISTING25.3 Using C in GDNative
    Click here to view code image
    #include
    #include
    #define FIELD_WIDTH 21
    #define FIELD_HEIGHT 21
    #define CIRCLE_CENTER_X 11
    #define CIRCLE_CENTER_Y 11
    #define CIRCLE_RADIUS 5
    void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options o)
    {
    // Nothing for now.
    }
    int field_value(int y, int x)
    {
    godot_vector2 pos;
    godot_vector2_new(&pos, x, y);
    godot_vector2 circle_center;
    godot_vector2_new(&circle_center, CIRCLE_CENTER_X, CIRCLE_CENTER_Y);
    godot_vector2 difference = godot_vector2_operator_substract(&pos,
    &circle_center);
    float distance = fabs(godot_vector2_length(&difference));
    if (distance <= CIRCLE_RADIUS / 2)
    return ‘#’;
    if (distance <= CIRCLE_RADIUS)
    return ‘/‘;
    return ‘ ‘;
    }
    godot_variant GDN_EXPORT create_circle(void
    data, godot_array args)
    {
    godot_array field;
    godot_array_new(&field);
    godot_array_resize(&field, FIELD_HEIGHT);
    111111111
    22222222for (int i = 0; i < FIELD_HEIGHT; i++) {
    godot_array row;
    godot_array_new(&row);
    godot_array_resize(&row, FIELD_WIDTH);
    for (int j = 0; j < FIELD_WIDTH; j++) {
    godot_variant value;
    godot_variant_new_int(&value, field_value(i, j));
    godot_array_set(&row, j, &value);
    godot_variant_destroy(&value);
    }
    godot_variant row_variant;
    godot_variant_new_array(&row_variant, &row);
    godot_array_destroy(&row);
    godot_array_set(&field, i, &row_variant);
    godot_variant_destroy(&row_variant);
    }
    godot_variant ret;
    godot_variant_new_array(&ret, &field);
    godot_array_destroy(&field);
    return ret;
    }
    TIP
    Variant Data-type
    Variant is the data-type that can hold all other data-types inside it. It’s like a var inGDScript. It carries type information so the code knows how
    to process the data inside it properly.
    TIP
    GDNative Initialization Functions
    Every shared library that is used inGodot needs to have a godot_gdnative_init function. That function is called once the library loads. A
    godot_gdnative_terminate function is called when it gets unloaded. This is useful when third-party code needs to be de-initialized.
    As you can see, C code can be very verbose because all the constructors and destructors are called manually. Also, there is no automatic
    conversion to Variant, which adds even more noise to the code. It is wise to only resort to a GDNative solution if GDScript or other scripting
    solutions are really under-performing.
    In order to use this new algorithm that’s expressed in the C code, we need to create a GDNativeLibrary. A GDNativeLibrary is a resource that
    abstracts the file paths to the native libraries on all Godot-supported platforms (see Figure 25.1).
    FIGURE 25.1
    The GDNativeLibrary.
    Now that the GDNativeLibrary exists as a GDScript (or any other scripting language, for that matter), we can load and use the library (see
    Listing 25.4).
    LISTING25.4 Using the GDNativeLibrary
    Click here to view code image
    extends Node
    func _ready():
    printraw(“——————-\n”)
    var lib = GDNative.new()
    lib.library = load(“res://draw_circle_library.tres”)
    lib.initialize()
    var array = lib.call_native(“standard_varcall”, “create_circle”, [])
    for row in array:
    for ch in row:
    printraw(char(ch))
    printraw(“\n”)
    111111111
    22222222lib.terminate()
    printraw(“——————-\n”)
    Using Third-party Libraries
    One common use for GDNative is to make third-party libraries usable inGodot without having to create modules (more on modules later). This
    is as simple as compiling the library like previously shown, but linking to other libraries.
    Here is a small example (Listing 25.5) that makes use of the “stb image write” single-header-file library to draw a circle into an image and then
    write it to a disk.
    LISTING25.5 Drawing a Circle with STB Image Writer
    Click here to view code image
    #include
    #include
    #include
    #include
    #define STB_IMAGE_WRITE_IMPLEMENTATION
    #include “stb_image_write.h”
    #define FIELD_WIDTH 200
    #define FIELD_HEIGHT 200
    #define CIRCLE_CENTER_X 100
    #define CIRCLE_CENTER_Y 100
    #define CIRCLE_RADIUS 50
    void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options
    o)
    {
    // Nothing for now.
    }
    void field_value(int y, int x, uint8_t r, uint8_t g, uint8_t b)
    {
    godot_vector2 pos;
    godot_vector2_new(&pos, x, y);
    godot_vector2 circle_center;
    godot_vector2_new(&circle_center, CIRCLE_CENTER_X, CIRCLE_CENTER_Y);
    godot_vector2 difference = godot_vector2_operator_substract(&pos,
    &circle_center);
    float distance = fabs(godot_vector2_length(&difference));
    if (distance <= CIRCLE_RADIUS / 2) {
    r = 255;
    g = 0;
    b = 255;
    return;
    }
    if (distance <= CIRCLE_RADIUS) {
    r = 255;
    g = 0;
    b = 0;
    return;
    }
    r = 255;
    g = 255;
    b = 255;
    }
    godot_variant GDN_EXPORT create_circle(void data, godot_array args)
    {
    godot_variant ret;
    godot_variant_new_nil(&ret);
    uint8_t image_data = malloc(3 FIELD_HEIGHT FIELD_WIDTH);
    for (int i = 0; i < FIELD_HEIGHT; i++) {
    for (int j = 0; j < FIELD_WIDTH; j++) {
    uint8_t r;
    uint8_t g;
    uint8_t b;
    field_value(i, j, &r, &g, &b);
    uint8_t
    start_pixel = image_data + (FIELD_WIDTH 3 i + j 3);
    start_pixel[0] = r;
    start_pixel[1] = g;
    111111111
    22222222start_pixel[1] = g;
    start_pixel[2] = b;
    }
    }
    stbi_write_png(“circle.png”, FIELD_WIDTH,
    FIELD_HEIGHT, 3, image_data, 0);
    free(image_data);
    return ret;
    }
    Because this is a header-only library, there are no extra steps involved to get it to compile. As an example of using a shared library, we link to
    libcurl and get the version string (see Listing 25.6).
    TIP
    Using Third-party Libraries
    In this next example, we use libcurl to get some data from a library. Make sure you have the library installed and that the linker can find it;
    otherwise, it won’t work.
    LISTING25.6 Using libcurl to Retrieve Data
    Click here to view code image
    #include
    #include
    #include
    void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options
    o)
    {
    // Nothing for now.
    }
    godot_variant GDN_EXPORT godot_libcurl_version(void data, godot_array args)
    {
    godot_variant ret;
    char version_string = curl_version();
    godot_string gdstring;
    godot_string_new_data(&gdstring, version_string, strlen(version_string));
    godot_variant_new_string(&ret, &gdstring);
    godot_string_destroy(&gdstring);
    return ret;
    }
    Now we can get the libcurl version (see Figure 25.2) from GDScript and other languages (Listing 25.7).
    FIGURE 25.2
    Libcurl and OpenSSL.
    LISTING25.7 libcurl with GDScript
    Click here to view code image
    extends Node
    func _ready():
    var lib = GDNative.new()
    lib.library = load(“res://curl.tres”)
    lib.initialize()
    var version = lib.call_native(“standard_varcall”, “godot_libcurl_version”, [])
    $Label.text = version
    lib.terminate()
    It works similarly for static libraries. Add the .a/.lib file to the compile command, and it works out of the box.
    111111111
    22222222Creating a NativeScript Using C
    NativeScript is a script that uses an underlying shared library for its code instead of source code. Writing NativeScripts in C can be quite
    verbose and error-prone, so there are some bindings to other languages to make it easier. Other languages include D, Nim, Go, Rust, and
    C++.
    When using a GDScript or VisualScript, Godot inspects the contents of those files directly. It can see available methods, the properties, and
    exported signals. With shared libraries, it’s not that simple, because Godot can’t parse the binary code on all platforms and decide which
    symbols are important or not. Also, Godot has signals that have no direct counterpart in native code. So, a registering mechanism is used in
    NativeScripts: the library tells Godot what it has to offer. This is done in the godot_nativescript_init function.
    In this example (Listing 25.8), we define a class “Adder,” which adds up numbers. It’s not very useful, but the setup needed to create a simple
    example and a more complex one is exactly the same.
    LISTING25.8 Adder Adds Up Numbers
    Click here to view code image
    #include
    #include
    void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options
    o)
    {
    // Nothing for now.
    }
    void adder_new(godot_object o, void method_data)
    {
    int
    call_count = godot_alloc(sizeof(int));
    call_count = 0;
    return call_count;
    }
    void adder_destroy(godot_object
    o, void method_data, void userdata)
    {
    int call_count = userdata;
    godot_free(call_count);
    }
    godot_variant adder_add(godot_object
    o, void method_data, void userdata,
    int num_args, godot_variant args)
    {
    int call_count = userdata;
    (
    call_count)++;
    int a = godot_variant_as_int(args[0]);
    int b = godot_variant_as_int(args[1]);
    int result = a + b;
    godot_variant res;
    godot_variant_new_int(&res, result);
    return res;
    }
    godot_variant adder_get_call_count(godot_object o, void method_data, void
    *userdata, int n, godot_variant
    a)
    {
    int call_count = userdata;
    godot_variant res;
    godot_variant_new_int(&res,
    call_count);
    return res;
    }
    void GDN_EXPORT godot_nativescript_init(void handle)
    {
    godot_instance_create_func create_func = {};
    create_func.create_func = &adder_new;
    godot_instance_destroy_func destroy_func = {};
    destroy_func.destroy_func = &adder_destroy;
    godot_nativescript_register_class(handle, “Adder”, “Node”, create_func,
    destroy_func);
    {
    godot_method_attributes method_attr;
    method_attr.rpc_type = GODOT_METHOD_RPC_MODE_DISABLED;
    godot_instance_method method = {};
    method.method = &adder_add;
    godot_nativescript_register_method(handle, “Adder”, “add”, method_attr,
    111111111
    22222222method);
    }
    {
    godot_method_attributes method_attr;
    method_attr.rpc_type = GODOT_METHOD_RPC_MODE_DISABLED;
    godot_instance_method method = {};
    method.method = &adder_get_call_count;
    godot_nativescript_register_method(handle, “Adder”, “get_call_count”,
    method_attr, method);
    }
    }
    As you can see, the class gets registered in the godot_nativescript_init function, along with its method. The godot_method,
    godot_create_func, and godot_destroy_func structures each have method_data and free_func fields. Some bindings might
    reuse the same functions for different methods, but they need to pass some custom data to know what to actually perform. This data is passed
    to these functions in the method_data field. If the data is heap allocated, free_func is called on the data before the library gets unloaded.
    In the simple C example, we don’t need these features, so we leave both fields 0, which is done by using the {} initialization.
    The create_func gets called when the script instance gets created. The function is supposed to return a pointer to the object data that the
    script needs, so it’s like a pointer in C++. This pointer is passed to all functions that are registered on that class for all of the objects as the
    user_data parameter. A structure with fields is allocated, the pointer returns, and all of the methods access the member variables through
    that pointer. In the case of the Adder, it is a pointer to an integer in which we store the number of times the add method gets called. The
    get_call_count method returns the number so it can be inspected from another script.
    Now that the library is in place, you can create a new NativeScript file. It’s like a GDScript file, but it doesn’t contain source code. Instead,
    there’s a link to a GDNativeLibrary and the name of the class used. One library can contain multiple classes, so it’s necessary to specify which
    one should be used.
    Because the Adder class extends node, we can use it as an AutoLoad. Select the .gdns file and name it “Adder,” then you can use it from
    anyGDScript (see Listing 25.9).
    LISTING25.9 Adder in AutoLoad
    Click here to view code image
    extends Node
    func _ready():
    var res = Adder.add(13, 37)
    print(res)
    res = Adder.add(4, 2)
    print(res)
    print(Adder.get_call_count())
    This creates the following output:
    # output
    50
    6
    2
    Modules
    Modules are parts of Godot source code that represent an extension of the engine functionality. Many features of Godot are implemented in
    modules; for example, GDScript or the TileMap Node. Modules are statically compiled into the Godot binary and have access to all other
    classes and functions defined inside Godot.
    Because modules are usually independent from each other and only depend on core functionality—but not the other way around—it’s possible
    to disable modules at compile time.
    For example, if a game doesn’t use the TileMap Node, it’s possible to disable the tilemap module to reduce the size of the game’s binary.
    Godot Source Structure
    In order to write modules, you first have to have a basic understanding of the wayGodot’s source code is structured. If you obtain the source
    code, you will see these top-level directories:
    core: This folder contains all of the core data types, including Vectors, Variant, Arrays, HashMap, Set, and many more. Godot’s object
    system is defined here as well. So, in short, it contains all of the basic building blocks.
    doc: Contains the documentation data that’s accessible in the script editor.
    drivers: Contains the code that implements interfaces of the engine using a specific third-party library or technology; for example, the
    OpenGL renderer and the PNG image loader. When a driver is platform-specific (for example, the rendering code for a console), it’ll be
    found in its corresponding “platform” directory.
    editor: Because the editor is just a “game” inGodot, it needs to be written somewhere. This is where. The whole editor is defined in the
    EditorNode class. The export templates get compiled without editor sources, so this whole directory gets ignored when building these
    111111111
    22222222export templates.
    main: Contains the code for the main loop. It defines how one iteration of the game loop executes.
    misc: Contains mostly scripts for special situations. It also includes git commit hooks you can use when working on a pull request for the
    engine.
    modules: This is where custom modules are placed. Modules extend the engine; they aren’t fundamental, but they still offer functionality.
    For example, GDScript is a module just like TileMap or ENet (networking). This is where we need to place our custom modules for the
    engine to find them.
    platform: Godot runs on many platforms. It abstracts APIs to make working with these platforms easier. This is where the actual
    implementation of these interfaces is defined for each platform.
    scene: The source code for all the different node types are defined here, including 3D, 2D, and control. Everything is in here.
    servers: The servers are the low-level systems that are in charge of the main features of the engine: rendering, physics, audio, etc.
    Servers have an asynchronous API and are a fairly higher-level abstraction than usual to achieve better portability. The scene system
    abstracts this architecture away from the user.
    third-party: Godot makes use of multiple third-party libraries. These are included in this directory, along with licensing information.
    Compiling Godot
    Godot uses the scons build system. To build Godot, you need to execute the following command in the Godot source directory:
    scons p = x11 -j n
    scons: Is the name of the build program. It executes the code in the Sconstruct file.
    P: Is shorthand for platform.
    x11: Is the platform for which we’re building. In this case, it’s Linux/X11. You can also write platform=x11. Other platforms to build
    are: windows, osx, iphone, and javascript. For platforms that are not your host platform, you need some form of cross compiler
    on your system.
    –j n: Where n is the number of jobs.
    The latter argument specifies the number of “jobs” used to build Godot. One job is one compiler process used to build your program. So, if you
    specify -j 4, four compiler processes will run in parallel. This can cause problems on Windows due to file locking. If your compilation throws
    errors because files cannot be opened, try to leave this option out or set use 1 as n.
    On some systems that have a more recent version of OpenSLL installed, it may be necessary to pass the argument
    builtin_openssl=yes to the scons command.
    TIP
    Compiling on Different Platforms
    Godot builds on many different platforms, and on some (looking at you, Windows), you need to perform some extra steps to compile Godot.
    The official documentation has more information about the compilation process for different platforms.
    Custom Modules
    Because the design of Godot is to “keep it simple,” in general, there may be missing functionality for some games. For example, a module to
    connect two devices via Bluetooth may be needed for a game that makes use of it to implement some form of local multiplayer across devices.
    This functionality is unneeded in the majority of games, so it’s not a good idea to include this functionality as a core part of the engine.
    This is where custom modules are popular. They let users extend the engine with functionality that’s needed for their games.
    Modules are rather easy to create and distribute, but they require a recompilation of the engine. Here is the directory structure of the module:
    adder
    register_types.h
    register_types.cpp
    adder.h
    adder.cpp
    SCsub
    config.py
    When scons starts to build Godot, it searches in the modules/directory. Every subdirectory represents a module (Listing 25.10).
    LISTING25.10 Searching for Modules
    Click here to view code image
    # SCsub
    Import(‘env’)
    env.add_source_files(env.modules_sources, “
    .cpp”)
    The SCsub file is a scons subbuildscript, which tells scons how to build the module. The config.py is a file that only needs two methods:
    can_build, which returns True or False depending on if the module is built on that current platform or not, and configure, which is used
    to change scons settings if needed (Listing 25.11).
    111111111
    22222222LISTING25.11 The conifg.py File
    Click here to view code image
    # config.py
    def can_build(platform):
    return True
    def configure(env):
    pass
    Scons adds a file called register_types.cpp to the build queue for every subdirectory.
    This file needs to include a function called register_MODULENAME_types, where MODULENAME is the name of the subdirectory (Listing
    25.12). This function is used to register types defined in the module. It’s a lot like the registering process inGDNative. Godot needs to know
    what classes and types are available.
    LISTING25.12 Including register_MODULENAME_types
    Click here to view code image
    // register_types.h
    void register_adder_types();
    void unregister_adder_types();
    And:
    // register_types.cpp
    #include “register_types.h”
    #include “core/class_db.h”
    #include “adder.h”
    void register_adder_types() {
    ClassDB::register_class();
    }
    void unregister_adder_types() {
    }
    Like in the GDNative example, we create a class called “Adder” that ad
    ds numbers and has a way to tell us how often the method gets called
    (Listing 25.13).
    LISTING25.13 Adding Adder
    Click here to view code image
    // adder.h
    #ifndef ADDER_H
    #define ADDER_H
    #include “core/reference.h”
    class Adder : public Reference {
    GDCLASS(Adder, Reference)
    int call_count = 0;
    public:
    static void _bind_methods();
    int add(int a, int b);
    int get_call_count();
    };
    #endif
    To create a class we can use from the scripting system, we need to be able to register that class to ClassDB. The macro GDCLASS(name,
    base) needs to be used as the first thing in the class declaration. This macro code implements some methods needed for the introspection
    system of ClassDB to work properly (Listing 25.14).
    LISTING25.14 Registering the Class to ClassDB
    Click here to view code image
    // adder.cpp
    #include “adder.h”
    void Adder::_bind_methods() {
    ClassDB::bind_method(D_METHOD(“add”, “a”, “b”),
    &Adder::add);
    ClassDB::bind_method(D_METHOD(“get_call_count”),
    &Adder::get_call_count);
    }
    111111111
    22222222int Adder::add(int a, int b) {
    call_count++;
    return a + b;
    }
    int Adder::get_call_count() {
    return call_count;
    }
    NOTE
    Introspection
    Introspection is the ability to see and query properties of certain types of classes. Classes inGodot have the get_method_list and
    get_property_list methods for that purpose. A lot more of those methods are available in the ClassDB singleton.
    The bind_methods is the method that needs to register all of the other properties that the class exposes. This is done using the
    ClassDB::bind_method method. The D_METHOD macro is for including debug information about the method in debug builds. In export
    templates, these do not generate debug information.
    After that, we recompile the engine with scons p = x11 -j n, where n is the number of jobs.
    Everything should compile without errors.
    Now, you can use the Adder class in a GDScript to test if everything works (Listing 25.15).
    LISTING25.15 Adder Testing
    Click here to view code image
    extends Node
    func _ready():
    var adder = Adder.new()
    var res = adder.add(13, 37)
    print(res)
    res = adder.add(4, 2)
    print(res)
    print(adder.get_call_count())
    As you can see, the NativeScript and module version are very similar in usage. Other high-level language bindings for NativeScript can make
    the implementation of it look much more like the module implementation, but every binding handles things differently, so the examples here
    were in C, because NativeScript and GDNative are pure C APIs.
    Summary
    This was a short introduction to using native code withGodot, be it via GDNative or modules. What was shown here is only a small part of what
    is possible to achieve. The truth is that a chapter in a book isn’t enough to talk about everything that the engine source code has to offer and
    how to interact with it to get the most out of Godot. There are many ways to get in contact with developers to get more information about how to
    make better use of the engine’s APIs. Hopefully, this chapter gave you a first impression of what the workflow looks like!
    Q&A
    Q. What is the difference between a NativeScript and a module?
    A. A NativeScript is like a GDScript—but it uses native code. A module gets compiled into the engine and can add more functionality to the
    core of the engine than a GDNative library can.
    Q. Can every language that can produce C-callable code be used to create GDNative libraries?
    A. Yes, yet some languages are easier to use withGDNative than others. This is the case because of many different things like Garbage
    Collection or binary compatibility.
    Q. How can a GDScript/VisualScript/[Insert other scripting language here] method be called froma NativeScript?
    A. It can be done by using the Variant.call() method or the Object.call() method. The Object.call() method is be called by
    using so-called “method binds,” which we didn’t have time to explore here.
    Workshop
    Answer the following questions to make sure you understood the content of this hour.
    Quiz
    1. Where do modules need to be put in the Godot source code to be compiled?
    2. What files need to be present for Godot to find and compile modules?
    111111111
    222222223. Why do libraries need to be linked in a GDNativeLibrary resource?
    4. For what are the godot_gdnative_init and godot_gdnative_terminate functions used?
    5. For what is the godot_nativescript_init function used?
    Answers
    1. Modules need to be put inside the modules/ directory.
    2. Every module needs to include a config.py and SCsub file. These are used to check if the module can be compiled and to let the build
    system know which files should get compiled and how.
    3. Godot runs on multiple platforms, which use different formats for native libraries. The GDNativeLibrary includes paths for every library for
    every platform. This way, native code can run on all platforms that support GDNative.
    4. Those functions are supposed to be used for setup and de-initialization of possible third-party libraries.
    5. It’s used to register script classes to Godot, much like how the _bind_methods method is used in modules.
    Exercises
    Try to make a button that spawns Sprites that fall down and increase a counter when they leave the screen:
    1. Read the source file main/main.cpp; it contains the code that starts off anyGodot application.
    2. Explore the GDScript module in module/gdscript. If you’re familiar with compiler development, you can try to add your own
    language construct (like a do-while loop, for example).
    3. Look at the core/object.h, core/object.cpp, and core/reference.h files. They contain the definition of the Object
    system with its signal and group subsystems, as well as the implementation of Reference-Counting—the main memory management
    system used inGodot.
    111111111
    22222222