What is the best way to handle block placing in a minecraft-like game on roblox?

I’m making a Minecraft clone game on ROBLOX for fun, and I’ve been thinking about how to handle placing the blocks. I currently have setup a solution where there’s a remote that gets fired when the user interacts with a block, then the server determines the position of the new block(+sanity checks), and then the server creates the block, but I feel like there’s a bit too long of a delay with the RemoteEvent and the replication.

Would it be a good idea to have an event on all my clients that gets fired, and have the blocks only on the client side? I’ve also considered a hybrid idea where the client creates a fake block when it’s placed, and then replaces it with the real one replicated from the server, but since I don’t really have a good way of knowing when it actually gets placed besides a remote (which means potential delay), there would be a short time of both of them intersecting and it would look weird.

Any ideas?
(Apologies in advance if this is the wrong section)

Can’t people just play “Minecraft” instead of a “Minecraft-like” game?

I’m not really doing it for practicality, just to get better at making games in general and practice my programming skills a little bit. So yes, they can just play actual Minecraft.

I created my own “block placing system” a while ago, and I used the position of the player’s mouse to get the position of the block. Since I don’t really need it, I will provide it for you to experiment with and get an idea of how a block placing system works.

Just make sure to make a remote event in ReplicatedStorage called “PlaceBlock” or the system won’t work

Code

Script in ServerScriptService:

game.ReplicatedStorage.PlaceBlock.OnServerEvent:Connect(function(player,pos)
	
	repeat
		local rep = false
		for _, block in pairs(game.Workspace.Blocks:GetDescendants()) do
			if block.Position == pos then
				pos = Vector3.new(pos.X,pos.Y+5,pos.Z)
				rep = true
				break
			end
		end
	until rep == false
		
	
	local place = Instance.new("Part",game.Workspace.Blocks)
	place.Size = Vector3.new(5,5,5)
	place.Position = pos
	place.Anchored = true
	place.CanCollide = true
	place.Name = "block"
	place.Transparency = 0
	place.BrickColor = BrickColor.new("Brown")
	print("placed")
end)

LocalScript in StarterPlayerScripts:

local mouse = game:GetService("Players").LocalPlayer:GetMouse()
selecting = false
cooldown = false

mouse.Move:Connect(function()
	
	if cooldown == false then
		
		for _, part in pairs(workspace:GetDescendants()) do
			if part.Name == "selection" then
				part:Destroy()
			end
		end
		
		local mousePos = mouse.Hit.p
		
		mousePos = Vector3.new((math.round(mousePos.X/5))*5,(math.round(mousePos.Y/5))*5,(math.round(mousePos.Z/5))*5)
		
		if mouse.target then
			selecting = true
				
			local selection = Instance.new("Part",workspace)
			selection.Size = Vector3.new(5,5,5)
			selection.Name = "selection"
			selection.CanCollide = false
			selection.BrickColor = BrickColor.new("Baby blue")
			selection.Transparency = 0.5
			selection.Anchored = true
			
			selection.Position = mousePos
				
			cooldown = true
			wait(0.08)
			cooldown = false
		end
	end
	
end)

game:GetService("UserInputService").InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		if selecting == true then
			local found = false
			for _, part in pairs(workspace:GetDescendants()) do
				if part.Name == "selection" then
					found = true
				end
			end
			if found == true then
				local place = workspace.selection
				game.ReplicatedStorage.PlaceBlock:FireServer(place.Position)
				place:Destroy()
			end
		end
	end
end)

Hope this helps!

1 Like

Thanks, but I already have code written, I’m just not sure the best way to architect block placing, and you did placing on the server, like I currently have it.

1 Like