What math formulas i need to make a grid system?

  1. What do you want to achieve?

    Bassicaly i want make a grid system on my map (using the baseplate as reference to create the grids)

  2. What is the issue?

    Iam not super good with math, so i need understand how that math will work, i need create the grids just with positions (that i will save on tables), than i will need a math for check if some spell or player is inside some grid using that positions on table.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

    I tryed look for some tutorials, but i still dont understand how that type of math work.

What do you mean by “grid system”?

I think that it means locking object to a grid in a building system and define “legal” way of placing objects.
In the screenshot bellow you can see legally (green) and illegally (red) placed parts to a grid system:
image
I might be wrong of course.

like chuncks, like minecraft, chuncks, that.

yes but i will create a grid for the entire map


i pretend save the chuncks positions on tables (to dont be necessay create parts or region 3 for that).

What goes on this grid? A part / model that fits within that grid spot? A bit confused as to what you want to do.

I made blocks placing system, which uses a definied grid. I can share and explain from scratch how I figured it out and how I coded it.

that is fine, how that work, it would be helpful

bassicaly i wont use .touched for my spells hitbox, i will check in what GRID the spell is, and check for spells that are inside that chunck too, that is why i need a grid system.

Well for example, if you have one box where the bottom left corner is position (0,0) and you know the side of each grid box is 2 studs, you can find the bounds of that box like this:

Left Side Bottom Corner: (0,0)
Right Side Bottom Corner (2,0)
Left Side Top Corner: (0,2)
Right Side Top Corner: (2,0)

And then repeat for each after that, if you have another grid to the immediate right of the first grid, just adjust the bottom corners by adding 2 to the first values of both pairs.

than how i would be able to check if some PART is inside that grid? (since i just have the borders positions)

If its less than the right and top most bounds and greater than the left and bottom most bounds.

EX: A position of (1,1) is less than (0,2) in the Y-axis (1 < 2) and greater than (0,0).

what you mean “left most bound”? iam brazilian so i didnt get it.

If the part is inside of a grid box, it must be less than the top Y-axis value and greater than the bottom Y-axis value. In the above example the top y value is 2 and the bottom is 0, so to be within the bounds on the Y-axis it must be between 0 and 2.

Same for the x-axis values.

My blocks basement system uses blocks with size of 3x3x3 studs.

  1. Legal x axis:
    I noticed that:
    if part.Position * 10 % 3 == 0 then it’s legally placed in x axis
    else it’s illegally placed in x axis

  2. Legal y axis:
    To make my explanation shorter I will explain the system only for placing on a baseplate.
    There is only one legal Position.Y number for legal placement (expection, placing blocks on blocks)

  3. Legal z axis:
    Very similiar to x axis, but with z axis

  4. My code (local script):

local players = game:GetService("Players")
local player = players.LocalPlayer
local replicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = script.Parent:WaitForChild("RemoteFunction")
local mouse = player:GetMouse()
local tool = script.Parent
local ghostParts = workspace:WaitForChild("GhostParts")
local placeBlockPreview = replicatedStorage:WaitForChild("PlaceBlockPreview")
local character = player.Character
if not character or not character.Parent then
	character = player.CharacterAdded:Wait()
end
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local baseplate = workspace:WaitForChild("Baseplate")
local buildingModel = workspace:WaitForChild("BuildingModel")
local canUse = true

-- Important for calculating legal x and z position
local function calculateOffset(positionNumber)
	if positionNumber * 10 % 3 == 1 then
		return -1
	elseif  positionNumber * 10 % 3 == 2 then
		return 1
	else
		return 0
	end
end

mouse.TargetFilter = ghostParts

