6 Commits

Author SHA1 Message Date
JonShard 5c4baa272a Fix Move windows script 2026-08-20 12:57:45 +02:00
JonShard 59bd3d1d66 Warning hunt 2026-08-20 12:22:07 +02:00
JonShard a79096eb1d Add check_reference helper 2026-08-20 11:46:00 +02:00
JonShard 6432dca31a Fix queue in multiplayer 2026-08-20 11:18:38 +02:00
JonShard 655751e5bd Change log levels and add more logging 2026-08-20 10:48:20 +02:00
JonShard 06dde91468 Fix plates not syncing dirty 2026-08-20 09:23:25 +02:00
37 changed files with 200 additions and 169 deletions
+2 -4
View File
@@ -23,10 +23,8 @@ var _pending_absorb: Array[Node3D] = []
func _ready() -> void: func _ready() -> void:
area_3d.body_entered.connect(_on_body_entered) area_3d.body_entered.connect(_on_body_entered)
if not area_3d: Helper.check_reference(self, area_3d, Area3D)
SweetLogger.warning("{0} missing area_3d reference", [name]) Helper.check_reference(self, xr_pickable, XRToolsPickable)
if not xr_pickable:
SweetLogger.warning("{0} missing xr_pickable reference", [name])
# Absorbing items is a server decision (the container's holder is server- # Absorbing items is a server decision (the container's holder is server-
+17 -14
View File
@@ -4,26 +4,29 @@ extends Node
@onready var dirty_node: Node3D = $"../Dirty" @onready var dirty_node: Node3D = $"../Dirty"
@onready var container: ItemContainer = $"../Container" @onready var container: ItemContainer = $"../Container"
@export var is_dirty: bool = false
## Synced summary of the plate's contents (item ids). The contents themselves ## Synced summary of the plate's contents (item ids). The contents themselves
## are the real item nodes ItemContainer reparents under the plate; this is only ## are the real item nodes ItemContainer reparents under the plate; this is only
## what other systems read to ask "what is on this plate" without walking them. ## what other systems read to ask "what is on this plate" without walking them.
@export var contained_ids: Array[String] = [] @export var contained_ids: Array[String] = []
@export var is_dirty: bool = false:
get:
return is_dirty
set(value):
if NetworkManager.owns_world():
clients_set_dirty.rpc(value)
is_dirty = value
container.enabled = not value
dirty_node.visible = value
SweetLogger.info("Set plate dirty: {0}", [value])
@rpc("authority", "call_remote", "reliable")
func clients_set_dirty(value: bool) -> void:
is_dirty = value
func get_food_items() -> Array[FoodItem]: func get_food_items() -> Array[FoodItem]:
return container.contained_items return container.contained_items
func _ready() -> void: func _ready() -> void:
if not dirty_node: Helper.check_reference(self, dirty_node, Node3D)
SweetLogger.warning("{0} missing dirty_node reference", [name])
dirty_node.visible = is_dirty
func _process(_delta: float) -> void:
if is_dirty:
container.enabled = false
dirty_node.visible = true
else:
container.enabled = true
dirty_node.visible = false
-2
View File
@@ -179,8 +179,6 @@ func apply_held_state() -> void:
and _pickable.collision_mask == 0 \ and _pickable.collision_mask == 0 \
and _pickable.enabled == want_enabled: and _pickable.enabled == want_enabled:
return return
if NetworkManager.is_online(): # This was spamming that Knife was frozen every frame.
SweetLogger.debug("{0}: freezing (non-authority, owner=peer {1})", [_pickable.name, net_held_by])
_pickable.freeze = true _pickable.freeze = true
_pickable.freeze_mode = RigidBody3D.FREEZE_MODE_KINEMATIC _pickable.freeze_mode = RigidBody3D.FREEZE_MODE_KINEMATIC
_pickable.collision_mask = 0 _pickable.collision_mask = 0
+2
View File
@@ -431,6 +431,8 @@ func request_join(ip: String) -> void:
pending_ip = ip pending_ip = ip
func consume_pending_session() -> void: func consume_pending_session() -> void:
if is_online():
return
if pending_action == "host": if pending_action == "host":
pending_action = "" pending_action = ""
host() host()
+3 -5
View File
@@ -14,14 +14,11 @@ var _food_item: FoodItem
func _ready() -> void: func _ready() -> void:
SweetLogger.debug("{0} ready", [_pickable.name]) SweetLogger.debug("{0} ready", [_pickable.name])
_food_item = get_parent().get_node_or_null("FoodItem") as FoodItem _food_item = get_parent().get_node_or_null("FoodItem") as FoodItem
if not _food_item:
SweetLogger.warning("{0} missing FoodItem reference, must be a sibling of a FoodItem", [get_parent().name])
if not _pickable: if not _pickable:
SweetLogger.error("{0} must be a grandchild of an XRToolsPickable", [get_parent().name]) SweetLogger.error("{0} must be a grandchild of an XRToolsPickable", [get_parent().name])
return return
if not _food_item: if not Helper.check_reference(get_parent(), _food_item, FoodItem):
SweetLogger.warning("{0} requires a FoodItem sibling", [_pickable.name])
return return
if not enabled: if not enabled:
return return
@@ -73,11 +70,12 @@ func _on_body_entered(body: Node3D) -> void:
# Instantiate the result of combination and free the two ingredient items # Instantiate the result of combination and free the two ingredient items
func _combine(other_body: Node3D, result: PackedScene) -> void: func _combine(other_body: Node3D, result: PackedScene) -> void:
SweetLogger.debug("Combining {0} + {1} into {2}", [_food_item.id, Helper.find_food_item(other_body).id, result.resource_path]) SweetLogger.info("Combining {0} + {1} into {2}", [_food_item.id, Helper.find_food_item(other_body).id, result.resource_path])
# Get Snapzone # Get Snapzone
var snap_zone := _pickable.get_picked_up_by() var snap_zone := _pickable.get_picked_up_by()
if not snap_zone or not snap_zone.has_method("pick_up_object"): if not snap_zone or not snap_zone.has_method("pick_up_object"):
SweetLogger.warning("{0}: combine triggered but base item is not in a snap zone, aborting", [_pickable.name])
return return
# Spawn the result through the server (so it replicates to every peer, # Spawn the result through the server (so it replicates to every peer,
+1 -2
View File
@@ -5,5 +5,4 @@ extends Node
@export var turns_into: PackedScene @export var turns_into: PackedScene
func _ready() -> void: func _ready() -> void:
if not turns_into: Helper.check_reference(self, turns_into, PackedScene)
SweetLogger.warning("{0} missing turns_into reference", [name])
+1 -3
View File
@@ -5,9 +5,7 @@ extends Node3D
func _ready() -> void: func _ready() -> void:
Helper.check_reference(self, kitchen_scene, PackedScene)
if not kitchen_scene:
SweetLogger.warning("{0} missing kitchen_scene reference", [name])
SweetLogger.debug("->[]") SweetLogger.debug("->[]")
+3 -3
View File
@@ -29,10 +29,10 @@ size = Vector3(16, 0.1, 16)
background_mode = 2 background_mode = 2
sky = ExtResource("5_kh26v") sky = ExtResource("5_kh26v")
reflected_light_source = 2 reflected_light_source = 2
ssr_enabled = true ssr_enabled = false
ssao_enabled = true ssao_enabled = true
ssil_enabled = true ssil_enabled = false
sdfgi_enabled = true sdfgi_enabled = false
[sub_resource type="BoxShape3D" id="BoxShape3D_24d3s"] [sub_resource type="BoxShape3D" id="BoxShape3D_24d3s"]
size = Vector3(16, 10, 0.1) size = Vector3(16, 10, 0.1)
+3 -3
View File
@@ -30,10 +30,10 @@ ambient_light_source = 3
ambient_light_color = Color(1, 1, 1, 1) ambient_light_color = Color(1, 1, 1, 1)
ambient_light_sky_contribution = 0.9 ambient_light_sky_contribution = 0.9
reflected_light_source = 2 reflected_light_source = 2
ssr_enabled = true ssr_enabled = false
ssao_enabled = true ssao_enabled = true
ssil_enabled = true ssil_enabled = false
sdfgi_enabled = true sdfgi_enabled = false
[sub_resource type="BoxShape3D" id="BoxShape3D_vlqg6"] [sub_resource type="BoxShape3D" id="BoxShape3D_vlqg6"]
size = Vector3(20, 0.1, 20) size = Vector3(20, 0.1, 20)
+18 -7
View File
@@ -9,18 +9,24 @@ var customers_served: int = 0
func _ready() -> void: func _ready() -> void:
GameManager.set_game_state(GameManager.GameState.BUILDING) if NetworkManager.owns_world():
GameManager.set_game_state(GameManager.GameState.BUILDING)
Signals.game_state_changed.connect(_on_game_state_changed) Signals.game_state_changed.connect(_on_game_state_changed)
Signals.table_satisfied.connect(_on_table_statisfied)
func _on_game_state_changed(new_state: GameManager.GameState) -> void: func _on_game_state_changed(new_state: GameManager.GameState) -> void:
if new_state == GameManager.GameState.RUNNING: if new_state == GameManager.GameState.RUNNING:
start_next_day() start_next_day()
func _on_table_statisfied(_table: Table) -> void:
customers_served += 1
SweetLogger.info("Spawned: {0} served: {1}, per_day: {2} time_remaining: {3}, progress: {4}", [customers_spawned, customers_served, GameManager.customers_per_day, snappedf(day_time_remaining, 0.1), snappedf(get_day_progression(), 0.1)])
# Returns 0-1 progress of the day time # Returns 0-1 progress of the day time
func get_day_progression() -> float: func get_day_progression() -> float:
return 1 - (day_time_remaining / GameManager.day_length_seconds) return clampf(1 - (day_time_remaining / GameManager.day_length_seconds), 0.0, 1.0)
func _reset_values() -> void: func _reset_values() -> void:
@@ -39,18 +45,23 @@ func start_next_day() -> void:
func finish_current_day() -> void: func finish_current_day() -> void:
SweetLogger.info("Finishing current day") SweetLogger.info("Finishing current day")
_reset_values() _reset_values()
GameManager.set_game_state(GameManager.GameState.BUILDING)
func _process(delta: float) -> void: func _process(delta: float) -> void:
if not NetworkManager.owns_world():
return
if GameManager.game_state != GameManager.GameState.RUNNING: if GameManager.game_state != GameManager.GameState.RUNNING:
return return
day_time_remaining -= delta if day_time_remaining > 0:
day_time_remaining -= delta
day_time_remaining = max(0, day_time_remaining)
var customers_at_this_time = GameManager.customers_per_day * get_day_progression() var customers_at_this_time = GameManager.customers_per_day * get_day_progression()
#print("DayController: customers_at_this_time: ", customers_at_this_time)
if customers_spawned < customers_at_this_time: if customers_spawned < customers_at_this_time:
customers_spawned += 1 customers_spawned += 1
SweetLogger.debug("Spawning customer") SweetLogger.info("Requesting to spawn customer")
Signals.request_customer_spawn.emit() Signals.request_customer_spawn.emit()
# If day complete # If day complete
if GameManager.customers_per_day == customers_served and customers_spawned == GameManager.customers_per_day: if GameManager.customers_per_day == customers_served and customers_spawned == GameManager.customers_per_day:
+3 -3
View File
@@ -18,10 +18,10 @@ size = Vector3(15, 0.1, 15)
background_mode = 2 background_mode = 2
sky = ExtResource("5_l1qm6") sky = ExtResource("5_l1qm6")
reflected_light_source = 2 reflected_light_source = 2
ssr_enabled = true ssr_enabled = false
ssao_enabled = true ssao_enabled = true
ssil_enabled = true ssil_enabled = false
sdfgi_enabled = true sdfgi_enabled = false
[node name="Main" type="Node3D" unique_id=1312265607] [node name="Main" type="Node3D" unique_id=1312265607]
script = ExtResource("1_jfr2g") script = ExtResource("1_jfr2g")
+3 -3
View File
@@ -24,10 +24,10 @@ size = Vector3(15, 0.1, 15)
background_mode = 2 background_mode = 2
sky = ExtResource("5_c3xgf") sky = ExtResource("5_c3xgf")
reflected_light_source = 2 reflected_light_source = 2
ssr_enabled = true ssr_enabled = false
ssao_enabled = true ssao_enabled = true
ssil_enabled = true ssil_enabled = false
sdfgi_enabled = true sdfgi_enabled = false
[sub_resource type="BoxShape3D" id="BoxShape3D_arao0"] [sub_resource type="BoxShape3D" id="BoxShape3D_arao0"]
size = Vector3(15, 20, 0.1) size = Vector3(15, 20, 0.1)
+19 -11
View File
@@ -6,10 +6,10 @@ extends Node3D
@export var progress_bar_3d: ProgressBar3D @export var progress_bar_3d: ProgressBar3D
@export var label_3d: Label3D @export var label_3d: Label3D
var _customers: Array[float] = [] # Temp. Array of their patience var _customers: Array[float] = [] # Temp. Array of their patience
var _tables: Array[Node3D] = [] var _tables: Array[Node3D] = []
func _ready() -> void: func _ready() -> void:
progress_bar_3d.override_fill_color(Color.YELLOW) progress_bar_3d.override_fill_color(Color.YELLOW)
progress_bar_3d.exponential = true progress_bar_3d.exponential = true
@@ -21,6 +21,7 @@ func _on_game_state_changed(new_state: GameManager.GameState) -> void:
if new_state == GameManager.GameState.RUNNING: if new_state == GameManager.GameState.RUNNING:
_rebuild_table_list() _rebuild_table_list()
func _on_request_customer_spawn() -> void: func _on_request_customer_spawn() -> void:
spawn_customer() spawn_customer()
@@ -44,20 +45,27 @@ func _try_to_assign_customers() -> void:
break break
func _update_clients_display() -> void:
if not _customers.is_empty():
everyone_set_queue_info.rpc("Customers in queue: " + str(_customers.size()), _customers.front() / queue_patience)
else:
everyone_set_queue_info.rpc("No Customers", 0)
@rpc("authority", "call_local", "unreliable")
func everyone_set_queue_info(label_text: String, progress: float) -> void:
label_3d.text = label_text
progress_bar_3d.set_progress(progress)
func _process(delta: float) -> void: func _process(delta: float) -> void:
if not NetworkManager.owns_world():
return
# Process customers patience # Process customers patience
for i in range(0, _customers.size()): for i in range(0, _customers.size()):
_customers[i] -= delta _customers[i] -= delta
if _customers[i] <= 0: if _customers[i] <= 0:
SweetLogger.info("Customer patience ran out, game over")
GameManager.game_over() GameManager.game_over()
_try_to_assign_customers() _try_to_assign_customers()
_update_clients_display()
# Update visuals
if not _customers.is_empty():
label_3d.text = "Customers in queue: " + str(_customers.size())
progress_bar_3d.set_progress(_customers.front() / queue_patience)
else:
progress_bar_3d.set_progress(0)
label_3d.text = "No Customers"
+3 -3
View File
@@ -24,10 +24,10 @@ ambient_light_source = 3
ambient_light_color = Color(1, 1, 1, 1) ambient_light_color = Color(1, 1, 1, 1)
ambient_light_sky_contribution = 0.9 ambient_light_sky_contribution = 0.9
reflected_light_source = 2 reflected_light_source = 2
ssr_enabled = true ssr_enabled = false
ssao_enabled = true ssao_enabled = true
ssil_enabled = true ssil_enabled = false
sdfgi_enabled = true sdfgi_enabled = false
[sub_resource type="BoxShape3D" id="BoxShape3D_vlqg6"] [sub_resource type="BoxShape3D" id="BoxShape3D_vlqg6"]
size = Vector3(20, 0.1, 20) size = Vector3(20, 0.1, 20)
+3 -6
View File
@@ -12,12 +12,9 @@ extends WorkStation
func _ready() -> void: func _ready() -> void:
super.ready() super.ready()
SweetLogger.debug("Counter {0} _ready", [name]) SweetLogger.debug("Counter {0} _ready", [name])
if not audio: Helper.check_reference(self, audio, AudioStreamPlayer3D)
SweetLogger.warning("{0} missing audio reference", [name]) Helper.check_reference(self, chop_audio, AudioStream)
if not chop_audio: Helper.check_reference(self, knife, XRToolsPickable)
SweetLogger.warning("{0} missing chop_audio reference", [name])
if not knife:
SweetLogger.warning("{0} missing knife reference", [name])
_disable_all_tools() _disable_all_tools()
+2 -3
View File
@@ -9,9 +9,8 @@ extends WorkStation
func _ready() -> void: func _ready() -> void:
super.ready() super.ready()
SweetLogger.debug("Hob {0} _ready", [name]) SweetLogger.debug("Hob {0} _ready", [name])
if not animation_player: Helper.check_reference(self, animation_player, AnimationPlayer)
SweetLogger.warning("{0} missing animation_player reference", [name])
func _start_cooking(id: String, work: float) -> void: func _start_cooking(id: String, work: float) -> void:
animation_player.play("hob") animation_player.play("hob")
if not enabled: if not enabled:
+1 -2
View File
@@ -7,8 +7,7 @@ extends Station
func _ready() -> void: func _ready() -> void:
super.ready() super.ready()
SweetLogger.debug("ItemDispenser {0} _ready", [name]) SweetLogger.debug("ItemDispenser {0} _ready", [name])
if not item_scene: Helper.check_reference(self, item_scene, PackedScene)
SweetLogger.warning("{0} missing item_scene reference", [name])
func _process(delta: float) -> void: func _process(delta: float) -> void:
+3 -6
View File
@@ -38,12 +38,9 @@ func _on_station_bought(_instance: Node3D):
func _ready() -> void: func _ready() -> void:
SweetLogger.debug("->[]") SweetLogger.debug("->[]")
if not station: Helper.check_reference(self, station, StaticBody3D)
SweetLogger.warning("{0} missing station reference", [name]) Helper.check_reference(self, move_handle, XRToolsPickable)
if not move_handle: Helper.check_reference(self, move_ghost, Area3D)
SweetLogger.warning("{0} missing move_handle reference", [name])
if not move_ghost:
SweetLogger.warning("{0} missing move_ghost reference", [name])
move_handle_rigid = move_handle as RigidBody3D move_handle_rigid = move_handle as RigidBody3D
original_collision_layer = station.collision_layer original_collision_layer = station.collision_layer
+12 -16
View File
@@ -147,24 +147,20 @@ func _enter_tree() -> void:
sync_config.add_property(property_path) sync_config.add_property(property_path)
sync_config.property_set_spawn(property_path, false) sync_config.property_set_spawn(property_path, false)
sync_config.property_set_replication_mode(property_path, SceneReplicationConfig.REPLICATION_MODE_ON_CHANGE) sync_config.property_set_replication_mode(property_path, SceneReplicationConfig.REPLICATION_MODE_ON_CHANGE)
SweetLogger.info("DEBUG sync_config properties: {0} | root_path: {1} | authority: {2} | peer: {3}", [sync_config.get_properties(), synchronizer.root_path, get_multiplayer_authority(), multiplayer.get_unique_id()]) # temp diagnostic SweetLogger.debug("sync_config properties: {0} | root_path: {1} | authority: {2} | peer: {3}", [sync_config.get_properties(), synchronizer.root_path, get_multiplayer_authority(), multiplayer.get_unique_id()])
func _ready() -> void: func _ready() -> void:
super.ready() super.ready()
if not label_3d: Helper.check_reference(self, label_3d, Label3D)
SweetLogger.warning("{0} missing label_3d reference", [name]) Helper.check_reference(self, label_3d_time, Label3D)
if not label_3d_time: Helper.check_reference(self, progress_bar, ProgressBar3D)
SweetLogger.warning("{0} missing label_3d_time reference", [name])
if not progress_bar or progress_bar is not ProgressBar3D:
SweetLogger.warning("{0} missing progress_bar reference", [name])
progress_bar.y_billboard = true progress_bar.y_billboard = true
progress_bar.exponential = true progress_bar.exponential = true
# Render whatever state already arrived from the server before we were in # Render whatever state already arrived from the server before we were in
# the tree (see the guard in _refresh_display). # the tree (see the guard in _refresh_display).
_refresh_display.call_deferred() _refresh_display.call_deferred()
if not audio_player: Helper.check_reference(self, audio_player, AudioStreamPlayer3D)
SweetLogger.warning("{0} missing audio_player reference", [name])
# Get snap_zones for plates, store in array snap_zones # Get snap_zones for plates, store in array snap_zones
for child in get_children(): for child in get_children():
@@ -200,10 +196,6 @@ func _on_object_dropped(_item) -> void:
_unsatisfied_orders.append(food_item.id) _unsatisfied_orders.append(food_item.id)
# original : burger cube, cube
# unsatisfied : burger cube
# table :
# There is no on_stay signal, we have to track player with bool # There is no on_stay signal, we have to track player with bool
func _on_player_enter(_body): func _on_player_enter(_body):
_players_count += 1 _players_count += 1
@@ -241,7 +233,6 @@ func _absorb_item_if_correct(_item: Node) -> void:
# Plate: Get plate controller in child of _item (hopefully a plate XRpickable) # Plate: Get plate controller in child of _item (hopefully a plate XRpickable)
var plate_controller = _get_plate_controller_from_item(_item) var plate_controller = _get_plate_controller_from_item(_item)
SweetLogger.debug("Plate_controller ref: {0}", [plate_controller]) SweetLogger.debug("Plate_controller ref: {0}", [plate_controller])
_item.print_tree_pretty()
if plate_controller: if plate_controller:
# Absorm items from the plate we want # Absorm items from the plate we want
@@ -359,8 +350,11 @@ func _state_end(oldState: TableState):
clearAllFood() clearAllFood()
_set_snap_zones_enabled(true) _set_snap_zones_enabled(true)
_set_state(TableState.EMPTY) _set_state(TableState.EMPTY)
SweetLogger.info("Table satisfied, emitting signal")
Signals.table_satisfied.emit(self)
TableState.ORDERING, TableState.WAITING_PRIMARY, TableState.WAITING_FRIEND: TableState.ORDERING, TableState.WAITING_PRIMARY, TableState.WAITING_FRIEND:
SweetLogger.info("{0}: order timed out in state {1}, game over", [name, TableState.keys()[oldState]])
label_3d.text = lbl_gameover label_3d.text = lbl_gameover
GameManager.game_over() GameManager.game_over()
@@ -373,8 +367,10 @@ func _refresh_display() -> void:
# tree — so these setters fire while the @onready children below are still # tree — so these setters fire while the @onready children below are still
# null. Bail out until _ready() has resolved them; _ready() calls back in # null. Bail out until _ready() has resolved them; _ready() calls back in
# once it has, so nothing that arrived early is lost. # once it has, so nothing that arrived early is lost.
if not progress_bar or not label_3d or not label_3d_time: var a := Helper.check_reference(self, progress_bar, ProgressBar3D)
SweetLogger.warning("{0} missing progress_bar or label reference", [name]) var b := Helper.check_reference(self, label_3d, Label3D)
var c := Helper.check_reference(self, label_3d_time, Label3D)
if not (a and b and c):
return return
match _state: match _state:
TableState.IDLE: TableState.IDLE:
+3 -2
View File
@@ -9,8 +9,9 @@ class_name ProgressBar3D
func _ready() -> void: func _ready() -> void:
if not progress_bar: Helper.check_reference(self, progress_bar, ProgressBar)
SweetLogger.warning("{0} missing progress_bar reference", [name]) # Rebind now that SubViewport is guaranteed live, avoiding a stale ViewportTexture.
sprite_3d.texture = sprite_3d.get_node(^"SubViewport").get_texture()
if y_billboard: if y_billboard:
$Sprite3D.billboard = BaseMaterial3D.BillboardMode.BILLBOARD_FIXED_Y $Sprite3D.billboard = BaseMaterial3D.BillboardMode.BILLBOARD_FIXED_Y
+1 -1
View File
@@ -21,7 +21,7 @@ func _process(_delta: float) -> void:
func _on_button_pressed() -> void: func _on_button_pressed() -> void:
SweetLogger.debug("Buy {0}", [station_name]) SweetLogger.info("Buy {0}", [station_name])
_buy_station() _buy_station()
+7 -11
View File
@@ -20,7 +20,7 @@ var sync_config: SceneReplicationConfig
var enabled: bool: # When disabled the station only updated display and sounds. var enabled: bool: # When disabled the station only updated display and sounds.
get: return snap_zone.enabled get: return snap_zone.enabled
set(p_enabled): set(p_enabled):
SweetLogger.info("Set enabled {0} on station {1} on client {2}", [p_enabled, name, multiplayer.get_unique_id()]) SweetLogger.debug("Set enabled {0} on station {1} on client {2}", [p_enabled, name, multiplayer.get_unique_id()])
snap_zone.enabled = p_enabled snap_zone.enabled = p_enabled
snap_zone.set_process(p_enabled) snap_zone.set_process(p_enabled)
@@ -39,14 +39,10 @@ func _enter_tree() -> void:
# The child station has to call super.ready() for this to be called # The child station has to call super.ready() for this to be called
func ready() -> void: func ready() -> void:
SweetLogger.debug("Station {0} ready", [name]) SweetLogger.debug("Station {0} ready", [name])
if not notification_audio: Helper.check_reference(self, notification_audio, AudioStreamPlayer3D)
SweetLogger.warning("{0} missing notification_audio reference", [name]) Helper.check_reference(self, ambient_audio, AudioStreamPlayer3D)
if not ambient_audio: Helper.check_reference(self, snap_zone, XRToolsSnapZone)
SweetLogger.warning("{0} missing ambient_audio reference", [name]) Helper.check_reference(self, synchronizer, MultiplayerSynchronizer)
if not snap_zone:
SweetLogger.warning("{0} missing snap_zone reference", [name])
if not synchronizer:
SweetLogger.warning("{0} missing synchronizer reference", [name])
# Disable if we're not the server. # Disable if we're not the server.
if not NetworkManager.owns_world(): if not NetworkManager.owns_world():
enabled = false enabled = false
@@ -75,7 +71,7 @@ func _on_object_dropped_handler(item: Node3D) -> void:
func _apply_object_picked_up(item: Node3D) -> void: func _apply_object_picked_up(item: Node3D) -> void:
SweetLogger.debug("Pickup: {0}", [item.name]) SweetLogger.info("{0}: Pickup: {1}", [name, item.name])
Helper.play_sound(notification_audio, pickup_sound) Helper.play_sound(notification_audio, pickup_sound)
on_object_picked_up(item) on_object_picked_up(item)
var food_item = Helper.find_food_item(item) var food_item = Helper.find_food_item(item)
@@ -85,7 +81,7 @@ func _apply_object_picked_up(item: Node3D) -> void:
func _apply_object_dropped(item: Node3D) -> void: func _apply_object_dropped(item: Node3D) -> void:
Helper.play_sound(notification_audio, drop_sound, 0.8) Helper.play_sound(notification_audio, drop_sound, 0.8)
SweetLogger.debug("Drop: {0}", [item.name]) SweetLogger.info("{0}: Drop: {1}", [name, item.name])
on_object_dropped(item) on_object_dropped(item)
var food_item = Helper.find_food_item(item) var food_item = Helper.find_food_item(item)
if food_item: if food_item:
+1 -2
View File
@@ -32,8 +32,7 @@ func _enter_tree() -> void:
# The child station has to call super.ready() for this to be called # The child station has to call super.ready() for this to be called
func ready() -> void: func ready() -> void:
super.ready() super.ready()
if not progress_bar: Helper.check_reference(self, progress_bar, ProgressBar3D)
SweetLogger.warning("{0} missing progress_bar reference", [name])
# The child station has to call super.process(delta) for this to be called # The child station has to call super.process(delta) for this to be called
@@ -1,4 +1,4 @@
[gd_scene load_steps=7 format=3 uid="uid://clujaf3u776a3"] [gd_scene load_steps=5 format=3 uid="uid://clujaf3u776a3"]
[ext_resource type="Script" uid="uid://eavk7267igp7" path="res://addons/godot-xr-tools/objects/viewport_2d_in_3d.gd" id="1"] [ext_resource type="Script" uid="uid://eavk7267igp7" path="res://addons/godot-xr-tools/objects/viewport_2d_in_3d.gd" id="1"]
[ext_resource type="Script" uid="uid://cpl5yiyf1ypft" path="res://addons/godot-xr-tools/objects/viewport_2d_in_3d_body.gd" id="2"] [ext_resource type="Script" uid="uid://cpl5yiyf1ypft" path="res://addons/godot-xr-tools/objects/viewport_2d_in_3d_body.gd" id="2"]
@@ -7,14 +7,6 @@
resource_local_to_scene = true resource_local_to_scene = true
size = Vector2(3, 2) size = Vector2(3, 2)
[sub_resource type="ViewportTexture" id="ViewportTexture_ufe4n"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_fvml0"]
transparency = 1
cull_mode = 2
albedo_texture = SubResource("ViewportTexture_ufe4n")
texture_filter = 1
[sub_resource type="BoxShape3D" id="4"] [sub_resource type="BoxShape3D" id="4"]
resource_local_to_scene = true resource_local_to_scene = true
size = Vector3(3, 2, 0.02) size = Vector3(3, 2, 0.02)
@@ -34,7 +26,6 @@ render_target_update_mode = 1
[node name="Screen" type="MeshInstance3D" parent="."] [node name="Screen" type="MeshInstance3D" parent="."]
mesh = SubResource("1") mesh = SubResource("1")
surface_material_override/0 = SubResource("StandardMaterial3D_fvml0")
[node name="StaticBody3D" type="StaticBody3D" parent="."] [node name="StaticBody3D" type="StaticBody3D" parent="."]
collision_layer = 5242881 collision_layer = 5242881
+2 -2
View File
@@ -1,6 +1,6 @@
extends Node extends Node
const enable_debug = true const enable_debug = false
var frame_count = 0 var frame_count = 0
# Inside SweetLogger or a static helper class: # Inside SweetLogger or a static helper class:
static func get_current_function_name() -> String: static func get_current_function_name() -> String:
@@ -98,7 +98,7 @@ const TIMESTAMP_BG_COLOR = "#1e3a5f"
#===================================================================================# #===================================================================================#
## Column widths for alignment (in characters) ## Column widths for alignment (in characters)
const PEER_ID_COLUMN_WIDTH = 6 const PEER_ID_COLUMN_WIDTH = 6
const LOG_TYPE_COLUMN_WIDTH = 12 const LOG_TYPE_COLUMN_WIDTH = 13
## Default mm:ss:ms; with SHOW_TIMESTAMP_HOURS, hh:mm:ss:ms ## Default mm:ss:ms; with SHOW_TIMESTAMP_HOURS, hh:mm:ss:ms
const TIMESTAMP_COLUMN_WIDTH_MMSSMS = 9 const TIMESTAMP_COLUMN_WIDTH_MMSSMS = 9
const TIMESTAMP_COLUMN_WIDTH_HHMMSSMS = 12 const TIMESTAMP_COLUMN_WIDTH_HHMMSSMS = 12
Binary file not shown.
+4
View File
@@ -19,6 +19,10 @@
- Freshness - Freshness
- Fullbody tracking (Height calibration) - Fullbody tracking (Height calibration)
### Bugs
- Plate not locked on clinets by table
- Rare times, plate not cleared / has buger on it after table eaten. New customer didn't accept it, so must have been empty, but server and client visuals had burger on plate.
- Table does not accept clinet that was already in player detect zone
### Station inheritence suggestion ### Station inheritence suggestion
Station Station
+19
View File
@@ -19,3 +19,22 @@ Add (what) to singal dropped in snap_zone
picked_up_object.let_go(self, Vector3.ZERO, Vector3.ZERO) picked_up_object.let_go(self, Vector3.ZERO, Vector3.ZERO)
picked_up_object = null picked_up_object = null
highlight_updated.emit(self, enabled) highlight_updated.emit(self, enabled)
viewport_2d_in_3d.tscn:
Removed the baked ViewportTexture sub-resource (no viewport_path set, genuinely
invalid) that was the default material on the Screen mesh. The script always
builds and swaps in its own material at _ready(), so the baked one only
existed to be briefly invalid before being discarded, printing a spurious
"Viewport Texture must be set to use it" error on every instance (MainMenuPanel3D
at boot, the player's shop_menu_3d on avatar spawn).
Removed:
[sub_resource type="ViewportTexture" id="ViewportTexture_ufe4n"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_fvml0"]
transparency = 1
cull_mode = 2
albedo_texture = SubResource("ViewportTexture_ufe4n")
texture_filter = 1
And the reference to it on the Screen node:
surface_material_override/0 = SubResource("StandardMaterial3D_fvml0")
+2 -2
View File
@@ -21,7 +21,7 @@ func server_set_money(value: int) -> void: set_money(value)
func client_sync_money(value: int) -> void: money = value func client_sync_money(value: int) -> void: money = value
var day_number: int = 1: var day_number: int = 0:
get: get:
return day_number return day_number
@@ -110,7 +110,7 @@ func client_sync_day_length_seconds(value: float) -> void:
day_length_seconds = value day_length_seconds = value
var customers_per_day: float = 5.0: var customers_per_day: float = 3.0:
get: get:
return customers_per_day return customers_per_day
+22 -16
View File
@@ -20,22 +20,28 @@ static func load_recipes() -> void:
return return
var yaml_available := ClassDB.class_exists("YAML") var yaml_available := ClassDB.class_exists("YAML")
if yaml_available: if not yaml_available:
var result = ClassDB.class_call_static("YAML", "load_file", recipe_path) SweetLogger.error("YAML addon is not available, recipes.yaml can not be loaded")
if result != null and not result.has_error(): return
var data = result.get_data()
if typeof(data) != TYPE_DICTIONARY: var result = ClassDB.class_call_static("YAML", "load_file", recipe_path)
SweetLogger.warning("YAML addon parsed recipes.yaml but returned an unsupported structure") if result == null or result.has_error():
SweetLogger.error("Failed to parse recipes.yaml: {0}", [result.get_error_message() if result else "null result"])
_recipes = data return
_build_scene_paths()
_build_combining_map() var data = result.get_data()
_build_cooking_map() if typeof(data) != TYPE_DICTIONARY:
_build_chopping_map() SweetLogger.warning("YAML addon parsed recipes.yaml but returned an unsupported structure")
_build_rolling_map()
_build_augmenting_map() _recipes = data
_loaded = true _build_scene_paths()
_build_combining_map()
_build_cooking_map()
_build_chopping_map()
_build_rolling_map()
_build_augmenting_map()
_loaded = true
#print_all_recipes()
static func get_combination_result(first_id: StringName, second_id: StringName) -> PackedScene: static func get_combination_result(first_id: StringName, second_id: StringName) -> PackedScene:
load_recipes() load_recipes()
+6 -11
View File
@@ -1,12 +1,7 @@
extends Node extends Node
@warning_ignore("unused_signal") signal game_over
@warning_ignore("unused_signal") @warning_ignore("unused_signal") signal restart_game
signal game_over @warning_ignore("unused_signal") signal game_state_changed(new_state: GameManager.GameState)
@warning_ignore("unused_signal") @warning_ignore("unused_signal") signal station_bought(instance: Node3D)
signal restart_game @warning_ignore("unused_signal") signal request_customer_spawn()
@warning_ignore("unused_signal") @warning_ignore("unused_signal") signal table_satisfied(table: Table)
signal game_state_changed(new_state: GameManager.GameState)
@warning_ignore("unused_signal")
signal station_bought(instance: Node3D)
@warning_ignore("unused_signal")
signal request_customer_spawn()
+10 -10
View File
@@ -1,20 +1,20 @@
extends Node extends Node
## Nudge down from the screen top so the window's title bar/menu stays visible.
const SERVER_Y_OFFSET := 45
func _ready() -> void: func _ready() -> void:
if OS.has_feature("editor"): # Only the (non-VR) server window needs positioning; the VR instance's
# Force subwindows to be native OS windows instead of embedded viewports # window is left wherever the OS/editor puts it.
if OS.has_feature("editor") and OS.get_cmdline_args().has("--server"):
get_tree().root.gui_embed_subwindows = false get_tree().root.gui_embed_subwindows = false
get_tree().create_timer(0.05).timeout.connect(_position_window) get_tree().create_timer(0.05).timeout.connect(_position_window)
func _position_window() -> void: func _position_window() -> void:
var is_server: bool = OS.get_cmdline_args().has("--server")
var screen_rect: Rect2i = DisplayServer.screen_get_usable_rect(DisplayServer.window_get_current_screen()) var screen_rect: Rect2i = DisplayServer.screen_get_usable_rect(DisplayServer.window_get_current_screen())
@warning_ignore("integer_division") @warning_ignore("integer_division")
var window_width: int = screen_rect.size.x / 2 var window_width: int = screen_rect.size.x / 2
var window_height: int = int(screen_rect.size.y * (2.0 / 3.0)) var x_pos: int = screen_rect.position.x + window_width
var y_pos: int = screen_rect.position.y + SERVER_Y_OFFSET
DisplayServer.window_set_size(Vector2i(window_width - 10, window_height)) DisplayServer.window_set_position(Vector2i(x_pos, y_pos))
if is_server:
var x_pos: int = screen_rect.position.x + window_width
DisplayServer.window_set_position(Vector2i(x_pos, screen_rect.position.y))
+3 -1
View File
@@ -15,13 +15,15 @@ func _unhandled_input(event: InputEvent) -> void:
# Kill all clients # Kill all clients
@rpc("any_peer", "call_local", "reliable") @rpc("any_peer", "call_local", "reliable")
func all_quit_game(): func all_quit_game():
SweetLogger.info("Quit game requested, killing all clients")
get_tree().quit() get_tree().quit()
# Finds any node of class/type Table and calls satisfyAllOrders() # Finds any node of class/type Table and calls satisfyAllOrders()
func satisfy_table_orders() -> void: func satisfy_table_orders() -> void:
SweetLogger.info("Debug: satisfying all table orders")
# Searches all nodes in the current running scene matching the class "Table" # Searches all nodes in the current running scene matching the class "Table"
var table_nodes = get_tree().root.find_children("*", "Table", true, false) var table_nodes = get_tree().root.find_children("*", "Table", true, false)
for node in table_nodes: for node in table_nodes:
if node.has_method("satisfyAllOrders"): if node.has_method("satisfyAllOrders"):
node.satisfyAllOrders() node.satisfyAllOrders()
+16
View File
@@ -72,6 +72,22 @@ static func get_node_from_path(from: Node, node_path: NodePath) -> Node3D:
static func check_reference(node: Node, ref: Variant, type: Variant) -> bool:
if is_instance_valid(ref) and is_instance_of(ref, type):
return true
var type_name: String
if type is Script:
type_name = type.get_global_name()
else:
var probe: Object = type.new()
type_name = probe.get_class()
if not (probe is RefCounted):
probe.free()
SweetLogger.warning("{0} missing reference {1} ({2})", [node.name, type_name, _get_caller_label()])
return false
static func play_sound(player: AudioStreamPlayer3D, stream: AudioStream, pitch_scale: float = 1): static func play_sound(player: AudioStreamPlayer3D, stream: AudioStream, pitch_scale: float = 1):
if not player: if not player:
SweetLogger.warning("{0}: AudioStreamPlayer3D is null, can not play sound", [_get_caller_label()]) SweetLogger.warning("{0}: AudioStreamPlayer3D is null, can not play sound", [_get_caller_label()])
-1
View File
@@ -1 +0,0 @@
uid://be8o8m6xpp3kc
+3 -3
View File
@@ -24,10 +24,10 @@ size = Vector3(15, 0.1, 15)
background_mode = 2 background_mode = 2
sky = ExtResource("4_081u3") sky = ExtResource("4_081u3")
reflected_light_source = 2 reflected_light_source = 2
ssr_enabled = true ssr_enabled = false
ssao_enabled = true ssao_enabled = true
ssil_enabled = true ssil_enabled = false
sdfgi_enabled = true sdfgi_enabled = false
[sub_resource type="BoxShape3D" id="BoxShape3D_arao0"] [sub_resource type="BoxShape3D" id="BoxShape3D_arao0"]
size = Vector3(15, 20, 0.1) size = Vector3(15, 20, 0.1)
+1 -1
View File
@@ -12,7 +12,7 @@ var _camera: Camera3D
func _ready() -> void: func _ready() -> void:
var xr_interface := XRServer.find_interface("OpenXR") var xr_interface := XRServer.find_interface("OpenXR")
if xr_interface and xr_interface.is_initialized(): if xr_interface and xr_interface.is_initialized():
SweetLogger.warning("{0} disabled - this instance is the VR client", [name]) SweetLogger.debug("{0} disabled - this instance is the VR client", [name])
return return
if not _players: if not _players:
SweetLogger.warning("{0} could not resolve players_path {1}", [name, players_path]) SweetLogger.warning("{0} could not resolve players_path {1}", [name, players_path])