Using a loop to designate and formulate Regions

Hey there!

I’m a Developer and otherwise map maker who’s otherwise happened upon some old maps that I was looking to shape up and revitalize for new use elsewhere, though in order to do that, I’m finding that a lot of the existing terrain needs to be converted almost entirely from one type of terrain from another.

That being said, I have a base idea to do this with, in addition to some code to work off of, however, the only problem I’m finding is using a loop or other function to declare and execute the replacement function on the given regions. So, more or less what I’m looking for help doing is getting said loop formulated to run around coordinate positions as such, though the math and the necessary equations, as I’m finding, is proving somewhat difficult.

Would anyone be able to help me in this regard to get something consistent and furthermore functional running towards this end?

Thanks!

Your thread’s confusing and the simplification is even more confusing. What are you trying to do? What’s your specific use case and what are you hoping to do? Is it just splitting your map up into regions or what are you going to do with those regions?

If you’re looking to make a grid-like identifier for your map, then you can think of this problem as columns and rows and iterate accordingly. If you’re trying to reuse the terrain, then CopyRegion and PasteRegion are what you want - there are code samples on how to use that on the Developer Hub.

My apologies if that was made to seem confusing, let me try again here;

Effectively, I have a map with terrain, said terrain that, among multiple materials, I want to change one of those materials (Grass) to Snow. That being said, painting a 16kx16k map isn’t necessarily optimal. Hours or work, at best. So, the idea is that, using some code, either through a loop or otherwise, I have a script that isolates regions, kind of like into a grid pattern, and then replace the terrain which matches the material requirement to the desired material.

Is that better? The only problem I’m finding is figuring out the needed math that I would put in a loop to properly go all around the map and replace the needed terrain.

1 Like

Well, Not sure how well one is able to use Terrain:ReadVoxels and Terrain:WriteVoxels. for this as I personalyl have never tried it, but you might be able to try that.

The idea being you Terrain:ReadVoxels in a given area to get all the grass terrain and then replace them using Terrain:WriteVoxels.

Scripting Terrain - Reading and Writing Voxels

Unless you’re looking to have grass in certain regions and snow in others I personally would select the whole region for the map and set said terrain matching grass to snow. Likewise if you want to sweep an area in sections you could run a loop that goes up in the X axis.

Example: I have a region of 10 x 10 x 10 centered at 0,0,0. I want to go + on the X axis 2 times each region having a different terrain set.

I know that since the region is a 10 x 10 x 10 square that on the left side (X-) it goes to -5 and on the right side it goes to 5 (X+) for the X axis. For depth (Z) it does the same thing, goes to 5 on Z+ and -5 on Z-. Same thing for the Y axis 5 on Y+ and -5 on Y-.

Now I just need some sort of function or formula that can give me the center of the next region.

In this case POS will be the initial starting position in this example we’re staying on the X axis. and REPT going left/Right. Obviously the down side is we’re stuck on one Axis currently.

F(POSX,SIZE,REPT) = POSX + (SIZE* REPT)

So long as we know our Z Axis we can use this in one direction going left to right, so let’s put some numbers in.

F(0,10,1) = 0 + (101)
F = 10
F(0,10,2) = 0 + (10
2)
F = 20

Now that we have values for the center of region on the X axis we can go X- by 1/2 of SIZE and X+ by 1/2 of SIZE on the X axis to get the Region Corners. Keep in mind we haven’t changed our Z so for F(0,10,2) we’re at 20,0,0 (X,Y,Z).

Taking 1/2 of SIZE on X- gets us 15. so thats 15,0,0 now if we take 1/2 of SIZE and add it to the Z axis we get the top right corner which is 15,0,5.

Now lets get the bottom left corner.

We take 20 and add 1/2 half of SIZE to it and get 25 for our X axis now we take 1/2 of Size again and subtract it from the Z axis and get -5 for that. Puting numbers together we get 25,0,-5 for the bottom left. That gets us what the region bounderies are which can be useful for many things.

the included picture shows what the region would look like. the parts are 1x1x1

image

Since regions do this math for bounderies for us we just need the center position and size of the region. F(POSX,SIZE,REPT) gets us the position on the X axis.

However, we’re still stuck going left and right on the X axis and cant make any progress with the Z Axis. I personally would take the first region we started with and say I want to go Z+ would take
Z and add the SIZE to it. if we’re at 0,0,0 for the center that means the next region above that is at
0,0,10. so long as SIZE = 10.

