So, i was wondering how can i store a terrain in a string, so i can use it, and later load / unload it.
Basically i have a system that loads & unloads maps, most of them having terrain.
I have asked AI to write a script, the only result i see is that my terrain is cleared and is not restored, something is definitely broken here, any help or suggestions highly appreciated:
local Terrain = workspace.Terrain
local HttpService = game:GetService("HttpService")
local function SerializeFullTerrain()
-- Approximate Max Region3 Size:
local min, max = Vector3.new(6999, 6999, 6999), Vector3.new(7000, 7000, 7000)
local regionMin = Vector3.new(min.X, min.Y, min.Z)
local regionMax = Vector3.new(max.X, max.Y, max.Z)
local region = Region3.new(regionMin, regionMax):ExpandToGrid(4)
local materials, occupancies = Terrain:ReadVoxels(region, 4)
local serializedData = {
Min = {regionMin.X, regionMin.Y, regionMin.Z},
Max = {regionMax.X, regionMax.Y, regionMax.Z},
Voxels = {}
}
for x = 0, materials.Size.X - 1 do
for y = 0, materials.Size.Y - 1 do
for z = 0, materials.Size.Z - 1 do
local material = materials[x + 1][y + 1][z + 1]
local occupancy = occupancies[x + 1][y + 1][z + 1]
if material ~= Enum.Material.Air and occupancy > 0 then
table.insert(serializedData.Voxels, {
Position = {x, y, z},
Material = material.Value,
Occupancy = math.floor(occupancy * 1000) / 1000
})
end
end
end
end
return HttpService:JSONEncode(serializedData)
end
local function DeserializeFullTerrain(serializedString)
local data = HttpService:JSONDecode(serializedString)
local regionMin = Vector3.new(unpack(data.Min))
local regionMax = Vector3.new(unpack(data.Max))
local region = Region3.new(regionMin, regionMax):ExpandToGrid(4)
local size = region.Size / 4
local materials = {}
local occupancies = {}
for x = 1, size.X do
materials[x] = {}
occupancies[x] = {}
for y = 1, size.Y do
materials[x][y] = {}
occupancies[x][y] = {}
for z = 1, size.Z do
materials[x][y][z] = Enum.Material.Air
occupancies[x][y][z] = 0
end
end
end
for _, voxel in ipairs(data.Voxels) do
local x, y, z = voxel.Position[1] + 1, voxel.Position[2] + 1, voxel.Position[3] + 1
materials[x][y][z] = Enum.Material:GetEnumItems()[voxel.Material]
occupancies[x][y][z] = voxel.Occupancy
end
Terrain:WriteVoxels(region, 4, materials, occupancies)
end
local serializedTerrain = SerializeFullTerrain()
Terrain:Clear()
DeserializeFullTerrain(serializedTerrain)