"attempt to call a nil value" with a ModuleScript

For an obvious reason, I kept on getting an “attempt to call a nil value” for a tile-matching game that I’m working on right now.

Here’s the script:

local findTiles = require(game.ReplicatedStorage.ModuleScripts.FindTiles)

function Detect()
	for _, tile in script.Parent.Parent.Tiles:GetChildren() do
		for _, Attachment in tile:GetChildren() do
			if Attachment.Name:find("DetectorTop") then
				local target = findTiles.LookForAdjacents(Attachment.WorldPosition)
				if target ~= nil then
					local CountedBy = Instance.new("ObjectValue",target.Parent.AdjacentsAndStackers)
					CountedBy.Name = "StackedOnTopOf"..tile.Name..tile:GetAttribute("TileNumber")
					CountedBy.Value = tile
					local Blocker = Instance.new("ObjectValue")
					Blocker.Name = "StackingTile"
					Blocker.Value = target.Parent
					local RemoveIfCleared = script.Script:clone()
					RemoveIfCleared.Disabled = false
					RemoveIfCleared.Parent = Blocker
					local Cleared = Instance.new("BoolValue",RemoveIfCleared)
					Cleared.Name = "Cleared"
					Blocker.Parent = tile.Mechanics.StackingTiles
				end
			elseif Attachment.Name:find("DetectorLeft") then
				if script.Parent.GamemodeRules.BlockTilesOnLeftAndRight.Value == true then
					local target = findTiles.LookForAdjacents(Attachment.WorldPosition)
					if target ~= nil then
						local CountedBy = Instance.new("ObjectValue",target.Parent.AdjacentsAndStackers)
						CountedBy.Name = "ToTheLeftOf"..tile.Name..tile:GetAttribute("TileNumber")
						CountedBy.Value = tile
						local Blocker = Instance.new("ObjectValue")
						Blocker.Name = "LeftAdjacentTile"
						Blocker.Value = target.Parent
						local RemoveIfCleared = script.Script:clone()
						RemoveIfCleared.Disabled = false
						RemoveIfCleared.Parent = Blocker
						local Cleared = Instance.new("BoolValue",RemoveIfCleared)
						Cleared.Name = "Cleared"
						Blocker.Parent = tile.Mechanics.LeftAdjacentTiles
					end
				end
			elseif Attachment.Name:find("DetectorRight") then
				if script.Parent.GamemodeRules.BlockTilesOnLeftAndRight.Value == true then
					local target = findTiles.LookForAdjacents(Attachment.WorldPosition)
					if target ~= nil then
					local CountedBy = Instance.new("ObjectValue",target.Parent.AdjacentsAndStackers)
					CountedBy.Name = "ToTheRightOf"..tile.Name..tile:GetAttribute("TileNumber")
					CountedBy.Value = tile
					local Blocker = Instance.new("ObjectValue")
					Blocker.Name = "RightAdjacentTile"
					Blocker.Value = target.Parent
					local RemoveIfCleared = script.Script:clone()
					RemoveIfCleared.Disabled = false
					RemoveIfCleared.Parent = Blocker
					local Cleared = Instance.new("BoolValue",RemoveIfCleared)
					Cleared.Name = "Cleared"
					Blocker.Parent = tile.Mechanics.RightAdjacentTiles
				end
			end
		elseif Attachment.Name:find("DetectorFront") then
			if script.Parent.GamemodeRules.BlockTilesOnFrontAndBack.Value == true then
				local target = findTiles.LookForAdjacents(Attachment.WorldPosition)
				if target ~= nil then
					local CountedBy = Instance.new("ObjectValue",target.Parent.AdjacentsAndStackers)
					CountedBy.Name = "Behind"..tile.Name..tile:GetAttribute("TileNumber")
					CountedBy.Value = tile
					local Blocker = Instance.new("ObjectValue")
					Blocker.Name = "FrontAdjacentTile"
					Blocker.Value = target.Parent
					local RemoveIfCleared = script.Script:clone()
					RemoveIfCleared.Disabled = false
					RemoveIfCleared.Parent = Blocker
					local Cleared = Instance.new("BoolValue",RemoveIfCleared)
					Cleared.Name = "Cleared"
					Blocker.Parent = tile.Mechanics.FrontAdjacentTiles
				end
			end
		elseif Attachment.Name:find("DetectorBack") then
			if script.Parent.GamemodeRules.BlockTilesOnFrontAndBack.Value == true then
				local target = findTiles.LookForAdjacents(Attachment.WorldPosition)
				if target ~= nil then
					local CountedBy = Instance.new("ObjectValue",target.Parent.AdjacentsAndStackers)
					CountedBy.Name = "InFrontOf"..tile.Name..tile:GetAttribute("TileNumber")
					CountedBy.Value = tile
					local Blocker = Instance.new("ObjectValue")
					Blocker.Name = "BackAdjacentTile"
					Blocker.Value = target.Parent
					local RemoveIfCleared = script.Script:clone()
					RemoveIfCleared.Disabled = false
					RemoveIfCleared.Parent = Blocker
					local Cleared = Instance.new("BoolValue",RemoveIfCleared)
					Cleared.Name = "Cleared"
					Blocker.Parent = tile.Mechanics.BackAdjacentTiles
					end
				end
			end
		end
		tile.Mechanics.DetectAdjacentsAndStackers.Detect:Fire()
		tile:SetAttribute("IsLoaded",true)
		tile.Mechanics.Owner.Value.Mechanics.TilesLoaded.Value = tile.Owner.Value.Mechanics.TilesLoaded.Value + 1
		tile.SelectScript.Disabled = false
		tile.Mechanics.FindPairs.Event:Fire()
	end
