Unable to disable a button

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By lonnwolf031

I am making a multiplayer dice game. At this moment I struggle with disabling a button.
I want the ‘roll dice’ button to be disabled if it’s not the players turn of when the current player already pressed the button. I haven’t tested with multiple users yet, but when I test it I am still able to press the button multiple times. I tried several ways, and the code for disabling a button I’ve looked up and gives no errors.

Here is some relevant code, as you can see I tried multiple places for disabling the button, but none of them seem to work.

onready var _action = $VBoxContainer/HBoxContainer/SubVBoxContainer/Action


func _on_RollButton_pressed():
	if get_tree().is_network_server():
		do_action("roll")
		print("roll is done")
		#disable button
		_action.set_disabled(true)
		next_turn()
	else:
		rpc_id(1, "request_action", "roll")


sync func set_turn(turn):
	_turn = turn
	if turn >= _players.size():
		return
	for i in range(0, _playersDict.size()):
		if i == turn:
			_action.disabled = false
			#_playByRulesRolledDice()
			#_list.set_item_icon(i, _crown)
			pass
		else:
			
			#_playByRulesOthers()
			#_list.set_item_icon(i, null)
			pass
	if _players[turn] != get_tree().get_network_unique_id():
		_action.disabled = true
	elif clicked == true:
		_action.disabled = true
	else:
		_action.disabled = false

Are you sure the _action.set_disabled(true) is actually referencing the button node itself?

Tato64 | 2021-04-12 17:44

:bust_in_silhouette: Reply From: Legorel

In the _on_RollButton_pressed function, you disable the button on the server side (because of the if get_tree().is_network_server()).
The problem is, all instances of your game (the server and all the clients) have a different scene tree, so when you disable a button on the server, nothing happens on the client.

Tho fix this problem you need to do 2 things:

  1. On the server, instead of doing
 _action.set_disabled(true)

You need to do a rpc_id to the corresponding player and inside the remote function (on the client) you need to disable the button. You also need to do the same thing for enabling the button

  1. When you are doing a multiplayer, game you need to remember 1 rule: Never trust the client
    This means you need to keep track of which player is able to click the button and which isn’t, on the server.
    When a player do a rpc_id to the server when he click the button, the server must test first if the player is actually able to click the button (in case of someone modifying there game to cheat)