tool.Equipped:Connect(function()
	local clone = placeBlockPreview:Clone()
	
	while tool:FindFirstAncestorOfClass("Model") and humanoid.Health ~= 0 do
		local mouseHit = mouse.Hit
		local mouseTarget = mouse.Target
		local mouseSurface = mouse.TargetSurface

		-- In my building system it's used to prevent building outside game's map
		local legalPosX = mouseHit.X < 750 and mouseHit.X > -750
		local legalPosY = mouseHit.Y < 1507.5
		local legalPosZ = mouseHit.Z < 750 and mouseHit.Z > -750

		local hitPosition = Vector3.new(mouseHit.X, mouseHit.Y, mouseHit.Z)
		local rootPartPosition = rootPart.Position
		local distance = (hitPosition - rootPartPosition).magnitude

		-- Distance is used to limit player's distance of building
		if mouseTarget ~= nil and legalPosX and legalPosY and legalPosZ and distance <= 18 then

			-- My building system also uses other types of blocks, don't worry about that
			if mouseTarget.Name == "Slab" and mouseTarget:FindFirstChild("SlabBlock") then
				mouseTarget = mouseTarget.SlabBlock
			elseif mouseTarget.Name == "OnTopSlab" and mouseTarget.Parent.Name == "SlabBlock" then
				mouseTarget = mouseTarget.Parent
			end

			-- This checks if player is pointing with his mouse at an another block or the baseplate
			if mouseTarget == baseplate or mouseTarget:FindFirstAncestor("BuildingModel") then
				-- This is the most important part because you want to understand how to make grid system on only a baseplate
				if mouseSurface == Enum.NormalId.Top then -- Check if mouse is pointing at baseplate's top surface
					if mouseTarget == baseplate then
						clone.CFrame = mouseHit
-- This is the actual math part. math.floor rounds down every number (examples: 5 to 5, 5.44 to 5, 5.87 also to 5, not 6). I also noticed that the last number of Position.X and Position.Z must be 5 for a block to be legally placed
						clone.CFrame = mouseTarget.CFrame:ToWorldSpace(CFrame.new(
							math.floor(clone.Position.X) + 0.5 + calculateOffset(math.floor(clone.Position.X) + 0.5),
							(mouseTarget.Size.Y + clone.Size.Y) / 2,
							math.floor(clone.Position.Z) + 0.5 + calculateOffset(math.floor(clone.Position.Z) + 0.5)
						))

					else -- Don't worry about that, it's related to placing on other blocks, not baseplate
						clone.CFrame = mouseTarget.CFrame:ToWorldSpace(CFrame.new(0, mouseTarget.Size.Y, 0))
					end
-- For other surfaces it's also not related to grid on the baseplate
				elseif mouseSurface == Enum.NormalId.Right then
					clone.CFrame = mouseTarget.CFrame:ToWorldSpace(CFrame.new(mouseTarget.Size.X, 0, 0))

				elseif mouseSurface == Enum.NormalId.Left then
					clone.CFrame = mouseTarget.CFrame:ToWorldSpace(CFrame.new(-mouseTarget.Size.X, 0, 0))

				elseif mouseSurface == Enum.NormalId.Front then
					clone.CFrame = mouseTarget.CFrame:ToWorldSpace(CFrame.new(0, 0, -mouseTarget.Size.Z))

				elseif mouseSurface == Enum.NormalId.Bottom then
					clone.CFrame = mouseTarget.CFrame:ToWorldSpace(CFrame.new(0, -mouseTarget.Size.Y, 0))
					
				elseif mouseSurface == Enum.NormalId.Back then
					clone.CFrame = mouseTarget.CFrame:ToWorldSpace(CFrame.new(0, 0, mouseTarget.Size.Z))

				end
				
				clone.Parent = ghostParts
			end
			
		else
			clone.Parent = nil
		end
		
		wait()
	end
	
	clone:Destroy()
end)

tool.Activated:Connect(function()
-- Player sees a transparent block (placement preview block). After activating the tool, the server gets a request to clone a block from server storage, set the clone's CFrame to preview block CFrame and set it's parent to BuildindModel
	if humanoid.Health ~= 0 and ghostParts:FindFirstChild("PlaceBlockPreview") and canUse then
		local previewCFrame = ghostParts.PlaceBlockPreview.CFrame
		canUse = false
		remoteFunction:InvokeServer(previewCFrame)
		canUse = true
	end
end)

You can ask questions about the code here. I suggest copying the code to Roblox Studio and removing pieces of code, which aren’t related to placing blocks on a baseplate and then reading it.

For people in the future, who find this topic to find a soluion related to the topic, there’s a free model made by me, which is easier to understand: Blocks Placement System to Grid (Like Minecraft) - Roblox.