This commit is contained in:
2026-01-15 09:07:56 +08:00
parent bee9c30f0e
commit 5a97f7959e
4 changed files with 77 additions and 7 deletions
+16
View File
@@ -0,0 +1,16 @@
[ ADT's Report ]
Updated the `tekton-enet` ( Armageddon Multiplayer ) on branch `launcher`
**Gameplay & Level Design**
**Smart Tile Randomization** - Implemented advanced shuffling for game board.
* **Logic**: Instead of random noise, Floor 1 (Item Layer) now performs a "Shuffle" operation on game start.
* **Benefit**: Preserves the exact count and type of special tiles (Hearts, Diamonds, Shield, etc.) designed in the editor, while randomizing their locations for fresh gameplay every match.
* **Safety**: Floor 0 (Ground/Path) remains untouched to ensure map navigability.
**Network & Desync Fixes**
**Idle Position Correction** - Eliminated client-side drift when idle.
* **Fix**: Modified `player.gd` to disable network interpolation while local movement animations (Tweens) are active, preventing "fight-for-control" jitter.
* **Improvement**: Added force-snapping to the exact grid center when movement finishes to correct any floating-point drift from unreliable network packets.
+47 -3
View File
@@ -9,6 +9,7 @@ signal grid_updated
@export var rows: int = 10: set = set_rows @export var rows: int = 10: set = set_rows
@export var floors: int = 3: set = set_floors @export var floors: int = 3: set = set_floors
@export var auto_generate: bool = false: set = set_auto_generate @export var auto_generate: bool = false: set = set_auto_generate
@export var auto_randomize: bool = false # If true, randomizes grid on start
@export var normal_items: Array[int] = [0] @export var normal_items: Array[int] = [0]
@export var non_walkable_items: Array[int] = [4] @export var non_walkable_items: Array[int] = [4]
@@ -46,8 +47,11 @@ class NeighborInfo:
func _ready(): func _ready():
mesh_library_changed.connect(_on_mesh_library_changed) mesh_library_changed.connect(_on_mesh_library_changed)
if not Engine.is_editor_hint() and auto_generate: if not Engine.is_editor_hint():
if auto_generate:
generate_grid() generate_grid()
if auto_randomize:
randomize_grid()
validate_item_indices() validate_item_indices()
# Core grid management functions # Core grid management functions
@@ -173,8 +177,10 @@ func fill_floor(item_index: int, floor_index: int):
# Randomization functions # Randomization functions
func randomize_grid(floor_index: int = -1): func randomize_grid(floor_index: int = -1):
if floor_index == -1: if floor_index == -1:
for y in range(floors): # Default auto-randomize behavior:
randomize_floor(y) # Preserve Floor 0 (Ground)
# Shuffle Floor 1 (Objects/Items)
shuffle_floor_objects(1)
else: else:
randomize_floor(floor_index) randomize_floor(floor_index)
@@ -259,6 +265,44 @@ func randomize_floor_custom(randomize_states: Array, floor_index: int):
set_cell_item(cell_pos, normal_items[0], current_orientation) set_cell_item(cell_pos, normal_items[0], current_orientation)
func shuffle_floor_objects(floor_idx: int):
if not mesh_library:
print("Error: No MeshLibrary assigned to GridMap")
return
# 1. Collect all existing items and their positions on this floor
var positions: Array[Vector3i] = []
var items: Array[int] = []
for x in range(columns):
for z in range(rows):
var cell_pos = Vector3i(x, floor_idx, z)
var item = get_cell_item(cell_pos)
if item != -1:
positions.append(cell_pos)
items.append(item)
if positions.is_empty():
return
# 2. Shuffle the items list
var rng = RandomNumberGenerator.new()
rng.randomize()
items.shuffle()
# 3. Reassign items to the existing positions
# This preserves the location of "something exists here" (layout)
# but randomizes "what exists here" (type)
for i in range(positions.size()):
var pos = positions[i]
var new_item = items[i]
var orientation = get_cell_item_orientation(pos) # Keep orientation? Or reset? Keeping seems safer.
set_cell_item(pos, new_item, orientation)
print("Shuffled %d items on Floor %d" % [items.size(), floor_idx])
#func get_neighbors(current_pos: Vector2i, floor_index: int) -> Array[NeighborInfo]: #func get_neighbors(current_pos: Vector2i, floor_index: int) -> Array[NeighborInfo]:
#var neighbors: Array[NeighborInfo] = [] #var neighbors: Array[NeighborInfo] = []
# #
+1
View File
@@ -61,6 +61,7 @@ script = ExtResource("2_hbe1v")
columns = 14 columns = 14
rows = 14 rows = 14
floors = 2 floors = 2
auto_randomize = true
metadata/_editor_floor_ = Vector3(0, 1, 0) metadata/_editor_floor_ = Vector3(0, 1, 0)
[node name="Camera3D" type="Camera3D" parent="."] [node name="Camera3D" type="Camera3D" parent="."]
+10 -1
View File
@@ -616,8 +616,13 @@ func _process(delta):
rpc("ping_existence") rpc("ping_existence")
else: else:
# Client-side visual smoothing # Client-side visual smoothing
# Only interpolate if NOT running a movement tween, OR if the drift is large (teleport/snap)
if not is_player_moving:
# Snap to target if very close (prevents micro-jitter)
if global_position.distance_squared_to(target_visual_position) < 0.001:
global_position = target_visual_position
else:
# Interpolate towards the target position received from authority # Interpolate towards the target position received from authority
if global_position.distance_squared_to(target_visual_position) > 0.001:
global_position = global_position.lerp(target_visual_position, delta * 15.0) global_position = global_position.lerp(target_visual_position, delta * 15.0)
# Delegate rotation to movement manager # Delegate rotation to movement manager
@@ -841,6 +846,10 @@ func start_movement_along_path(path: Array, clear_visual: bool = true):
is_player_moving = false is_player_moving = false
target_position = Vector2i(-1, -1) target_position = Vector2i(-1, -1)
# FORCE SNAP: Update target visual position to the perfect grid center
# This ensures that when interpolation resumes (in _process), it pulls to the correct spot
target_visual_position = grid_to_world(current_position)
# Check if we've reached the finish line (uses lap-aware finish locations) # Check if we've reached the finish line (uses lap-aware finish locations)
var current_finish_locs = race_manager.get_current_finish_locations() if race_manager else finish_locations var current_finish_locs = race_manager.get_current_finish_locations() if race_manager else finish_locations
if current_position in current_finish_locs and can_finish: if current_position in current_finish_locs and can_finish: