Part not cloning

I’m making a pathfinding system for a tile based movement game, and whenever I try to clone the goal tile of the player it breaks the script.
Heres the code:

if tile.Position == primaryPart.Position + distanceTable[key] and tile:GetAttribute("occupiedBy") ~= "pokemon" then
							goal = tile:Clone()
							goal.Parent = workspace
							goal.Name = "Goal"
							for i, j in pairs(goal:GetChildren()) do
								j:Remove()
							end
createObject("IntValue", {
								Name = "G",
								Parent = goal
							})

Whenever I remove

goal = tile:Clone()
							goal.Parent = workspace
							goal.Name = "Goal"
							for i, j in pairs(goal:GetChildren()) do
								j:Remove()
							end
createObject("IntValue", {
								Name = "G",
								Parent = goal
							})

It works perfectly, so I need some help here.

4 Likes

In the script you copy-pasted to this post, there is no “end” line for the if statement. So your script should look like:

if tile.Position == primaryPart.Position + distanceTable[key] and tile:GetAttribute("occupiedBy") ~= "pokemon" then
	goal = tile:Clone()
	goal.Parent = workspace
	goal.Name = "Goal"
	for i, j in pairs(goal:GetChildren()) do
		j:Remove()
	end
	createObject("IntValue", {
		Name = "G",
		Parent = goal
	})
end

If that’s your mistake, no worries. As programmers, we do mistakes like this all the time.

1 Like

There is a conclusion in the script, I’m aware of this unfortunately. There’s just a butt-ton of stuff after that doesn’t have much to do with this error. I apologize for that confusion.

what exactly breaks? because unless it errors EXACTLY there, its very possible its a script afterwards thats breaking due to the tile being cloned (as in, some scrip that happens later really doesn’t like a cloned tile).

There are no errors in the output, but it’s very odd how the script only doesn’t work when the line to clone the part is there. I’m very curious now though, so I’ll test what you’ve said and see exactly where it breaks when the clone function is there.

especially as there is no error in the output, its most likely theres something that happens afterwards that doesn’t like the addition of extra tiles. I would suggest using print statements to test out what variable/list/other value isn’t as expected (or if statements) as to locate the issue

I did a bit of testing and I’ve pinpointed

if tile.Position == primaryPart.Position + distanceTable[key] and tile:GetAttribute("occupiedBy") ~= "pokemon" then

Breaks the script. Which is weird because before I got to all this pathfinding junk, this worked perfectly.

quick question: is “goal” still considered apart of the tiles? if so, the issue is most likely because you removed alot of stuff from it or something.
(since I dont know exactly what your script does and how it does it thats the only thing I can really guess)

Goal is basically a clone of the tile the player is trying to get to so that the pathfinding can create a path from where the enemy is, to where the player is. And the goal tile is supposed to be cloned to workspace, which for some reason is not happening. So no, it should not be a part of the tiles.

1 Like

Yes, but is it actually still considered part of the tile (not should it).

Try printing out the tile and maybe tile.parent before the if statement

Unfortunately I can’t because

if tile.Position == primaryPart.Position + distanceTable[key] and tile:GetAttribute("occupiedBy") ~= "pokemon" then

is breaking the script, any ideas on why this might be broken? Because like I said earlier, it worked fine before I started working on the pathfinding.

1 Like

its breaking the script as in?
Is it erroring or is it just causing some issues?
No matter which one, add a “print(tile)” right before that line

No errors, the code just stops there, and here is the output after adding what you said before the line:


(Don’t worry about the error, that’s simply because the goal tile is not existent. And there a line calling upon the nil tile later in the script.)
The tiles are stored in a folder called tiles, and I added print(tile.parent) after print(tile).
Does any of this help you out?

1 Like

Strange. Can you provide a bit more of the code? (and also try printing primaryPart.Position, distanceTable[key] and all attributes of the tile)

Heres what I added before the line:
image
And here is the output:


Also, I wouldn’t know what specifically to send to you, so let me provide the entire open source module:

--[[Pokemon: Ultra Mystery Dungeon Main Dungeon Module]]--

--[[
	>>Credits:
	--@NolanC
	--@SorrowScripts
--]]

--[Services]
local replicatedStorage = game:GetService("ReplicatedStorage")
local replicatedFirst = game:GetService("ReplicatedFirst")
local userInputService = game:GetService("UserInputService")

