Heya, so I am having some trouble with my Cellular Automata code. If I use it like I originally did (see first .rbxm file) it works fine. However, I have recently been trying to make the code compatible with loading chunks (so I can make the cave system infinite), however my code is not working properly. I am getting the error ServerScriptService.Script:104: attempt to index nil with number
. This is my code:
math.randomseed(tick())
local scale = 4
local size = 16
local offset = Vector3.new(0, 0, 0)
local aliveChance = 0.45
local birthLimit = 12
local deathLimit = 13
local stepAmount = 4
-- Generates a 2d grid based on certain dimensions
function createGrid(xOffset, yOffset, zOffset)
local grid = {}
for i = 1, size do
grid[i] = grid[i] or {}
for j = 1, size do
grid[i][j] = grid[i][j] or {}
for k = 1, size do
if math.random() <= aliveChance then
grid[i][j][k] = "O"
else
grid[i][j][k] = "X"
end
end
end
end
return grid
end
-- Appends new data to existing grid for cellular automata to base off of
function appendToGrid(grid, xOffset, yOffset, zOffset)
for i = 1, size do
grid[i + xOffset] = grid[i + xOffset] or {}
print(i + xOffset)
for j = 1, size do
print(j + xOffset)
grid[i + xOffset][j + yOffset] = grid[i + xOffset][j + yOffset] or {}
for k = 1, size do
if math.random() <= aliveChance then
grid[i + xOffset][j + yOffset][k + zOffset] = "O"
else
grid[i + xOffset][j + yOffset][k + zOffset] = "X"
end
end
end
end
return grid
end
-- Function to print the grid for troubleshooting
function printGrid(grid)
for i, v in pairs(grid) do
for j, k in pairs(v) do
local printString = table.concat(k, "")
print(printString)
end
end
end
-- Function to count neighbors in a 2d array
function countNeighbors(grid, xPos, yPos, zPos)
local neighbors = 0
for x = -1, 1 do
for y = -1, 1 do
for z = -1, 1 do
if xPos + x < 1 or xPos + x > size or yPos + y < 1 or yPos + y > size or zPos + z < 1 or zPos + z > size then
-- neighbors += 1
else
local neighbor = grid[xPos + x][yPos + y][zPos + z]
if neighbor == "O" then
neighbors += 1
end
end
end
end
end
return neighbors
end
-- Function to perform a step of cellular automata
function doSimulationStep(grid, chunkCoordinates)
local newGrid = grid
for i = 1, size do
newGrid[i + chunkCoordinates.X] = newGrid[i + chunkCoordinates.X] or {}
for j = 1, size do
newGrid[i + chunkCoordinates.X][j + chunkCoordinates.Y] = newGrid[i + chunkCoordinates.X][j + chunkCoordinates.Y] or {}
end
end
for x, v in pairs(grid) do
for y, w in pairs(v) do
for z, u in pairs(w) do
local neighbors = countNeighbors(grid, x + chunkCoordinates.X, y + chunkCoordinates.Y, z + chunkCoordinates.Z)
if u == "O" then
if neighbors < deathLimit then
print("Appended grid to" .. x + chunkCoordinates.X .. " " .. y + chunkCoordinates.Y .. " " .. z + chunkCoordinates.Z)
newGrid[x + chunkCoordinates.X][y + chunkCoordinates.Y][z + chunkCoordinates.Z] = "X"
else
newGrid[x + chunkCoordinates.X][y + chunkCoordinates.Y][z + chunkCoordinates.Z] = "O"
end
else
if neighbors > birthLimit then
newGrid[x + chunkCoordinates.X][y + chunkCoordinates.Y][z + chunkCoordinates.Z] = "O"
else
newGrid[x + chunkCoordinates.X][y + chunkCoordinates.Y][z + chunkCoordinates.Z] = "X"
end
end
end
end
wait()
end
return newGrid
end
-- Function to place grid into workspace
function placeGrid(grid, chunk)
local offset = chunk * size
print(offset)
print(chunk * scale)
for x, v in pairs(grid) do
for y, w in pairs(v) do
for z, u in pairs(w) do
if u == "O" then
local part = Instance.new("Part")
part.Size = Vector3.new(1, 1, 1) * scale
part.Position = (Vector3.new(x + offset.X, y + offset.Y, z + offset.Z) * scale) - (chunk * scale * 2)
part.Anchored = true
part.Parent = workspace.CaveParts
end
end
end
wait()
end
end
function loadChunk(grid, chunkCoordinates, iterations)
chunkCoordinates *= size
print(chunkCoordinates)
grid = appendToGrid(grid, chunkCoordinates.X, chunkCoordinates.Y, chunkCoordinates.Z)
for i = 1, iterations do
grid = doSimulationStep(grid, chunkCoordinates)
print(grid)
end
placeGrid(grid, chunkCoordinates)
end
local grid = createGrid()
for x = -1, 1 do
for y = -1, 1 do
for z = -1, 1 do
loadChunk(grid, Vector3.new(x, y, z), stepAmount)
end
end
end
It’s very messy, I apologize. However, it seems to cause the error after 0, 0, 0, where it then tries to index the nil value, and always on the if statements between lines 94 and 105
Any help would be greatly appreciated as this is a new thing for me and I’m not quite sure how to fix this issue.
Also just realized my print statement is in a weird place but it does confirm that it is doing steps of cellular automata until it errors out
Edit: Oops, forgot to attach the old game with the code, here it is: Cellular Automata 3D Testing-2.rbxl (25.0 KB)