LibreGrid - A lightweight, intuitive and open-source grid solution for Roblox

A placement system does not “require” raycasts as it does not only happen on the client. Your module fails to account for the developer’s need to validate and ensure the position the client has provided is grid-aligned. The functions to grid-align & perform raycasts should be decoupled for this reason.

Correcting this since I did not realize that your module does actually have separate methods for raycasting and grid alignment. Though I still stand by the opinion that raycasts are not a requirement for a grid system.

Also as an FYI, this resource would be a bit more useful to developers if the Github repository was properly setup to work with Rojo.

1 Like

I really appreciate your hard work and that you are releasing this to the public. Thank you.

1 Like

hey!!

heres the code!!

local function generateblock(usepos, target, isez)
	local block = game.ReplicatedStorage.Files.BlockTypes:FindFirstChild(script.Parent.Properties.Shape.Value):Clone()
	block.Size = script.Parent.Properties.Size.Value
	block.Anchored = true
	block.CanCollide = false
	block.Color = script.Parent.Properties.Color.Value
	block.Material = Enum.Material[script.Parent.Properties.Material.Value]
	block.Transparency = script.Parent.Properties.Transparency.Value
	block.Reflectance = script.Parent.Properties.Reflectance.Value
	block.Name = "PreviewBlock"
	block.Orientation = script.Parent.Properties.Orientation.Value
	highlight.Parent = block
	highlight.Adornee = block
	if isez ~= nil and isez == true then
		highlight.Color3 = Color3.new(0.337255, 0.796078, 0.0352941)
	else
		highlight.Color3 = Color3.new(0.00784314, 0.513725, 0.827451)
	end
	if script.Parent.Properties.Light.Brightness.Value ~= 0 and script.Parent.Properties.Light.Radius.Value ~= 0 then
		local light = Instance.new("PointLight")
		light.Parent = block
		light.Color = script.Parent.Properties.Light.Color.Value
		light.Range = script.Parent.Properties.Light.Radius.Value
		light.Brightness = script.Parent.Properties.Light.Brightness.Value
	end
	if usepos == true then
		block.Position = require(script.Parent.LibreGrid):GetCFrameAtMousePosition(block, 4, CFrame.new(block.Orientation)).Position
		print(block.Position)
	end
	return block
end

the “4” part in the getcframeatmousepos is meant to be dynamic, but i havent worked on said dynamic part yet so i could report this bug

thanks for your suggestions! ill try setting up rojo although i have never tried it before :3

also, if you’re worried about the grid alignment server-side, instead of sending the cframe over, you could send every parameter needed to replicate the function there. although it might be a little bit complicated to figure out the ray if you’re using GetCFrameAtMousePosition, i’ll probably add better support for this in the future. thank you! :3

you could use the NormalBased configuration (as explained in the documentation) which makes placement relative to normals instead of the ray hit for this use case :3

though, now that i’m realizing it, i forgot to add support for smaller sizes while this is turned on. i will try to add support for it asap!

1 Like

LibreGrid V.1.1.0

V.1.1.0 is here!!! woohoo!!

LibreGrid now allows you to customize the rounding function utilized. this is to avoid weird, jittery behavior on bigger grid sizes:

math.round (default):


it’s jittery and doesn’t work as desired

math.floor:


works as desired

2 Likes

i mean it “sort of” works but…

image

it does still seem to offset [if i have like, my params right].

is this normal? i think i enabled it with the params

		block.Position = require(script.Parent.LibreGrid):GetCFrameAtMousePosition(block, 4, CFrame.new(block.Orientation), {
			raycastparams,
			false,
			true,
			false,
			true,
			math.floor
		}).Position

i did also forget to mention, if my orientation isnt exactly 0,0,0, it clips to like hundreds of blocks above for some reason

Use CFrame.fromOrientation instead of CFrame.new for the orientation

watch out! settings uses a dictionary, not an array!

this is a dictionary:

local dictionary = {
A = 5,
B = true,
C = "hey there"
}
1 Like

Pretty much fixed most of my issues.

My only two issues now:


