Is there any clean/efficient way to change the properties of terrain with a dictionary/table of properties?

Hello! :wave:

A bit of backstory, I am creating a round based game with different maps. These maps includes terrain (I use Crazyman32’s Terrain Save and Load if you are curious). When building these maps, I changed the material color3 value to better fit the environment plus changed other numeral/bool settings. All the values I stored are in a modules (child of map model).

Example:

--Tropical Island
local terrainProperties = {
	
["Decoration"]			= true,
	
["Material"] = {
	["Basalt"]			= Color3.fromRGB(30, 30, 37),
	["Cobblestone"]		= Color3.fromRGB(132, 123, 90),
	["CrackedLava"]		= Color3.fromRGB(232, 156, 74),
	["Grass"]			= Color3.fromRGB(86, 119, 47),
	["Ground"]			= Color3.fromRGB(102, 92, 59),
	["Sand"]			= Color3.fromRGB(197, 173, 129)
	},

["WaterColor"]			= Color3.fromRGB(82, 135, 136),
["WaterReflectance"]	= .2,
["WaterWaveSize"]		= .2

}

return terrainProperties

Currently the main script calls a function to load the map.

--Modules
local terrainModule = require(script.TerrainModule) --TerrainModule from plugin mentioned above

--Objects
local terrain = workspace:WaitForChild("Terrain")
local selectedMapFolder = workspace:WaitForChild("SelectedMap")

function loadMap(map)
	--Modules
	local terrainProperies = require(map.TerrainProperties)
	
	--Objects
	local clonedMap = map:Clone()
	local savedTerrain = map.Terrain
	
	--Setting up terrain
	terrain:Clear()
	terrainModule:Load(savedTerrain)
--Preferred place to change properties with values from module
	
	--Setting up parts
	if selectedMapFolder:FindFirstChildOfClass("Model") then selectedMapFolder:FindFirstChildOfClass("Model"):Destroy() end
	clonedMap.Parent = selectedMapFolder
	
end

loadMap(map) --"map" is the model

I was wondering is there is any compact way to change all the properties of terrain to the desired color3 values/bool values/numeral values. I feel there is a clean way to do this that is not expansive and I am just not seeing it.

I could change all properties individually but it takes a lot of lines and it’s inefficient. As a beginner to scripting, I do not have the experience to create this. Because I am a beginner, this will give me the opportunity to learn from experienced people and maybe improve existing code.

Anything advice given, taken! :grinning:

1 Like

Since the keys are the properties and the values being the desired values of those properties, you can use a for loop and index the terrain property with the key:

for property, value in pairs(terrainProperties) do
    if property ~= "Material" then
        terrain[property] = value
    end
end

-- colours. You can't directly write to the material colours,
--so you'd have to use SetMaterialColor

for material, colour in pairs(terrainProperties.Material)
    terrain:SetMaterialColor(Enum.Material[material], colour)
end
1 Like

Thanks! I will definitely use this.

Edit: Currently cannot change “decoration” property in script.