end

script.Event.Event:connect(Detect)

And here’s the module script the script above is requiring:

local LookForAdjacents = {}

function LookForAdjacents.Init(pos)
	local list = script.Parent.Mechanics.Owner.Value.Tiles:children()
	local tile = nil
	local dist = .5
	local temp = nil
	local temp2 = nil
	for x = 1, #list do
		temp2 = list[x]
		if (temp2.Name:find("Tile")) and (temp2 ~= script.Parent) then
			temp = temp2:FindFirstChild("RootAttachment")
			if (temp ~= nil) and (temp.WorldPosition - pos).magnitude < dist then
				tile = temp
				dist = (temp.WorldPosition - pos).magnitude
			end
		end
	end
	return tile
end

return LookForAdjacents

No matter how much I change it to GetChildren() or children(), or even keep changing the LookForAdjacents() to LookForAdjacents.Init() all I kept getting is this:

16:09:45.676  Workspace.Mahjong.Mechanics.DetectEachTile:24: attempt to call a nil value  -  Server - DetectEachTile:24

If anyone can find a solution for this, please help me as possible. Thanks.

your sure this value exist

if script.Parent.GamemodeRules.BlockTilesOnLeftAndRight.Value == true then

That’s not the issue I’m talking about.
I’m talking about how to solve the issue with the ModuleScript that’s being ran by the Script, but keep getting this “attempt to call a nil value” error no matter how much I try to change it.

the error is actually from the module script?

It’s actually from this:

16:09:45.676  Workspace.Mahjong.Mechanics.DetectEachTile:24: attempt to call a nil value  -  Server - DetectEachTile:24

it should be findTiles.Init() not findTiles.LookForAdjacents()
and :GetChildren()

Also put some prints in there so you know where it is getting to right before the error

if its in the module script seems this maybe the issue
script.Parent.Mechanics.Owner.Value
its probably not set to anything as i am guessing its a object value the way you are trying to get a folder under it

I tried, but all I got was:

16:28:38.650  Workspace.Mahjong.Mechanics.DetectEachTile:24: attempt to index nil with 'Init'  -  Server - DetectEachTile:24