How would I disable the overlapping of the block? like, if I aim at the front area of the wedge, it’ll clip into the white wedge [or the top], but any other area it’d build below.

Also this:
image
Whenever I rotate my block, it offsets now.

could you please show me your script so i can see what went wrong? thank you :3

Wow finally an open source for grid related stuff, This is going to be useful for the current game I’m working on. Thanks for your contribution!

2 Likes

Is it possible to make a gui version of this? Im trying to make self learning chess

I find that the orientation not being relative to its surface grid, is it supposed to do that?
Or did i do something wrong?

local LibreGrid = require(script.LibreGrid)

local Setup = {
	RaycastParams = nil,
	ForceAlignedOutput = false,
	AllowFaceAlignment = true,
	NormalBased = false,
	WhitelistedNormals = nil,
	RoundingMethod = math.floor,
}


while wait() do
	local block = workspace.Folder.Test
	local Result = LibreGrid:GetCFrameAtMousePosition(
		block,
		1, 
		CFrame.new(block:GetPivot():ToOrientation()), 
		Setup
	)
	workspace.Folder.Test:PivotTo(Result)
end

It’d be helpful if you could provide us information of setting up and possible coding examples and what they do. :heart:
Take your time, this could be a game changer.
image
image

1 Like

this module is focused on 3d, im sorry but i haven’t delved into the math needed to do this in a 2d space!

i can see why this happens. libregrid is rounding the position to the grid. however, the slope would require the block to get a bit off the grid to snap to that surface.

im not sure if i want to keep this behavior or allow parts to stay a bit off to snap to the surface. though, the current behavior facilitates sanity-checking on the server.

also sorry for the delayed response i didn’t see ur post :broken_heart:

1 Like
local function generateblock(usepos, target, isez)
	local block = game.ReplicatedStorage.Files.BlockTypes:FindFirstChild(script.Parent.Properties.Shape.Value):Clone()
	block.Size = script.Parent.Properties.Size.Value
	block.Anchored = true
	block.CanCollide = false
	block.Color = script.Parent.Properties.Color.Value
	block.Material = Enum.Material[script.Parent.Properties.Material.Value]
	block.Transparency = script.Parent.Properties.Transparency.Value
	block.Reflectance = script.Parent.Properties.Reflectance.Value
	block.Name = "PreviewBlock"
	block.Orientation = script.Parent.Properties.Orientation.Value
	highlight.Parent = block
	highlight.Adornee = block
	if isez ~= nil and isez == true then
		highlight.Color3 = Color3.new(0.337255, 0.796078, 0.0352941)
	else
		highlight.Color3 = Color3.new(0.00784314, 0.513725, 0.827451)
	end
	if script.Parent.Properties.Light.Brightness.Value ~= 0 and script.Parent.Properties.Light.Radius.Value ~= 0 then
		local light = Instance.new("PointLight")
		light.Parent = block
		light.Color = script.Parent.Properties.Light.Color.Value
		light.Range = script.Parent.Properties.Light.Radius.Value
		light.Brightness = script.Parent.Properties.Light.Brightness.Value
	end
	if usepos == true then
		local raycastparams = RaycastParams.new()
		raycastparams.FilterDescendantsInstances = {block, game.Players.LocalPlayer.Character}
		raycastparams.FilterType = Enum.RaycastFilterType.Exclude
		block.Position = require(script.Parent.LibreGrid):GetCFrameAtMousePosition(block, 4, CFrame.fromOrientation(
			block.Orientation.X, block.Orientation.Y, block.Orientation.Z), {
			RaycastParams = raycastparams,
			ForceAlignedOutput = false,
			AllowFaceAlignment = true,
			NormalBased = false,
			WhitelistedNormals = nil,
			RoundingMethod = math.floor
		}).Position
		--print(block.Position)
	end
	return block
end

i know this is taking forever :sob:

2 Likes

have you tried using the NormalBased configuration? it allows you to align blocks to each surface better, just like your use case.

sorry again for the late response, i barely have any time rn :sob:

After setting it to true,
image

it still offsets :disappointed_relieved: on the X and Z axis

could you please check if the ground is offset from the grid? that might be why it’s not aligned