feat: Add initial gridmap mesh library, main game script, and Nakama manager.

This commit is contained in:
Yogi Wiguna
2026-02-10 17:44:07 +08:00
parent 0c2a53c0cc
commit 903619a396
3 changed files with 17 additions and 99 deletions
+1 -91
View File
@@ -12,7 +12,6 @@ var touch_controls
# Minimal local state
var _connection_check_timer: float = 0.0
var tile_respawn_timers = {} # Tracks removed tiles: {Vector2i(x,z): respawn_time_msec}
func _ready():
# Initialize scene managers
@@ -49,16 +48,7 @@ func _ready():
# Ensure grid is randomized with Scarcity if server
if multiplayer.is_server():
randomize_game_grid()
_setup_tile_respawn_timer()
# Targeted 5s Respawn Timer for empty spots
var respawn_check_timer = Timer.new()
respawn_check_timer.name = "RespawnCheckTimer"
respawn_check_timer.wait_time = 0.5
respawn_check_timer.autostart = true
respawn_check_timer.timeout.connect(_check_respawns)
add_child(respawn_check_timer)
# Force gridmap cell size to match player logic (1, 0.05, 1) - >0.001 to avoid errors
var em = $EnhancedGridMap
if em:
@@ -69,56 +59,6 @@ func _on_goal_count_updated(peer_id: int, count: int):
if peer_id == multiplayer.get_unique_id():
ui_manager.update_goal_count_label(count)
func _setup_tile_respawn_timer():
# Configure respawn rate based on Scarcity Mode from Lobby
var mode = LobbyManager.get_scarcity_mode()
var interval = 0.0
match mode:
"Aggressive": interval = 5.0
"Chaos": interval = 1.0 # Very fast!
"Normal": interval = 0.0 # No periodic respawn (only refill when empty)
_: interval = 0.0
if interval > 0:
var timer = Timer.new()
timer.name = "TileRespawnTimer"
timer.wait_time = interval
timer.autostart = true
timer.one_shot = false
timer.timeout.connect(_on_tile_respawn_timeout)
add_child(timer)
print("[Main] TileRespawnTimer started with interval: %.1f (Mode: %s)" % [interval, mode])
func _on_tile_respawn_timeout():
if not multiplayer.is_server(): return
var enhanced_gridmap = $EnhancedGridMap
if not enhanced_gridmap: return
# Try to find an empty spot (max 10 retries)
for i in range(10):
var x = randi() % enhanced_gridmap.columns
var z = randi() % enhanced_gridmap.rows
var cell = Vector3i(x, 1, z)
if enhanced_gridmap.get_cell_item(cell) == -1:
# Check floor 0
if enhanced_gridmap.get_cell_item(Vector3i(x, 0, z)) != -1:
# Check player occupancy
var occupied = false
for player in get_tree().get_nodes_in_group("Players"):
if Vector2i(player.current_position.x, player.current_position.y) == Vector2i(x, z):
occupied = true
break
if not occupied:
# Spawn!
var new_item = ScarcityController.get_random_tile_id()
sync_grid_item(x, 1, z, new_item)
rpc("sync_grid_item", x, 1, z, new_item)
return # Spawned one, done for this tick
func _init_managers():
# Create and attach scene managers
ui_manager = load("res://scripts/managers/ui_manager.gd").new()
@@ -1144,42 +1084,12 @@ func request_randomize_item(grid_position: Vector2i):
if multiplayer.is_server():
randomize_item_at_position(grid_position)
func _check_respawns():
"""Check tile respawn timers and spawn items if ready."""
if not multiplayer.is_server():
return
var current_time = Time.get_ticks_msec()
var tiles_to_respawn = []
for pos in tile_respawn_timers.keys():
if current_time >= tile_respawn_timers[pos]:
tiles_to_respawn.append(pos)
for pos in tiles_to_respawn:
print("[Main] Respawning tile at ", pos)
randomize_item_at_position(pos)
tile_respawn_timers.erase(pos)
@rpc("any_peer", "call_local", "reliable")
func sync_grid_item(x: int, y: int, z: int, item: int):
var enhanced_gridmap = $EnhancedGridMap
if enhanced_gridmap:
enhanced_gridmap.set_cell_item(Vector3i(x, y, z), item)
# Server logic for respawns
if multiplayer.is_server() and y == 1:
var pos = Vector2i(x, z)
if item == -1:
# Item removed - schedule respawn 5s later
tile_respawn_timers[pos] = Time.get_ticks_msec() + 10000
print("[Main] Scheduled respawn for tile at %s in 10s" % pos)
else:
# Item placed - cancel pending respawn
if tile_respawn_timers.has(pos):
tile_respawn_timers.erase(pos)
print("[Main] Cancelled respawn for tile at %s (occupied)" % pos)
# Sync grid update (no need to sync whole grid if we do it at start, but if we do it late we might need to sync)
# For simplicity, we trust the grid syncs via normal mechanisms or initial state.