We’d do the same thing for the Y axis as well.

Here’s a Lua function:

-- return center of region
function regionCenter(x,y,z,size,rept)
	local z = 0
	local x = 0
	local y= 0
	local poss = {}
	
	x = x + (size * rept)
	z = z + (size * rept)
	y = y + (size * rept)
	
	poss = {x,y,z}
	
	return poss
end

Sorry if this was a bit confusing, thought it would be good to cover how a region is actually calculated before getting the center of a region. Hopefully this gives you an idea of where to go with looping through a region. Let me know if you run into any problems or have any questions.

Thank you for the input! That’s a good start on getting things going.

The only thing I noticed is that I’m not necessarily trying to go through a single region, rather the regions themselves being the only thing bounced between.

I was looking to use Terrain:ReplaceMaterial to this end, as it lets me already select a material to replace and a material to replace it with. The only problem I was encountering was finding a formula to effectively create the region bounds to be used with this function, then moving on and doing the same for another region, etc, etc, until the whole map was sorted and otherwise finished in terms of replacing materials.

With your note on region centers, however, what I’m thinking now is to identify several region centers by their coordinate points then, from there, use some sort of mathematical equation to stretch the bounds from the center and replace the terrain accordingly.

How does that sound?

1 Like

That is better, which I can now tell you that you’re going about this the wrong way and you have indeed stumbled into an XY problem. This is why you need to read documentation so you can at least some idea of what you can use natively rather than resorting to unnecessarily complex solutions.

You will need to use ReplaceMaterial if you want a very simple version of this. Cast a region across the entire map and replace the Grass material with Snow. This accepts 4 arguments: the Region, Resolution (AFAIK internally this calls ExpandToGrid), the old material and the new material. So the work on your part is finding a way to construct a Region3 across your whole map, then you can just use that here.

The voxel resolution minimum is 4, you can use larger resolutions in multiples of 4 to expedite the process.

That was the initial attempt, though I ran into the issue that Region3 values have a max volume of which they cannot exceed, so covering a 16kx16k map in one big swoop, while it would be most certainly optimal and simple to do, is impossible.

Edit: Forgot to add the below in;

Hence comes the need to construct a formula, if possible, to automatically designate and essentially build regions within the size constraints across the whole map.

edit2: i cannot simple english today apparently.

Oh, is that so? I was unaware, TIL. We can backtrack a bit then, keeping ReplaceMaterial in mind but figuring out how to divide the map up into cube regions. As far as how though, that’s the end for me, I’m no math wizard. The best I know is that you’ll have ease if you can at least work in a column-row style somehow.

Stupid solution but in this case because I’m no good at math, I resort to more visual attempts over arbitrary equations. I’d just create proxy parts and use a loop to increase how many there are, starting with an outer loop and an inner for loop. So for every time it goes downwards, it goes a certain number across. This would create basically an entire grid of parts cells. I can then cast a region across those to be passed to ReplaceMaterial.

:man_shrugging:

1 Like

Kinda Confused, Please correct me if I’m wrong.

I believe this is possible, off the top of my head I don’t know the max size of a region. Let’s say it’s 500,500,500 (X,Y,Z). You’d probably want to take note of points X,Y,Z and write them down somewhere for safe keeping and then calculate how many loops through it requires on each row, ideal if the map is indead 16k x 16k as you say and doesn’t weirdly extend beyound that once you find one row the rest should be the same.

Say I have a map that’s 2k x 2k and a region size limit of 500x500x500 (idk if this is roblox’s region size limit :man_shrugging:) starting at 0,0,0 and going right I’d have to do this 4 times to get to 2K. meaning each row (4 rows) should loop through 4 times using that axis thing mentioned above.
(Sorry my brain kinda pooped out after all that explanation.)

PS: Think I messed up a bit on that lua function above, but I think it gets the point across

Alright, well, I’ll work with what we have then and I’ll see what I can throw together, thank you!

(Also, for note, I did some research last night and the max region size is around 644,644,644)

1 Like

No Problem! Keep us posted and if you need anything let us know.

Edit: Thank you for the max region size info btw.

Edit2: Didn’t know ReplaceMaterial was a thing; couldn’t find it until you mentioned it.