0
\$\begingroup\$

I'm working on building an extension to MultiplayerPeer for Godot, using GDExtension. As is my custom, even if I don't end up pushing it to the final product, I always start with a Nullary Pattern implementation—that is, an implementation that doesn't actually do anything, but fits the mold—just to make sure that I'm getting the class recognition that I need in the editor. Then, I fill it out with proper behavior and turn it into my goal class.

Now, I've gone through MultiplayerPeer.hpp, and found a number of methods that end in = 0;, which makes them pure virtuals. I've implemented a nullary version of all of them, as far as I can tell. However, Godot, while recognizing that my class exists, is still telling me that it's abstract.

It's been a little while since I really sharpened my C++ skills, so I might be missing something else. Unfortunately I can't just trigger a compiler error with it and read the objection, as I'm building a library through Scons. nm has not been terribly helpful.

Here's my code:

nullary_multiplayer_peer.h:

#ifndef NULLARY_MULTIPLAYER_PEER
#define NULLARY_MULTIPLAYER_PEER

#include <godot_cpp/classes/multiplayer_peer.hpp>
#include <godot_cpp/classes/crypto.hpp>

namespace godot {

class NullaryMultiplayerPeer : public MultiplayerPeer {
    GDCLASS(NullaryMultiplayerPeer, MultiplayerPeer);
    
private:

protected:
    static void _bind_methods();

public:
    NullaryMultiplayerPeer();
    ~NullaryMultiplayerPeer();

    void set_transfer_channel(int p_channel);
    int get_transfer_channel() const;
    void set_transfer_mode(TransferMode p_mode);
    TransferMode get_transfer_mode() const;
    void set_refuse_new_connections(bool p_enable);
    bool is_refusing_new_connections() const;
    bool is_server_relay_supported() const;

    void set_target_peer(int p_peer_id);

    int get_packet_peer() const;
    TransferMode get_packet_mode() const;
    int get_packet_channel() const;

    void disconnect_peer(int p_peer, bool p_force = false);

    bool is_server() const;

    void poll();
    void close();

    int get_unique_id() const;

    ConnectionStatus get_connection_status() const;
};

}

#endif

nullary_multiplayer_peer.cpp:

#include "nullary_multiplayer_peer.h"
#include <godot_cpp/core/class_db.hpp>

using namespace godot;

void NullaryMultiplayerPeer::_bind_methods() {
}

NullaryMultiplayerPeer::NullaryMultiplayerPeer() {
}

NullaryMultiplayerPeer::~NullaryMultiplayerPeer() {
}

void NullaryMultiplayerPeer::set_transfer_channel(int p_channel) {}

int NullaryMultiplayerPeer::get_transfer_channel() const { return 0; }

void NullaryMultiplayerPeer::set_transfer_mode(TransferMode p_mode) {}

MultiplayerPeer::TransferMode NullaryMultiplayerPeer::get_transfer_mode() const { return MultiplayerPeer::TransferMode::TRANSFER_MODE_UNRELIABLE; }

void NullaryMultiplayerPeer::set_refuse_new_connections(bool p_enable) {}

bool NullaryMultiplayerPeer::is_refusing_new_connections() const { return true; }

bool NullaryMultiplayerPeer::is_server_relay_supported() const { return false; }

void NullaryMultiplayerPeer::set_target_peer(int p_peer_id) { }

int NullaryMultiplayerPeer::get_packet_peer() const { return 0; }
MultiplayerPeer::TransferMode NullaryMultiplayerPeer::get_packet_mode() const { return MultiplayerPeer::TransferMode::TRANSFER_MODE_UNRELIABLE; }
int NullaryMultiplayerPeer::get_packet_channel() const { return 0; }

void NullaryMultiplayerPeer::disconnect_peer(int p_peer, bool p_force) { }

bool NullaryMultiplayerPeer::is_server() const { return false; }

void NullaryMultiplayerPeer::poll() {}
void NullaryMultiplayerPeer::close() {}

int NullaryMultiplayerPeer::get_unique_id() const { return 0; }

MultiplayerPeer::ConnectionStatus NullaryMultiplayerPeer::get_connection_status() const { return MultiplayerPeer::ConnectionStatus::CONNECTION_DISCONNECTED; }

Lastly, here is the code with the error, in GDScript:

func _ready():
#   var peer = ENetMultiplayerPeer.new()
#   NullaryMultiplayerPeer.new()
    var peer = NullaryMultiplayerPeer.new()
    peer.create_server(9999)
    self.multiplayer.multiplayer_peer = peer

The specific error, and all that I've been able to get out of it, is "Native class 'NullaryMultiplayerPeer' cannot be instantiated as it is abstract."

Can anyone see what I'm missing, and why Godot sees it as an abstract class?

\$\endgroup\$
1
  • \$\begingroup\$ I'm beginning to suspect that an additional virtual function may exist somewhere higher up, from PacketPeer or something like that... not sure which one it is, though. \$\endgroup\$ May 31, 2023 at 17:27

1 Answer 1

4
\$\begingroup\$

I just ran into this while trying to extend StreamPeer to handle serial devices. It turns out that there is a StreamPeerExtension that is supposed to be as the base class instead. Using that got rid of the "Native class 'StreamPeerSerial' cannot be instantiated as it is abstract." error for me.

It looks like there is a MultiplayerPeerExtension class that should be used instead of MultiplayerPeer.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .