Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support rpc() and rset() even the client is not connected to a server #2728

Open
tavurth opened this issue May 15, 2021 · 1 comment
Open

Comments

@tavurth
Copy link

tavurth commented May 15, 2021

Describe the project you are working on

A multiplayer game where the client can also play offline, but connect to the server if it's online

Describe the problem or limitation you are having in your project

When I use the remotesync keyword and I'm the client I can't use rpc unless I'm connected to an actual server.
A simple implementation would look like:

Client -> Users GUI
Server -> Remote server

Sometimes the server is offline, and in this case the user should still be able to play, just not be able to see other players.
If the server comes back online then I can sync everything up.

In general the syncing is the hardest part here, but it's important for my use case.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Currently I have to check if the user is connected before using rpc otherwise it won't work even with remotesync

remotesync func say(message: String):
    $VoiceLabel.text = message

func _input(event: InputEvent):
    if event.is_action_pressed("say_hello"):
        rpc("say", "hello")

The above will fail if the user is not connected to a server.
Because of this the following is required:

remotesync func say(message: String):
    $VoiceLabel.text = message

func _input(event: InputEvent):
    if event.is_action_pressed("say_hello"):
        if Network.is_online():
            rpc("say", "hello")
        else:
            self.say("hello")

Where Network.is_online() looks like:

func is_online():
	return get_tree().get_network_peer().get_connection_status() == NetworkedMultiplayerPeer.CONNECTION_CONNECTED

This is cumbersome because it means duplication of hundreds of lines of code in the project.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Allow rpc for remotesync even when the user has no connection to server.

If this enhancement will not be used often, can it be worked around with a few lines of script?

See below...

I don't want to have each client become a host, although there might be a way for a client to switch between host and client modes based on a possible server connection.

Is there a reason why this should be core and not an add-on in the asset library?

This is GDscript core.

See also

@tavurth
Copy link
Author

tavurth commented May 15, 2021

I have found a workaround for this:

func is_online():
	return get_tree().get_network_peer().get_connection_status() == NetworkedMultiplayerPeer.CONNECTION_CONNECTED

func nrpc(node: Node, name: String, args = []):
	"""
	Call the `rpc` function on a node if the network is currently connected
	If the network is not connected we'll call the function name anyway
	"""
	# Ensure array to simplify logic
	if typeof(args) != TYPE_ARRAY:
		args = [args]
	
	if not is_online():
		return funcref(node, name).call_funcv(args)
	else:
		return funcref(node, "rpc").call_funcv([name] + args)

Then you can use the following in your nodes, where Network is loaded as a Singleton.

remotesync func say(message: String):
    $VoiceLabel.text = message

remotesync func some_multiarg(message: String, name: String):
    $VoiceLabel.text = message + " " + name

func _input(event: InputEvent):
    if event.is_action_pressed("say_hello"):
        Network.nrpc(self, "say", "hello")

    if event.is_action_pressed("say_hello_to"):
        Network.nrpc(self, "say", ["hello", "some_user"])

@Calinou Calinou changed the title Support rpc even when I'm a disconnected client Support rpc() and rset() even the client is not connected to a server May 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants