Try placing all the functions in the same node. I believe that RPC calls in your case don't recognize each other. You could try placing all the functions in the same file, And separate the code with puppet/master kget_tree().is_network_server()
function.
Example, joining _hello function would look like this:
remote func _hello():
if get_tree().is_network_server():
print("Hello !")
else:
print("Ok ok ok...")
I believe that problem was that you were trying to call functions across two different files with different type (Spatial and Node), without some extra parameters. So the simplest solution is to put everything in the same file for start.
EDIT
Oh and I forgot, you also have to refactor the logic from _ready function, which is not as simple as hello one. You may want to allow user to manually select if he wants to be a server or client, or do it automatically e.g. try joining the game and if it fails, create it. But I suggest that you do the first one.
So you would need to create a function, and init them on some user input (let's say if user presses "1" you call the start_server
and if he presses "2" you call start_client
), just a simple proof of concept, later you can put a more complex lobby interface if you decide to.
func start_client()
print("Client Started")
...
func start_server()
print("Server started")
...