GDExtension Godot-cpp - NetworkManager Class causing crashes

Godot Version

4.7

Question

Hi guys,

I’m trying to write a NetworkManager class using Godot-cpp, using this tutorial: https://youtu.be/rQ9mDxvuoeA?si=D_zRthnWsdfxYTg_

I am loading my NetworkManager class as a Node, adding it to a scene that gets auto-loaded.
The editor loads just fine, but when I go to run it, it loads the separate-window to test, and then crashes.

This is the crash log, it crashes after the “test1” print statement and crashes at Steam::get_singleton()->initRelayNetworkAccess();:

Godot Engine v4.7.stable.official.5b4e0cb0f - https://godotengine.org
D3D12 12_0 - Forward+ - Using Device #0: NVIDIA - NVIDIA GeForce RTX 5070 Ti

test1

================================================================
CrashHandlerException: Program crashed with signal 11
Engine version: Godot Engine v4.7.stable.official (5b4e0cb0fd279832bbdd69fed5354d4e5ad26f88)
Dumping the backtrace. Please include this when reporting the bug on: https://github.com/godotengine/godot/issues
Load address: 7ff645d60000

[1] 7ff789e260e1 (main+40c60e1) - no debug info in PE/COFF executable
[2] 7ff82f61f932 (ntdll.dll+11f932) - no debug info in PE/COFF executable
[3] 7ff82f6647ae (ntdll.dll+1647ae) - no debug info in PE/COFF executable
[4] 7ff82f5221c6 (ntdll.dll+221c6) - no debug info in PE/COFF executable
[5] 7ff82f6640ed (ntdll.dll+1640ed) - no debug info in PE/COFF executable
[6] 7fff0e87e483 (desperate.windows.template_debug.x86_64.dll+16e483) - no debug info in PE/COFF executable
[7] 7fff0e7141d6 (desperate.windows.template_debug.x86_64.dll+41d6) - no debug info in PE/COFF executable
[8] 7ff789b67a40 (main+3e07a40) - no debug info in PE/COFF executable
[9] 7ff7881a53c5 (main+24453c5) - no debug info in PE/COFF executable
[10] 7ff7881a5373 (main+2445373) - no debug info in PE/COFF executable
[11] 7ff7881ac69f (main+244c69f) - no debug info in PE/COFF executable
[12] 7ff785d62ecd (main+2ecd) - no debug info in PE/COFF executable
[13] 7ff785db2501 (main+52501) - no debug info in PE/COFF executable
[14] 7ff785db253d (main+5253d) - no debug info in PE/COFF executable
[15] 7ff785d610c8 (main+10c8) - no debug info in PE/COFF executable
[16] 7ff785d613f5 (main+13f5) - no debug info in PE/COFF executable
[17] 7ff82e24e956 (kernel32.dll+2e956) - no debug info in PE/COFF executable
[18] 7ff82f587c1b (ntdll.dll+87c1b) - no debug info in PE/COFF executable
[19] -1 (main+-7ff785d60001) - no debug info in PE/COFF executable
-- END OF C++ BACKTRACE --
================================================================

Here is my NetworkManager.cpp file:

#include "NetworkManager.hpp"
#include <godot_cpp/classes/multiplayer_api.hpp>
#include <godotsteam.h>
#include <godotsteam_multiplayer_peer.h>

using namespace godot;

void NetworkManager::_bind_methods()
{
	ClassDB::bind_method(D_METHOD("on_lobby_created", "result", "lobbyID"), &NetworkManager::on_lobby_created);
	ClassDB::bind_method(D_METHOD("on_lobby_joined", "lobbyID", "permissions", "lobbyIsLocked", "response"), &NetworkManager::on_lobby_joined);
	ClassDB::bind_method(D_METHOD("on_join_requested", "lobbyID", "steamID"), &NetworkManager::on_join_requested);
	ADD_SIGNAL(MethodInfo("host_created"));
	//ClassDB::bind_method(D_METHOD("_add_player", "id"), &NetworkManager::_add_player);
	//ClassDB::bind_method(D_METHOD("_remove_player", "id"), &NetworkManager::_remove_player);
}

NetworkManager::NetworkManager()
{

}

NetworkManager::~NetworkManager()
{

}