Regardless if I use children() or GetChildren(), it still gives me the same error.

sorry it should be findTiles.Init() not findTiles.LookForAdjacents.Init() as the LookForAdjacents is just the module scripts maintable of functions

you will need to change it in all the other statements too

I’ve done that, but I got this again:
16:37:53.460 Workspace.Mahjong.Mechanics.DetectEachTile:24: attempt to call a nil value - Server - DetectEachTile:24

Anyone else who has good programming skills skilled enough to find the best solution for this? Thanks!

There’s no way the script’s in the ModuleScript itself. I’ve put in ReplicatedStorage under ModuleScripts (which itself is a folder)

try findTiles.Init() instead of the findTiles.LookForAdjacents()

Can you show me the exact line where the error is taking place?
The code not the error

I’ve already done that and it gave me this error again:
16:37:53.460 Workspace.Mahjong.Mechanics.DetectEachTile:24: attempt to call a nil value - Server - DetectEachTile:24

Right here:


I’m still an amateur at scripting, so is there the best solution for this?

Are you sure you’re using the correct ModuleScript? The one you’re supposed to use returns the table named “LookForAdjacents”, yet the one you’re requiring has the name “FindTiles”

1 Like

yeah its like your .Init() function isn’t in that module script you are requiring

Well, even I change them to these:

local findTiles = require(game.ReplicatedStorage.ModuleScripts.FindTiles)

