I have RemoteEvents that fire from the client to the server as quickly as possible, but there is always a delay, therefore causing some errors. My goal is to create a smooth seamless environment, but this cannot be done because of the latency between clients and servers. Is there any way to smoothly replicate something as if there were no delay between the client and the server? If not, how would one go about making a pseudo-environment such as doing something client side while waiting for the server?
Here is some code just in case that is an issue:
Server:
coroutine.resume(coroutine.create(function() GenerateBlocks.OnServerEvent:Connect(function(player, targetSelection) if targetSelection ~= nil and targetSelection.Parent == Mine then local TargetPos = targetSelection.PrimaryPart.CFrame Instance.new("Folder",BlockData).Name = tostring(TargetPos) coroutine.resume(coroutine.create(function() createNewBlock(ChooseBlock(player, TargetPos.y):Clone(),CFrame.new(TargetPos.x,TargetPos.y-8,TargetPos.z)) --Bottom createNewBlock(ChooseBlock(player, TargetPos.y):Clone(),CFrame.new(TargetPos.x,TargetPos.y,TargetPos.z+8)) --Right createNewBlock(ChooseBlock(player, TargetPos.y):Clone(),CFrame.new(TargetPos.x,TargetPos.y,TargetPos.z-8)) --Left createNewBlock(ChooseBlock(player, TargetPos.y):Clone(),CFrame.new(TargetPos.x+8,TargetPos.y,TargetPos.z)) --Forward createNewBlock(ChooseBlock(player, TargetPos.y):Clone(),CFrame.new(TargetPos.x-8,TargetPos.y,TargetPos.z)) --Backward createNewBlock(ChooseBlock(player, TargetPos.y):Clone(),CFrame.new(TargetPos.x,TargetPos.y+8,TargetPos.z)) --Top end)) end end) end)) coroutine.resume(coroutine.create(function() DestroyBlock.OnServerEvent:Connect(function(player, targetSelection) if targetSelection ~= nil then targetSelection:Destroy() local Inv = game:GetService("ServerStorage").PlayerStats[player.Name].Inventory for _, InvItem in pairs (Inv:GetChildren()) do if InvItem:IsA("IntValue") then if InvItem.Name == targetSelection.Name and targetSelection.Name ~= "Soil" then InvItem.Value = InvItem.Value + 1 end end end end end) end))
Local Script:
function Mine(Target) if mouseDown and not CurrentMining then CurrentSelection = Target if CurrentSelection ~= nil and CurrentSelection:IsA("MeshPart") then CurrentSelection = CurrentSelection.Parent.PrimaryPart end if CurrentSelection ~= nil and CurrentSelection:IsDescendantOf(workspace.Mine) and CurrentSelection:IsA("BasePart") or CurrentSelection:IsA("MeshPart") and CurrentSelection.Parent:IsA("Model") then GenerateBlocks:FireServer(CurrentSelection.Parent) -- Generates surrounding blocks beforehand. while CurrentSelection ~= nil do CurrentMining = true ProgressBar:TweenSize(UDim2.new(0.96,0,0.7,0), Enum.EasingDirection.InOut, Enum.EasingStyle.Linear, mineTime, false, callMine) break -- so that it only runs 1 time, so long as the CurrentSelection exists. end end end end function callMine() if equipped then ProgressBar:TweenSize(UDim2.new(0,0,0.7,0), Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, 0, true) CurrentMining = false if CurrentSelection ~= nil and mouseDown then DestroyBlock:FireServer(CurrentSelection.Parent) end end end
In the while loop, as I have said to you before, use a wait. After the "while do" loop add a "wait()".