--[Directories]
local clientModulesFolder = replicatedStorage:WaitForChild("ClientModules")
local guisFolder = replicatedStorage:WaitForChild("Gui")
local assetsFolder = replicatedStorage:WaitForChild("Assets")
local chunksFolder = replicatedStorage:WaitForChild("Chunks")
local dungeonsFolder = replicatedStorage:WaitForChild("Dungeons")

--[Modules]
local ChunkService = require(clientModulesFolder:WaitForChild("ChunkService"))
local guiModule = require(guisFolder:WaitForChild("GuiModule"))
local utilities = require(clientModulesFolder:WaitForChild("Utilities"))
local playerData = require(clientModulesFolder:WaitForChild("PlayerData"))
local animations = require(assetsFolder:WaitForChild("Animations"))
local dungeonGui = require(guisFolder:WaitForChild("DungeonGui"))

--[Others]
local players = game:GetService("Players")
local player = players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local runService = game:GetService("RunService")
local camera = workspace.CurrentCamera

--[Utilites]
local createObject = utilities.CreateObject
local tween = utilities.Tween
local playAnimation = utilities.PlayAnimation
local signal = utilities.Signal()

--[DungeonModule]
local DungeonModule = {
	["Index"] = {
		["Shady Forest"] = {
			["Floors"] = 4,
			["EnemyPokemon"] = {
				--[["Nincada",
				"Seedot",
				"Wurmple",
				"Caterpie",
				"Plusle",
				"Minun",]]
				"Charmander",
				"Treecko",
				"Totodile"
			},
			["ItemsPossible"] = {
				"Apple",
				"Perfect Apple"
			}
		},
	},
	["InputsEnabled"] = false
}