void NetworkManager::_ready()
{
	if (Engine::get_singleton()->is_editor_hint())
	{
		return;
	}
	UtilityFunctions::print("test1");
	UtilityFunctions::print("Steam Initialized: ", Steam::get_singleton()->steamInit(480, true));
	UtilityFunctions::print("test2");
	Steam::get_singleton()->initRelayNetworkAccess(); // this line is crashing
	UtilityFunctions::print("test3");
	Steam::get_singleton()->connect("lobby_created", Callable(this, "on_lobby_created"));
	Steam::get_singleton()->connect("lobby_joined", Callable(this, "on_lobby_joined"));
	Steam::get_singleton()->connect("join_requested", Callable(this, "on_join_requested"));
}

void NetworkManager::_process(double delta)
{
	if (Engine::get_singleton()->is_editor_hint())
	{
		return;
	}
}

void NetworkManager::on_lobby_created(int result, int lobbyID)
{
	if (result == Steam::get_singleton()->RESULT_OK)
	{
		this->lobby_id = lobbyID;
		peer = memnew(SteamMultiplayerPeer);
		peer->set_server_relay(true);
		peer->create_host();
		get_multiplayer()->set_multiplayer_peer(peer);
		emit_signal("host_created");
	}
}
//TODO: Implement this
void NetworkManager::on_lobby_joined(uint64_t lobbyID, int permissions, bool lobbyIsLocked, int response)
{
	if (response == Steam::get_singleton()->CHAT_ROOM_ENTER_RESPONSE_SUCCESS)
	{
		if (Steam::get_singleton()->getLobbyOwner(lobbyID) == Steam::get_singleton()->getSteamID())
		{
			return;
		}
		peer = memnew(SteamMultiplayerPeer);
		peer->set_server_relay(true);
		peer->create_client(Steam::get_singleton()->getLobbyOwner(lobbyID));
		get_multiplayer()->set_multiplayer_peer(peer);
	}
}

void NetworkManager::on_join_requested(uint64_t lobbyID, uint64_t steamID)
{
	Steam::get_singleton()->joinLobby(lobbyID);
}

//void NetworkManager::_add_player(int id)
//{
//	 
//}
//
//void NetworkManager::_remove_player(int id)
//{
//
//}

Steam is logged-in and running as this was being tested.

Really would like some help with this, thanks guys.

Update: I know that this has to do with the Steam singleton returning as null. It runs successfully, just without the functionality of NetworkManager.

void NetworkManager::_ready()
{
	if (Engine::get_singleton()->is_editor_hint())
	{
		return;
	}

	if (!Steam::get_singleton()) {
		UtilityFunctions::print("Steam singleton is null!");
		return;
	} // Adding this, allows it to run because Steam seems to be null for some reason...

	UtilityFunctions::print("test1");
	UtilityFunctions::print("Steam Initialized: ", Steam::get_singleton()->steamInit(480, true));
	UtilityFunctions::print("test2");
	Steam::get_singleton()->initRelayNetworkAccess(); // this fuckass line is crashing
	UtilityFunctions::print("test3");
	Steam::get_singleton()->connect("lobby_created", Callable(this, "on_lobby_created"));
	Steam::get_singleton()->connect("lobby_joined", Callable(this, "on_lobby_joined"));
	Steam::get_singleton()->connect("join_requested", Callable(this, "on_join_requested"));
}

when you watched the video did you see this comment?

“IMPORTANT INFORMATION: The most recent version of GodotSteam (4.20) seems to have a bug, with it’s “Initialize On Startup” check in the project settings. Until solved, I recommend using the version in the video (4.19)”

I saw your message and went ahead to see if it is a problem with GodotSteam. It still crashes on versions 4.19.1, and 4.19 .

I assume this has to do with my code now. :roll_eyes:

Doesn’t it crash in debug build?

If it does, use breakpoints, watch contextually important variables and call stacks.

If it doesn’t, you could build release with symbols, details varying according to tool chain in use.

Cheers !

Hi to whoever visits this post, I have decided to just stick with the the regular GodotSteam plugin from the asset library. I will probably come back to making a NetworkManager another time.

Trying to make a NetworkManager class is a bit of a hassle and doesn’t go very well with GodotSteam’s GDExtention code.

For those of you wish to embark on this challenge, here are some replies I got from the developer of GodotSteam and another helpful developer:

You can further contact them if you have any inquires about GodotSteam on their Steam group: Steam Community :: Group :: GodotSteaм

Thanks to everyone who responded