So I was trying to improve my placement script, now to let it place with the server, this wasn't very easy lol. It works... but there is one thing that makes me a bit frustrated, when you place something it really lags, this isn't something that breaks the script but it's really really hard lag... It dissapears when the placement finished. The scripts are in the tool

Here is the local script that sends mouse data to the srever script

local AMPevent = game:GetService('ReplicatedStorage'):WaitForChild('AskMousePos')
local player = game.Players.LocalPlayer

local mouse = player:GetMouse()
local MouseClickEvent = game:GetService('ReplicatedStorage'):WaitForChild('MouseClick')

button = 1
buttonDebounce = true

function AMPevent.OnClientInvoke()
	
	local mousePos = mouse.Hit.p
	
	return mousePos
end

mouse.Button1Down:connect(function()
	if buttonDebounce then
		buttonDebounce = false
		print('fired')
		button = 1
		MouseClickEvent:FireServer(button)
		wait(1)
		buttonDebounce = true
	end
end)
mouse.Button2Down:connect(function()
	if buttonDebounce then
		print('fired')
		button = 2
		MouseClickEvent:FireServer(button)
		buttonDebounce = true
	end
end)

This is a server script inside the tool (the local script is also in the tool)

local AMPevent = game:GetService('ReplicatedStorage'):WaitForChild('AskMousePos')
local MouseClickEvent = game:GetService('ReplicatedStorage'):WaitForChild('MouseClick')

local plr = script.Parent.Parent.Parent
print(plr.Name)

local tool = script.Parent
local player = game:GetService("Players").LocalPlayer
Debounce = false
pressed = false
cancelled = false
canPress = false
 
tool.Equipped:connect(function()
	print("Tool equipped!")
 
	MouseClickEvent.OnServerEvent:connect(function(plr, button)
		print('client event')
		pos = AMPevent:InvokeClient(plr)
		
		print("Mouse pressed!")
		
		if Debounce == false and button == 1 then
				
			Debounce = true		
			
			local ray = Ray.new(tool.Handle.CFrame.p, (pos - tool.Handle.CFrame.p).unit * 30)
			local part, position = workspace:FindPartOnRay(ray, player.Character, false, true)
		
			PreviewPart = script.Parent.Wooden_Floor:Clone()
			PreviewPart.Name = "Preview part"
			PreviewPart.Transparency = 0.5
			PreviewPart.Anchored = true
			PreviewPart.CanCollide = false
			PreviewPart.Position = position + Vector3.new(0, 0.375, 0)--  + Vector3.new(0,part.Size.Y/2,0)
			PreviewPart.Parent = workspace
			
			customBuild = Instance.new("Part")
			customBuild.Transparency = 1
			customBuild.Anchored = true
			customBuild.CanCollide = false
			customBuild.Name = "CustomBuild"
			customBuild.Parent = PreviewPart
		
			wait(1)
			
			canPress = true	
		end
	end)
end)

while wait() do
	pos = AMPevent:InvokeClient(plr)
	if Debounce == true then
			 MouseClickEvent.OnServerEvent:connect(function(plr, button)
				print(tostring(button),tostring(canPress))
				if canPress == true and button == 1 then
					print('placed')
					pressed = true
				elseif button == 2 then
					print('cancelled')
					cancelled = true
				else
					warn('eror')
				end
			end)
			
		if cancelled == true then
			Debounce = false
			cancelled = false
			pressed = false
			canPress = false
			for i,v in pairs(workspace:GetChildren()) do
				if v.Name == "Preview part" then
					v:Destroy()
				end
			end
			print(cancelled)
		elseif pressed == true then
			Debounce = false
			cancelled = false
			pressed = false
			canPress = false
			for i,v in pairs(workspace:GetChildren()) do
				if v.Name == "Preview part" then
					v.Transparency = 0
					v.Name = "Floor"
					v.CanCollide = true
				end
			end
		end
		if PreviewPart ~= nil then
			local list = {player.Character,PreviewPart}
			local Player = game.Players:GetPlayers()
			local ray = Ray.new(tool.Handle.CFrame.p, (pos - tool.Handle.CFrame.p).unit * 30)
			local part, position = workspace:FindPartOnRayWithIgnoreList(ray, {player.Character,PreviewPart}, false, true)
			PreviewPart.Position = position --+ Vector3.new(0, 0.375, 0)
		end
	end
end