--[Local Utilites]
local function GetDungeonLevel(dungeonID)
	local dungeon
	local success, err = pcall(function()
		if dungeonID == "Shady Forest" then
			local dungeonFolder = dungeonsFolder:WaitForChild("Shady Forest")
			if not workspace:FindFirstChild("Level1") then
				dungeon = dungeonFolder:WaitForChild("Level1"):Clone()
				dungeon.Parent = workspace
				dungeon.Name = "DungeonChunk"
			elseif not workspace:FindFirstChild("Level2") then
				dungeon = dungeonFolder:WaitForChild("Level2"):Clone()
				dungeon.Parent = workspace
				dungeon.Name = "DungeonChunk"
			elseif not workspace:FindFirstChild("Level3") then
				dungeon = dungeonFolder:WaitForChild("Level3"):Clone()
				dungeon.Parent = workspace
				dungeon.Name = "DungeonChunk"
			elseif not workspace:FindFirstChild("Level4") then
				dungeon = dungeonFolder:WaitForChild("Level4"):Clone()
				dungeon.Parent = workspace
				dungeon.Name = "DungeonChunk"
			end
		else
			if workspace:FindFirstChild("DungeonChunk") then
				pcall(function()
					workspace:FindFirstChild("DungeonChunk"):Remove()
				end)
			end
			local dungeonFolder = dungeonsFolder:WaitForChild(dungeonID)
			dungeon = dungeonFolder:WaitForChild(math.random(1, #dungeonFolder:GetChildren())):Clone()
			dungeon.Parent = workspace
			dungeon.Name = "DungeonChunk"
		end
	end)
	if not success then
		warn("Request Dungeon Folder Failed:", err)
	end
	return dungeon
end

function pickUpItem(pokemon, amount, item)
	dungeonGui.MessageLog((pokemon.." picked up (x"..amount..") "..item.. if amount == 1 then "." else "(s)."))
end

--[PathFinding]
local nodeSpacing = 7

--Required for A* pathfinding algorithm.
local openList = {}
local closedList = {}

local validDirections = {
	Vector3.new(1, 0, 0),
	Vector3.new(-1, 0, 0),
	Vector3.new(1, 0, 1),
	Vector3.new(-1, 0, -1),
	Vector3.new(1, 0, -1),
	Vector3.new(-1, 0, 1),
	Vector3.new(0, 0, 1),
	Vector3.new(0, 0, -1)
}

--Getting the dungeon pathfinding folder
if not workspace:FindFirstChild("DungeonPaths") then
	createObject("Folder", {
		Name = "DungeonPaths",
		Parent = workspace
	})
end
local dungeonPathsFolder = workspace:WaitForChild("DungeonPaths")

function createPart(position, parent)
	local part = createObject("Part", {
		Name = "Node",
		BrickColor = BrickColor.Blue(),
		Position = position,
		Size = Vector3.new(1, 1, 1),
		Anchored = true,
		CanCollide = false,
		Parent = parent,
		createObject("IntValue", {
			Name = "G",
			Value = parent.G.Value + 1,
		})
	})
	return part
end

function castRay(start, direction)
	return workspace:FindPartOnRay(Ray.new(start, direction * nodeSpacing))
end

function tracePath(finalNode)
	local current = finalNode
	repeat
		current.BrickColor = BrickColor.Yellow()
		current = current.Parent
	until current.Parent == workspace
end

function createGoalTile(goalTile)
	print("yas")
	print(goalTile.Parent)
	local goalPart = goalTile:Clone()
	goalPart.Parent = workspace
	goalPart.Name = "Goal"
	for i, j in pairs(goalPart:GetChildren()) do
		j:Remove()
	end
	createObject("IntValue", {
		Name = "G",
		Parent = goalPart
	})
	return goalPart
end

function DungeonModule:CreatePath(start, goal)
	local final = nil
	table.insert(openList, start)
	repeat --wait()
		local low_F = math.huge
		local best = nil
		for l,node in ipairs(openList)do
			local H = (node.Position - goal.Position).Magnitude * nodeSpacing
			local G = node.G.Value
			if G + H < low_F then
				low_F = G + H
				best = {node, l}
			end
		end
		table.insert(closedList, best[1])
		if best[1] ~= start then
			best[1].BrickColor = BrickColor.Blue()
		end
		table.remove(openList, best[2])
		for _,vector in ipairs(validDirections)do
			local ray_Part, ray_Pos = castRay(best[1].Position, vector)
			if not ray_Part then
				local part = createPart(ray_Pos, best[1])
				table.insert(openList, part)
			end
		end
		final = best[1]
	until #openList <= 0 or (best[1].Position - goal.Position).Magnitude <= nodeSpacing * 1.5
	tracePath(final)
	start:Remove()
	goal:Remove()
	return dungeonPathsFolder:GetChildren()
end

function DungeonModule:Floor(level, team)
	local gui = createObject("ScreenGui", {
		Parent = playerGui,
		Name = "DungeonScreen",
		IgnoreGuiInset = true
	})
	
	local background = createObject("Frame", {
		Parent = gui,
		BackgroundColor3 = Color3.new(0, 0, 0),
		Size = UDim2.new(1, 0, 1, 0),
		ZIndex = 1
	})
	
	local topText = createObject("TextLabel", {
		Parent = background,
		BackgroundTransparency = 1,
		Size = UDim2.new(1, 0, 0.3, 0),
		Position = UDim2.new(0, 0, 0.3, 0),
		Font = Enum.Font.GothamBold,
		TextScaled = true,
		Name = "TopText",
		TextColor3 = Color3.new(1, 1, 1),
		TextTransparency = 1,
		Text = self,
		ZIndex = 2
	})
	
	local bottomText = createObject("TextLabel", {
		Parent = background,
		BackgroundTransparency = 1,
		Size = UDim2.new(1, 0, 0.17, 0),
		Position = UDim2.new(0, 0, 0.6, 0),
		Font = Enum.Font.GothamBold,
		TextScaled = true,
		Name = "BottomText",
		TextColor3 = Color3.new(1, 1, 1),
		TextTransparency = 1,
		Text = level.."F",
		ZIndex = 2
	})
	
	tween(topText, {TextTransparency = 0}, 1)
	task.wait(2)
	tween(bottomText, {TextTransparency = 0}, 1)
	task.wait(2)
	tween(topText, {TextTransparency = 1}, 1)
	tween(bottomText, {TextTransparency = 1}, 1)
	
	local modelsFolder = replicatedStorage:WaitForChild("Models")
	local itemModelsFolder = modelsFolder:WaitForChild("Items")
	local dungeonLevel = GetDungeonLevel(self)
	local tiles = dungeonLevel:WaitForChild("Tiles")
	local playerPokemon = utilities.GetPokemon(playerData.PlayerPokemon)
	local pokemonFolder = createObject("Folder", {
		Parent = workspace,
		Name = "Pokemon"
	})
	
	playerPokemon.Name = "Player"
	playerPokemon.PrimaryPart.Anchored = true
	playerPokemon.Parent = pokemonFolder
	local playerTile = tiles:GetChildren()[math.random(1, #tiles:GetChildren())]
	playerPokemon.PrimaryPart.CFrame = playerTile.CFrame
	playerTile:SetAttribute("occupied", true)
	playerTile:SetAttribute("occupiedBy", "pokemon")
	playAnimation(playerPokemon, animations[playerData.PlayerPokemon.."Idle"])
	
	for i = 1,1 --[[math.random(#DungeonModule.Index[self].EnemyPokemon,14)]] do
		local randomPokemon = DungeonModule.Index[self].EnemyPokemon[math.random(1, #DungeonModule.Index[self].EnemyPokemon)]
		local enemyPokemon = utilities.GetPokemon(randomPokemon)
		enemyPokemon.Name = (randomPokemon)
		enemyPokemon.PrimaryPart.Anchored = true
		enemyPokemon.Parent = pokemonFolder
		
		while true do
			local enemyTile = tiles:GetChildren()[math.random(1, #tiles:GetChildren())]
			if not enemyTile:GetAttribute("occupied") then
				enemyPokemon.PrimaryPart.CFrame = enemyTile.CFrame
				enemyTile:SetAttribute("occupied", true)
				enemyTile:SetAttribute("occupiedBy", "pokemon")
				break
			else
				enemyTile = tiles:GetChildren()[math.random(1, #tiles:GetChildren())]
			end
			break
		end
		
		playAnimation(enemyPokemon, animations[randomPokemon.."Idle"])
	end
	
	local function setItemAmount(item)
		local itemsIndex = require(clientModulesFolder:WaitForChild("Items"))
		return math.random(1, itemsIndex.Index[item])
	end

	for i = 1,10 do
		local itemTile = tiles:GetChildren()[math.random(1,#tiles:GetChildren())]
		local randomItem = DungeonModule.Index[self].ItemsPossible[math.random(1,#DungeonModule.Index[self].ItemsPossible)]
		local itemModel = itemModelsFolder:WaitForChild(randomItem):Clone()

		for i, itemData in pairs(itemModel:GetChildren()) do
			if itemData:IsA("MeshPart") then
				itemData.CanCollide = false
				itemData.CanTouch = false
				itemData.CanQuery = false
			end
		end

		itemModel.Parent = itemTile
		itemModel.PrimaryPart.CFrame = itemTile.CFrame
		itemTile:SetAttribute("occupied", true)
		itemTile:SetAttribute("occupiedBy", randomItem)
		itemTile:SetAttribute("itemAmount", setItemAmount(randomItem))
	end
	
	camera.CameraType = Enum.CameraType.Scriptable
	camera.CFrame = CFrame.new(playerPokemon.PrimaryPart.Position + Vector3.new(0, 20, 10), playerPokemon.PrimaryPart.Position)
	
	task.wait(1)
	task.spawn(function()
		tween(background, {BackgroundTransparency = 1}, 2)
		task.wait(2)
		pcall(function()
			background:Remove()
			topText:Remove()
			bottomText:Remove()
		end)
	end)
	
	local function inputValid(key, keys)
		for _, v in pairs(keys) do
			if key == v then
				return true
			end 
		end
		return false 
	end
	
	--[Input System]
	local function startInputs()
		local validKeys = {"W", "A", "S", "D"}
		local connection = userInputService.InputBegan:Connect(function(input)
			if DungeonModule.InputsEnabled then
				local key = input.KeyCode.Name
				if inputValid(key, validKeys) then
					local distanceTable = {
						W = Vector3.new(0, 0, -7),
						A = Vector3.new(-7, 0, 0),
						S = Vector3.new(0, 0, 7),
						D = Vector3.new(7, 0, 0),
					}
					
					local rotationTable = {
						W = 0,
						A = 90,
						S = 180,
						D = -90,
					}
					
					if workspace:FindFirstChild("Start") then
						workspace:WaitForChild("Start"):Remove()
						workspace:WaitForChild("Goal"):Remove()
					end
					
					local goal
					for i, tile in pairs(tiles:GetChildren()) do
						local primaryPart = playerPokemon.PrimaryPart
						print(primaryPart.Position)
						print(tile.Position)
						print()
						print(distanceTable[key])
						print(key)
						print()
						print(tile:GetAttribute("occupiedBy"))
						if tile.Position == primaryPart.Position + distanceTable[key] and tile:GetAttribute("occupiedBy") ~= "pokemon" then
							print(tile.Parent)
							goal = createGoalTile(tile)
							print(goal.Parent)
							
							tween(primaryPart, {CFrame = tile.CFrame * CFrame.Angles(0, math.rad(rotationTable[key]), 0)}, 0.25, nil, nil, true, function()
								for i, tileLookAt in pairs(tiles:GetChildren()) do
									if tileLookAt.Position == primaryPart.Position + distanceTable[key] then
										playerPokemon:PivotTo(CFrame.lookAt(primaryPart.Position, tileLookAt.CFrame.Position))
									end
								end
							end)
							
							primaryPart.CFrame = CFrame.lookAt(primaryPart.Position, tile.CFrame.Position)
							primaryPart:GetPropertyChangedSignal("Position"):Connect(function()
								camera.CFrame = CFrame.new(playerPokemon.PrimaryPart.Position + Vector3.new(0, 20, 10), playerPokemon.PrimaryPart.Position)
							end)
							
							if tile:GetAttribute("occupied") and tile:GetAttribute("occupiedBy") ~= "pokemon" then
								playerData.AddItemToBag(tile:GetAttribute("occupiedBy"), tile:GetAttribute("itemAmount"))
								pickUpItem(playerData.PlayerName, tile:GetAttribute("itemAmount"), tile:GetAttribute("occupiedBy"))
								utilities.PlaySound(require(assetsFolder:WaitForChild("Audio")).PickUpItem)
								tile:SetAttribute("itemAmount", nil)
								tile:WaitForChild(tile:GetAttribute("occupiedBy")):Remove()
								tile:SetAttribute("occupiedBy", "pokemon")
							end
							
						elseif tile.Position == primaryPart.Position + distanceTable[key] and tile:GetAttribute("occupied") and tile:GetAttribute("occupiedBy") == "pokemon" then
							utilities.PlaySound(require(assetsFolder:WaitForChild("Audio")).Boing)
						end
						
						task.wait() --Buffer
						for i, enemy in pairs(pokemonFolder:GetChildren()) do
							if enemy.Name ~= "Player" then
								local start, enemyPart
								
								pcall(function()
									enemyPart = enemy.PrimaryPart
									start = enemyPart:Clone()
									start.Parent = workspace
									start.Name = "Start"
									local startNode = Instance.new("IntValue", start)
									startNode.Name = "G"
									for i, data in pairs(start:GetChildren()) do
										if not data:IsA("IntValue") then
											data:Remove()
										end
									end
								end)
								
								local path = DungeonModule:CreatePath(start, goal)
								local function Magnitude(p)
									return math.sqrt(p.X^2 + p.Y^2 + p.Z^2)
								end
								
								local function GetNextNode()
									local currentDistance = math.huge
									local currentObject
									for i,v in pairs(path) do
										if not v:IsA("BasePart") then continue end
										local Distance = Magnitude(enemyPart.Position - v.Position)
										if Distance <= currentDistance then 
											currentDistance = Distance
											currentObject = v
										end
									end
									return currentObject
								end
								
								local nextNode = GetNextNode()
								for i, tileNode in pairs(tiles:GetChildren()) do
									if tileNode.Position == nextNode.Position and tileNode:GetAttribute("occupiedBy") ~= "pokemon" then
										tween(enemyPart, {CFrame = tileNode.CFrame})
										if tileNode:GetAttribute("occupied") and tileNode:GetAttribute("occupiedBy") ~= "pokemon" then
											pickUpItem(enemy.Name, tileNode:GetAttribute("itemAmount"), tileNode:GetAttribute("occupiedBy"))
											tileNode:SetAttribute("itemAmount", nil)
											tileNode:WaitForChild(tileNode:GetAttribute("occupiedBy")):Remove()
											tileNode:SetAttribute("occupiedBy", "pokemon")
										end
									end
								end
							end
						end
						
						if tile:GetAttribute("occupiedBy") == "pokemon" then
							tile:SetAttribute("occupiedBy", "")
							tile:SetAttribute("occupied", false)
						end
					end
					
					task.wait(0.251) --damn so precise
					for i, tile in pairs(tiles:GetChildren()) do
						for i, pokemon in pairs(pokemonFolder:GetChildren()) do
							if tile.Position == pokemon.PrimaryPart.Position then
								tile:SetAttribute("occupiedBy", "pokemon")
								tile:SetAttribute("occupied", true)
							end
						end
					end
				else
					return
				end
			end
		end)
		return connection 
	end
	
	dungeonGui:Enable(self, (level.."F"), team)
	DungeonModule.InputsEnabled = true
	local inputs = startInputs()
	local finishedFloor = signal:wait()
	inputs:Disconnect()
	dungeonGui:Disable()
	if utilities.ScreenUtilities.fadeObject.BackgroundTransparency ~= 0 then
		utilities.ScreenUtilities.FadeScreenIn(2, Color3.new(0, 0, 0))
	end	
	utilities.ScreenUtilities.RemoveScreen()
	return finishedFloor
end

--[Global Dungeon Init Function]
function DungeonModule:DoDungeon()
	task.spawn(function()
		guiModule:Disable()
	end)
	if utilities.ScreenUtilities.fadeObject.BackgroundTransparency ~= 0 then
		utilities.ScreenUtilities.FadeScreenIn(2, Color3.new(0, 0, 0))
	end	
	local won = true
	utilities.ScreenUtilities.RemoveScreen()
	for i = 1, self.Floors do
		local success = DungeonModule.Floor(self.Name, i, self.Team)
		if not success then
			won = false
			break
		end
	end
	if won then
		print("Dungeon Won")
	else
		print("Dungeon Lost")
	end
	return won
end

--[[
bro you've done so much am sorry i havent been on much am grinding my 2nd region
in my pbb i swear when its done ill grind umd and i mean it dawg.
if i dont just Dm me every day about it i gotchu

Bro you don't even gotta worry about it man, I totally understand. Absolutely no pressure and no rush man
]]

return DungeonModule

(I am aware that roblox does not like pokemon, but this is not going to be released, atleast I don’t plan on releasing this ever. This is simply a passion project that serves to better my programming knowledge.)

Okay wait I found something weird.
I commented

for i, enemy in pairs(pokemonFolder:GetChildren()) do
							if enemy.Name ~= "Player" then
								local start, enemyPart
								
								pcall(function()
									enemyPart = enemy.PrimaryPart
									start = enemyPart:Clone()
									start.Parent = workspace
									start.Name = "Start"
									local startNode = Instance.new("IntValue", start)
									startNode.Name = "G"
									for i, data in pairs(start:GetChildren()) do
										if not data:IsA("IntValue") then
											data:Remove()
										end
									end
								end)
								
								local path = DungeonModule:CreatePath(start, goal)
								local function Magnitude(p)
									return math.sqrt(p.X^2 + p.Y^2 + p.Z^2)
								end
								
								local function GetNextNode()
									local currentDistance = math.huge
									local currentObject
									for i,v in pairs(path) do
										if not v:IsA("BasePart") then continue end
										local Distance = Magnitude(enemyPart.Position - v.Position)
										if Distance <= currentDistance then 
											currentDistance = Distance
											currentObject = v
										end
									end
									return currentObject
								end
								
								local nextNode = GetNextNode()
								for i, tileNode in pairs(tiles:GetChildren()) do
									if tileNode.Position == nextNode.Position and tileNode:GetAttribute("occupiedBy") ~= "pokemon" then
										tween(enemyPart, {CFrame = tileNode.CFrame})
										if tileNode:GetAttribute("occupied") and tileNode:GetAttribute("occupiedBy") ~= "pokemon" then
											pickUpItem(enemy.Name, tileNode:GetAttribute("itemAmount"), tileNode:GetAttribute("occupiedBy"))
											tileNode:SetAttribute("itemAmount", nil)
											tileNode:WaitForChild(tileNode:GetAttribute("occupiedBy")):Remove()
											tileNode:SetAttribute("occupiedBy", "pokemon")
										end
									end
								end
							end
						end
						
						if tile:GetAttribute("occupiedBy") == "pokemon" then
							tile:SetAttribute("occupiedBy", "")
							tile:SetAttribute("occupied", false)
						end

and now the tile is creating and the player is moving perfectly
image
So now I know it’s NOT

if tile.Position == primaryPart.Position + distanceTable[key] and tile:GetAttribute("occupiedBy") ~= "pokemon" then

and something in this chunk is messing with the script.

1 Like

Could I get some help with this? I can’t pinpoint why this isn’t working.