Whats the problem here?

So i have a game loop and it includes functions to keep it organized. Here is the script:

local Players = game:GetService("Players")

local ROUND_DURATION = 15
local INTERMISSION_DURATION = 10
local MIN_PLAYERS = 1

local function getSpawnLocation(class)
	local allSpawns = workspace.Map.Spawns[class]:GetChildren()
	local random = Random.new()
	return allSpawns[random:NextInteger(1, #allSpawns)].CFrame
end

local function SpawnZombie(player)
	local zombie = script.Zombie:Clone()
	player.Character = zombie
	zombie:PivotTo(getSpawnLocation("Zombie"))
	zombie.Parent = workspace
	
	player:SetAttribute("isZombie", true)
end


local function Intermission()
	while #Players:GetPlayers() < MIN_PLAYERS do
		print("Waiting For Players...")
		task.wait(1)
	end

	for i = INTERMISSION_DURATION, 1, -1 do
		print("Intermission:", i)
		task.wait(1)
	end

	if #Players:GetPlayers() >= MIN_PLAYERS then
		StartGame()
	else
		Intermission()
	end
end


local function EndGame()
	workspace:SetAttribute("gameRunning", false)

	for i, player in pairs(Players:GetPlayers()) do

		player:SetAttribute("isSurvivor", false)
		player:SetAttribute("isZombie", false)
		player:LoadCharacter()

		player.Backpack:ClearAllChildren()
	end
	Intermission()
end

local function StartGame()
	workspace:SetAttribute("gameRunning", true)
	
	local allPlayers = Players:GetPlayers()
	local random = Random.new()
	local randomPlayer = allPlayers[random:NextInteger(1, #allPlayers)]
	SpawnZombie(randomPlayer)
	
	for i, player in pairs(allPlayers) do
		if player:GetAttribute("isZombie") == true then continue end
		
		player:SetAttribute("isSurvivor", true)
		player.Character:PivotTo(getSpawnLocation("Survivor"))
		
		for i, weapon in pairs(script.Weapons:GetChildren()) do
			weapon:Clone().Parent = player.Backpack
		end
	end
	
	for i = ROUND_DURATION, 1, -1 do
		print("Game:", i)
		task.wait(1)
	end
	
	EndGame()
end

Intermission()

and this is the error:

ServerScriptService.GameLoop:35: attempt to call a nil value

I understand that start game function needs to be on top of the other function but that messes up the other function so how can I solve this?

1 Like

I’m pretty sure you need to define the function StartGame earlier in the script than you call it. Can fix this by moving the Intermission function after the StartGame function.

Edit: I take that back. You can just put all of the functions into a table.

local functions = {}

local Players = game:GetService("Players")

local ROUND_DURATION = 15
local INTERMISSION_DURATION = 10
local MIN_PLAYERS = 1

function functions.getSpawnLocation(class)
	local allSpawns = workspace.Map.Spawns[class]:GetChildren()
	local random = Random.new()
	return allSpawns[random:NextInteger(1, #allSpawns)].CFrame
end

function functions.SpawnZombie(player)
	local zombie = script.Zombie:Clone()
	player.Character = zombie
	zombie:PivotTo(getSpawnLocation("Zombie"))
	zombie.Parent = workspace
	
	player:SetAttribute("isZombie", true)
end


function functions.Intermission()
	while #Players:GetPlayers() < MIN_PLAYERS do
		print("Waiting For Players...")
		task.wait(1)
	end

	for i = INTERMISSION_DURATION, 1, -1 do
		print("Intermission:", i)
		task.wait(1)
	end

	if #Players:GetPlayers() >= MIN_PLAYERS then
		functions.StartGame()
	else
		functions.Intermission()
	end
end


function functions.EndGame()
	workspace:SetAttribute("gameRunning", false)

	for i, player in pairs(Players:GetPlayers()) do

		player:SetAttribute("isSurvivor", false)
		player:SetAttribute("isZombie", false)
		player:LoadCharacter()

		player.Backpack:ClearAllChildren()
	end
	functions.Intermission()
end

function functions.StartGame()
	workspace:SetAttribute("gameRunning", true)
	
	local allPlayers = Players:GetPlayers()
	local random = Random.new()
	local randomPlayer = allPlayers[random:NextInteger(1, #allPlayers)]
	functions.SpawnZombie(randomPlayer)
	
	for i, player in pairs(allPlayers) do
		if player:GetAttribute("isZombie") == true then continue end
		
		player:SetAttribute("isSurvivor", true)
		player.Character:PivotTo(functions.getSpawnLocation("Survivor"))
		
		for i, weapon in pairs(script.Weapons:GetChildren()) do
			weapon:Clone().Parent = player.Backpack
		end
	end
	
	for i = ROUND_DURATION, 1, -1 do
		print("Game:", i)
		task.wait(1)
	end
	
	functions.EndGame()
end

functions.Intermission()
2 Likes

alr will try that out in a bit! Will let you know if it works.

yep, that worked perfectly! Learned something new today, Thanks!

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