Minecraft-like Roblox block game rblx.games/135624152691584
roblox roblox-game rojo

placement: handle existing block edge case

+13 -5
+12 -4
src/ReplicatedStorage/Shared/PlacementManager.lua
··· 31 31 local lastRaycastFailure: string? = nil 32 32 local lastSelectedChunkKey: string? = nil 33 33 local lastSelectedBlockKey: string? = nil 34 + local duplicateResyncCooldown: {[string]: number} = {} 34 35 local BREAK_ROLLBACK_TIMEOUT = 0.6 35 36 local pendingBreaks = {} 36 37 local clearSelection ··· 426 427 return 427 428 end 428 429 429 - -- if the client already thinks this block is the same id, skip sending 430 + -- allow sending even if the client thinks the id matches; server truth wins 430 431 if chunk then 431 432 local existing = chunk:GetBlockAt(x, y, z) 432 433 local existingId = existing and existing.id 433 434 if existingId and tostring(existingId) == tostring(blockId) then 434 435 debugPlacementLog( 435 - "[PLACE][CLIENT][SKIP]", 436 - "duplicate id", 436 + "[PLACE][CLIENT][DUPLICATE]", 437 + "still sending", 437 438 "chunk", 438 439 cx, 439 440 cy, ··· 447 448 "blockId", 448 449 blockId 449 450 ) 450 - return 451 + local ck = makeChunkKey(cx, cy, cz) 452 + local last = duplicateResyncCooldown[ck] 453 + if not last or (tick() - last) > 0.5 then 454 + duplicateResyncCooldown[ck] = tick() 455 + task.defer(function() 456 + ChunkManager:RefreshChunk(cx, cy, cz) 457 + end) 458 + end 451 459 else 452 460 debugPlacementLog( 453 461 "[PLACE][CLIENT][EXISTING]",
+1 -1
src/ServerScriptService/Actor/ServerChunkManager/init.server.lua
··· 138 138 return false 139 139 end 140 140 141 - local DEBUG_PLACEMENT = true 141 + local DEBUG_PLACEMENT = false 142 142 local function debugPlacementLog(...: any) 143 143 if DEBUG_PLACEMENT then 144 144 Util.StudioLog(...)