I did quite a bit of digging but I couldn’t find anything regarding a specific grid size. All answers just resort to math.floor(), but that only works with 1x1x1 grids.

I want the player to have the ability to choose the snapping grid, similar to how this works:

depending on whether you want to always round down or to round to the nearest. You could also use a custom rounding function that has grid size as a parameter and uses modulus (%-operator) which gives the remainder. This function should round to the nearest grid-aligned value.

local function round(n, gridSize)
local absN = math.abs(n)
local remainder = absN%gridSize
if remainder < gridSize*.5 then
return math.sign(n)*(absN-remainder)
else return math.sign(n)*(absN-remainder+gridSize)
end
end

If you just want to round down, you can use this

local function roundDown(n, gridSize)
return n-n%gridSize
end