Work in progress

Godot documentation is being updated to reflect the latest changes in version 4.0. Some documentation pages may still state outdated information. This banner will tell you if you're reading one of such pages.

The contents of this page are up to date. If you can still find outdated information, please open an issue.

Custom Godot servers


Godot implements multi-threading as servers. Servers are daemons which manage data, process it, and push the result. Servers implement the mediator pattern which interprets resource ID and process data for the engine and other modules. In addition, the server claims ownership for its RID allocations.

This guide assumes the reader knows how to create C++ modules and Godot data types. If not, refer to Custom modules in C++.


What for?

  • Adding artificial intelligence.

  • Adding custom asynchronous threads.

  • Adding support for a new input device.

  • Adding writing threads.

  • Adding a custom VoIP protocol.

  • And more...

Creating a Godot server

At minimum, a server must have a static instance, a sleep timer, a thread loop, an initialization state and a cleanup procedure.


#include "core/object/object.h"
#include "core/os/thread.h"
#include "core/os/mutex.h"
#include "core/templates/list.h"
#include "core/templates/rid.h"
#include "core/templates/set.h"
#include "core/variant/variant.h"

class HilbertHotel : public Object {
        GDCLASS(HilbertHotel, Object);

        static HilbertHotel *singleton;
        static void thread_func(void *p_udata);

        bool thread_exited;
        mutable bool exit_thread;
        Thread *thread;
        Mutex *mutex;

        static HilbertHotel *get_singleton();
        Error init();
        void lock();
        void unlock();
        void finish();

        static void _bind_methods();

        uint64_t counter;
        RID_Owner<InfiniteBus> bus_owner;
        Set<RID> buses;
        void _emit_occupy_room(uint64_t room, RID rid);

        RID create_bus();
        Variant get_bus_info(RID id);
        bool empty();
        bool delete_bus(RID id);
        void clear();
        void register_rooms();

#include "hilbert_hotel.h"

#include "core/variant/dictionary.h"
#include "core/os/os.h"

#include "prime_225.h"

void HilbertHotel::thread_func(void *p_udata) {

        HilbertHotel *ac = (HilbertHotel *) p_udata;
        uint64_t msdelay = 1000;

        while (!ac->exit_thread) {
                if (!ac->empty()) {
                OS::get_singleton()->delay_usec(msdelay * 1000);

Error HilbertHotel::init() {
        thread_exited = false;
        counter =