function Detect()
	for _, tile in script.Parent.Parent.Tiles:GetChildren() do
		for _, Attachment in tile:GetChildren() do
			if Attachment.Name:find("DetectorTop") then
				local target = findTiles.LookForAdjacents(Attachment.WorldPosition)
				if target ~= nil then
					local CountedBy = Instance.new("ObjectValue",target.Parent.AdjacentsAndStackers)
					CountedBy.Name = "StackedOnTopOf"..tile.Name..tile:GetAttribute("TileNumber")
					CountedBy.Value = tile
					local Blocker = Instance.new("ObjectValue")
					Blocker.Name = "StackingTile"
					Blocker.Value = target.Parent
					local RemoveIfCleared = script.Script:clone()
					RemoveIfCleared.Disabled = false
					RemoveIfCleared.Parent = Blocker
					local Cleared = Instance.new("BoolValue",RemoveIfCleared)
					Cleared.Name = "Cleared"
					Blocker.Parent = tile.Mechanics.StackingTiles
				end
			elseif Attachment.Name:find("DetectorLeft") then
				if script.Parent.GamemodeRules.BlockTilesOnLeftAndRight.Value == true then
					local target = findTiles.LookForAdjacents(Attachment.WorldPosition)
					if target ~= nil then
						local CountedBy = Instance.new("ObjectValue",target.Parent.AdjacentsAndStackers)
						CountedBy.Name = "ToTheLeftOf"..tile.Name..tile:GetAttribute("TileNumber")
						CountedBy.Value = tile
						local Blocker = Instance.new("ObjectValue")
						Blocker.Name = "LeftAdjacentTile"
						Blocker.Value = target.Parent
						local RemoveIfCleared = script.Script:clone()
						RemoveIfCleared.Disabled = false
						RemoveIfCleared.Parent = Blocker
						local Cleared = Instance.new("BoolValue",RemoveIfCleared)
						Cleared.Name = "Cleared"
						Blocker.Parent = tile.Mechanics.LeftAdjacentTiles
					end
				end
			elseif Attachment.Name:find("DetectorRight") then
				if script.Parent.GamemodeRules.BlockTilesOnLeftAndRight.Value == true then
					local target = findTiles.LookForAdjacents(Attachment.WorldPosition)
					if target ~= nil then
					local CountedBy = Instance.new("ObjectValue",target.Parent.AdjacentsAndStackers)
					CountedBy.Name = "ToTheRightOf"..tile.Name..tile:GetAttribute("TileNumber")
					CountedBy.Value = tile
					local Blocker = Instance.new("ObjectValue")
					Blocker.Name = "RightAdjacentTile"
					Blocker.Value = target.Parent
					local RemoveIfCleared = script.Script:clone()
					RemoveIfCleared.Disabled = false
					RemoveIfCleared.Parent = Blocker
					local Cleared = Instance.new("BoolValue",RemoveIfCleared)
					Cleared.Name = "Cleared"
					Blocker.Parent = tile.Mechanics.RightAdjacentTiles
				end
			end
		elseif Attachment.Name:find("DetectorFront") then
			if script.Parent.GamemodeRules.BlockTilesOnFrontAndBack.Value == true then
				local target = findTiles.LookForAdjacents(Attachment.WorldPosition)
				if target ~= nil then
					local CountedBy = Instance.new("ObjectValue",target.Parent.AdjacentsAndStackers)
					CountedBy.Name = "Behind"..tile.Name..tile:GetAttribute("TileNumber")
					CountedBy.Value = tile
					local Blocker = Instance.new("ObjectValue")
					Blocker.Name = "FrontAdjacentTile"
					Blocker.Value = target.Parent
					local RemoveIfCleared = script.Script:clone()
					RemoveIfCleared.Disabled = false
					RemoveIfCleared.Parent = Blocker
					local Cleared = Instance.new("BoolValue",RemoveIfCleared)
					Cleared.Name = "Cleared"
					Blocker.Parent = tile.Mechanics.FrontAdjacentTiles
				end
			end
		elseif Attachment.Name:find("DetectorBack") then
			if script.Parent.GamemodeRules.BlockTilesOnFrontAndBack.Value == true then
				local target = findTiles.LookForAdjacents(Attachment.WorldPosition)
				if target ~= nil then
					local CountedBy = Instance.new("ObjectValue",target.Parent.AdjacentsAndStackers)
					CountedBy.Name = "InFrontOf"..tile.Name..tile:GetAttribute("TileNumber")
					CountedBy.Value = tile
					local Blocker = Instance.new("ObjectValue")
					Blocker.Name = "BackAdjacentTile"
					Blocker.Value = target.Parent
					local RemoveIfCleared = script.Script:clone()
					RemoveIfCleared.Disabled = false
					RemoveIfCleared.Parent = Blocker
					local Cleared = Instance.new("BoolValue",RemoveIfCleared)
					Cleared.Name = "Cleared"
					Blocker.Parent = tile.Mechanics.BackAdjacentTiles
					end
				end
			end
		end
		tile.Mechanics.DetectAdjacentsAndStackers.Detect:Fire()
		tile:SetAttribute("IsLoaded",true)
		tile.Mechanics.Owner.Value.Mechanics.TilesLoaded.Value = tile.Owner.Value.Mechanics.TilesLoaded.Value + 1
		tile.SelectScript.Disabled = false
		tile.Mechanics.FindPairs.Event:Fire()
	end
end

script.Event.Event:connect(Detect)
local module = {}

function LookForAdjacents(pos)
	local list = script.Parent.Mechanics.Owner.Value.Tiles:GetChildren()
	local tile = nil
	local dist = .5
	local temp = nil
	local temp2 = nil
	for x = 1, #list do
		temp2 = list[x]
		if (temp2.Name:find("Tile")) and (temp2 ~= script.Parent) then
			temp = temp2:FindFirstChild("RootAttachment")
			if (temp ~= nil) and (temp.WorldPosition - pos).magnitude < dist then
				tile = temp
				dist = (temp.WorldPosition - pos).magnitude
			end
		end
	end
	return tile
end

return module

I still keep getting that “attempt to call a nil value” error.

if you have the require on the right module script setup etc when you type findTiles. then the Init function should popup and be selectable showing its able to reference to it

the way you have it now try function module.LookForAdjacents(pos) in the module script

a6f956803ef276c37949219a7241e88a