2 Commits

Author SHA1 Message Date
algodoogle 2efeb2dd24 Merge branch 'master' of https://git.offcoursegames.com/JonShard/VRyHungry1 2026-08-11 15:22:57 +01:00
algodoogle 88dcfbafdf table fix 2026-08-11 15:22:42 +01:00
2 changed files with 24 additions and 3 deletions
+12
View File
@@ -165,6 +165,12 @@ func _spawn_item_from_data(data: Variant) -> Node:
inst.set(key, data["props"][key]) inst.set(key, data["props"][key])
if not owns_world(): if not owns_world():
_gate_station(inst) _gate_station(inst)
# ...and again once the node is in the tree. Gating before _ready() is what
# keeps a station from ever ticking on a client, but a station's own
# _ready() runs afterwards and can undo it (table.gd re-arms its state
# machine with set_process(true)). The deferred pass runs after every
# _ready() in this frame and re-asserts the gate.
_gate_station.call_deferred(inst)
return inst return inst
@@ -187,10 +193,16 @@ func _gate_station(node: Node) -> void:
if child.is_in_group("station"): if child.is_in_group("station"):
_gate_station(child) _gate_station(child)
return return
# Only report a gate that actually changed something: this runs a second time
# (deferred) for every spawned station, and on a re-gate that found nothing to
# do there is nothing worth logging.
var changed := node.is_processing()
for zone in node.find_children("*", "XRToolsSnapZone", true, false): for zone in node.find_children("*", "XRToolsSnapZone", true, false):
changed = changed or zone.enabled or zone.is_processing()
zone.enabled = false zone.enabled = false
zone.set_process(false) zone.set_process(false)
node.set_process(false) node.set_process(false)
if changed:
log_line("gated station (non-owner peer): %s" % node.name) log_line("gated station (non-owner peer): %s" % node.name)
+11 -2
View File
@@ -132,7 +132,13 @@ func _ready() -> void:
for snap_zone_node in snap_zones: for snap_zone_node in snap_zones:
snap_zone_node.has_picked_up.connect(_on_object_picked_up) snap_zone_node.has_picked_up.connect(_on_object_picked_up)
snap_zone_node.has_dropped.connect(_on_object_dropped) snap_zone_node.has_dropped.connect(_on_object_dropped)
set_process(true) # Never on a client: the state machine is server-authoritative and _state is
# synced down. NetworkManager._gate_station() already turned processing off,
# but a spawned station is gated BEFORE its _ready() runs, so an unconditional
# set_process(true) here would quietly re-arm the FSM on every client — and
# _state_end(EATING) re-enables the snap zones, which then fight the server
# for items sitting on the table.
set_process(NetworkManager.owns_world())
_set_state(TableState.EMPTY) _set_state(TableState.EMPTY)
@@ -258,8 +264,11 @@ func _collect_money_from_food():
func _set_snap_zones_enabled(value: bool) -> void: func _set_snap_zones_enabled(value: bool) -> void:
# Enabling is the world owner's call only — a client's zones stay gated no
# matter what state its copy of the FSM thinks it is in.
var enabled := value and NetworkManager.owns_world()
for zone in snap_zones: for zone in snap_zones:
zone.enabled = value zone.enabled = enabled
## Server-only state transition: sets the new state's timer and assigns ## Server-only state transition: sets the new state's timer and assigns