Table.create() Method Acting Strange

  1. What do you want to achieve? Keep it simple and clear!

I want to use table.create() to make a 3-dimensional array, for the purpose of terrain generation.

  1. What is the issue? Include screenshots / videos if possible!

TL;DR -
My example 2D array is supposed to be {1,2,3} x {4,5,6}, but it’s {4,5,6} x {4,5,6} when using table.create().

Explanatory version -
When using table.create() to construct my array and then iterate through it to set values, it doesn’t set the values correctly.

When I use a nested for loop to construct the array (not as performant), it works as intended. I’m just curious why table.create() isn’t working for me. Is there something I don’t understand?

Here’s an example script you can run using a simpler 2x3 array to show what’s going on:

local sizeX = 2
local sizeY = 3

-- Returns a 2D array filled with the specified value.
local function create2DArray(x, y, value, style)
	
	-- style 1 uses table.create() to make the array
	if style == 1 then
		local tableCreateArray = table.create(x, table.create(y, value))
		return tableCreateArray
		
	-- style 2 uses nested for loops to make the array
	elseif style == 2 then
		local loopArray = {}
		for x = 1, sizeX do
			loopArray[x] = {}
			for y = 1, sizeY do
				loopArray[x][y] = value
			end
		end
		return loopArray
	end
end

-- Create arrays full of 0's, using both table.create() and nested for loops to construct them.
local tableCreateArray = create2DArray(sizeX, sizeY, 0, 1)
local loopArray = create2DArray(sizeX, sizeY, 0, 2)

print("You can see these arrays are exactly the same - full of 0's.")
print("tableCreateArray:")
print(tableCreateArray)
print("loopArray:")
print(loopArray)

-- Iterates through tableCreateArray and sets values
print("Now let's iterate through the constructed arrays and sequentially set their values.")
print("This shows that the array is being iterated through correctly:")
local count1 = 0
for x, valueX in tableCreateArray do
	for y, valueY in valueX do
		count1 += 1
		print("X: "..x.." - Y: "..y.." - Value: "..count1)
		tableCreateArray[x][y] = count1 -- But this doesn't seem to work right for whatever reason.
	end
end

-- Iterates through loopArray and sets values
local count2 = 0
for x, valueX in loopArray do
	for y, valueY in loopArray[x] do
		count2 += 1
		loopArray[x][y] = count2
	end
end

-- These arrays should be the same, but the table.create() array isn't right.
print("But this array shows that the values are not being set correctly:")
print("tableCreateArray:")
print(tableCreateArray) -- Here's the array that has issues.
print("This array shows what the array SHOULD look like:")
print("loopArray:")
print(loopArray) -- Here's the array that works fine.

Here’s the output I get from the above script:

You can see these arrays are exactly the same - full of 0’s.
tableCreateArray:
▼ {
[1] = ▼ {
[1] = 0,
[2] = 0,
[3] = 0
},
[2] = ▼ {
[1] = 0,
[2] = 0,
[3] = 0
}
}
loopArray:
▼ {
[1] = ▼ {
[1] = 0,
[2] = 0,
[3] = 0
},
[2] = ▼ {
[1] = 0,
[2] = 0,
[3] = 0
}
}
Now let’s iterate through the constructed arrays and sequentially set their values.
This shows that the array is being iterated through correctly:
X: 1 - Y: 1 - Value: 1
X: 1 - Y: 2 - Value: 2
X: 1 - Y: 3 - Value: 3
X: 2 - Y: 1 - Value: 4
X: 2 - Y: 2 - Value: 5
X: 2 - Y: 3 - Value: 6
But this array shows that the values are not being set correctly:
tableCreateArray:
▼ {
[1] = ▼ {
[1] = 4,
[2] = 5,
[3] = 6
},
[2] = ▼ {
[1] = 4,
[2] = 5,
[3] = 6
}
}
This array shows what the array SHOULD look like:
loopArray:
▼ {
[1] = ▼ {
[1] = 1,
[2] = 2,
[3] = 3
},
[2] = ▼ {
[1] = 4,
[2] = 5,
[3] = 6
}
}

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I made my code function with nested for loops, so a solution is not necessary. However, I prefer to use table.create() because it is much faster. I’ve looked into the developer documentation for the method and tested various scripts to get it to work properly.

To be honest, I’m starting to think this is more an engine issue than a scripting issue. I know there are much smarter scripters out there than me, so I figured I’d ask and see if anyone knows what’s going on here. Sorry for the long post :stuck_out_tongue:

This happens because table.create() does not create a new table for every value instead they all point to the same table.

table.create(3, {"Hello"})
is equivalent to

local t = {"Hello"}
{ t, t, t }

So you are forced to make your 2D or 3D table using loops.

Edit:
Some linters like Luau Language Server will actually tell you this.

2 Likes

Thanks for the response. It seems a bit silly that you can’t create tables for each value using a method called table.create()… I think it’s a major oversight. The whole purpose of the method is for using less memory for large arrays of known size, so it would be ideal for my (quite) large 3D arrays for generating terrain. Oh well :slight_smile: Thanks again.

The point of this function is not targeted towards memory, but more so the performance impact of resizing the internal array.

If you have a large array of say, 1000 items, it’s better to create the array with this method first so it never has to be resized. Otherwise, it may start with a size of 10, then 50, then 100, then 500, then 1000. Resizing an array is a relatively expensive operation, but this can be alleviated if you know the array size beforehand.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.