Calling a function from inside a function results in calling a nil value

So when i try to call a function from inside a function in this module script, it results in calling a nil value for seemingly no reason.

local secret = {}

local BadgeService = game:GetService("BadgeService")
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")

local secretsFolder = game:GetService("ServerScriptService"):WaitForChild("Secrets")
local stats = require(secretsFolder.SecretStats)

local highlight = secretsFolder.Assets:WaitForChild("UnlockHighlight")
local highlightTweenInfo = TweenInfo.new(1)

local buildSound = workspace.Music:WaitForChild("BuildingSound")
local finishSound = workspace.Music:WaitForChild("FinishSound")

local secrets = {}

function secret.Structure(structure, skipAnimation)
	
	buildSound.TimePosition = 1
	buildSound:Play()
	
	local order = secret.OrderStructure(structure)

	local model = structure:Clone()
	print(structure)
	for i, obj in model:GetDescendants() do if obj:IsA("BasePart") then obj:Destroy() end end
	model.Parent = workspace:WaitForChild("Structures")

	local debugTimes = {}
	
	for i, obj in order do
		
		local timev = i^0.15
		if #order - i <= 10 then
			timev *= (10-(#order - i))^0.3
			if i == #order then
				timev *= 1.2
			end
		end
		
		task.wait(timev/#order) --timev = (1+i^2)^0.1\
		table.insert(debugTimes, timev/#order)
		
		local parent = obj.Parent.Name
		
		obj.Parent = workspace.Structures:FindFirstChild(parent, true)
		
	end
	
	buildSound:Stop()
	
	finishSound.TimePosition = 2.5
	finishSound:Play()
	
	local newHighlight = highlight:Clone()
	newHighlight.Parent = model
	
	local highlightTween = TweenService:Create(newHighlight, highlightTweenInfo, {FillTransparency = 1})
	highlightTween:Play()
	
	task.wait(1)
	
	newHighlight:Destroy()
	
	print(debugTimes)
	
end

function secret.OrderStructure(structure)

	local objects = {}

	local order = {}

	for i, obj in structure:GetDescendants() do
		if obj:IsA("BasePart") then
			table.insert(objects, obj)
		end
	end

	for i=1, #objects do
		local lowestPart = objects[1]

		for i, obj in objects do
			if obj.Position.Y < lowestPart.Position.Y then
				lowestPart = obj
			end
		end

		table.insert(order, lowestPart)
		table.remove(objects, table.find(objects, lowestPart))
	end
	print("Order", order)

	return order
end

function secret.AwardBadge(player, badgeId)
	-- Fetch badge information
	local success, badgeInfo = pcall(function()
		return BadgeService:GetBadgeInfoAsync(badgeId)
	end)

	if success then
		-- Confirm that badge can be awarded
		if badgeInfo.IsEnabled then
			-- Award badge
			local awardSuccess, result = pcall(function()
				return BadgeService:AwardBadge(player.UserId, badgeId)
			end)

			if not awardSuccess then
				warn("Error while awarding badge:", result)
			elseif not result then
				warn("Failed to award badge.")
			end
		end
	else
		warn("Error while fetching badge info: " .. badgeInfo)
	end
end

function secret.Load(secret)
	local foundSecret = table.find(secrets, secret)
	if foundSecret == nil then return end

	table.insert(secrets, secret)

	secret.Structure(stats[secret].Structure, true)
end

function secret.Award(secret, player)
	local badgeID = stats[secret].BadgeID
	print(badgeID)
	secret.AwardBadge(player, badgeID)

	secret.Structure(stats[secret])
end


return secret

Any help? Thanks.

function secret.Structure(structure, skipAnimation)
    local order = secret.OrderStructure(structure)

if secret.OrderStructure hasn’t been defined yet at this point in the module, secret.OrderStructure is nil..

If that is the issue this should fix that:

ModuleScript
--ModuleScript in ???
local secret = {}

local BadgeService = game:GetService("BadgeService")
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")

local secretsFolder = game:GetService("ServerScriptService"):WaitForChild("Secrets")
local stats = require(secretsFolder.SecretStats)

local highlight = secretsFolder.Assets:WaitForChild("UnlockHighlight")
local highlightTweenInfo = TweenInfo.new(1)

local buildSound = workspace.Music:WaitForChild("BuildingSound")
local finishSound = workspace.Music:WaitForChild("FinishSound")

local secrets = {}

function secret.OrderStructure(structure)
	local order = {}
	for _, obj in pairs(structure:GetDescendants()) do
		if obj:IsA("BasePart") then
			table.insert(order, obj)
		end
	end
	return order
end

function secret.Structure(structure, skipAnimation)
	buildSound.TimePosition = 1
	buildSound:Play()
	
	local order = secret.OrderStructure(structure)

	local model = structure:Clone()
	local parentMap = {}
	for _, obj in pairs(model:GetDescendants()) do
		if obj:IsA("BasePart") then
			parentMap[obj] = obj.Parent
			obj:Destroy()
		end
	end
	model.Parent = workspace:WaitForChild("Structures")

	local debugTimes = {}
	for i, obj in pairs(order) do
		local timev = i^0.15
		if #order - i <= 10 then
			timev *= (10-(#order - i))^0.3
			if i == #order then
				timev *= 1.2
			end
		end
		
		task.wait(timev/#order)
		table.insert(debugTimes, timev/#order)
		
		local parentName = parentMap[obj] and parentMap[obj].Name
		if parentName then
			local parentInstance = workspace.Structures:FindFirstChild(parentName, true)
			if parentInstance then
				obj.Parent = parentInstance
			end
		end
	end
	
	buildSound:Stop()
	finishSound:Play()
end

return secret

Sorry, should have specified. This is occuring in secret.AwardBadge(), where it is already defined. This is why im confused. Thank you though, ill fix that too.

Would you please post the exact error message and line number you’re encountering? I suspect the error message might actually be “Function called with a nil value” or “Attempt to index nil”, not “Attempt to call a nil value”. If my suspicion is correct, then check for cases where player or badgeId could be nil; you’d have to look at the code where you’re calling secret.AwardBadge.

For example, I see you added a print(BadgeID) in the secret.Award function that calls secret.AwardBadge. Is that the only place secret.AwardBadge is called? And if so, does it ever print nil (or print an empty line)? Have you verified player always exists?

Also, you don’t need to worry about secret.OrderStructure not being defined in secret.Structure() because that function will only be called after the modulescript is required, and all the functions initialize in order (without running the function contents) when it’s required. So this quoted text is not actually a problem in your code.

He said it’s coming back nil. I’m assuming it isn’t set up right.

function secret.Award(secret, player)
	local badgeID = stats[secret].BadgeID
	print(badgeID)
	secret.AwardBadge(player, badgeID)

	secret.Structure(stats[secret])
end

You are overwriting the variable secret with the parameter secret inside the function scope, hence secret.AwardBadge is nil

1 Like

I don’t understand, how/when am i overwriting the variable?

secret.Award is the only place secret.AwardBadge is called, but i have made it a function so that if necessary i can simply call secret.AwardBadge. The badgeID prints fine. This is the exact error:

ServerScriptService.Secrets.Modules.SecretAwarder:136: attempt to call a nil value


The parameter secret seems to be some sort of id. Just rename parameter secret and and change it at the appropriate places.

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