Strange Scripting Issue - Please help!

:wave: Hello,
I’m working on a Minigame experience, and I’ve run into a strange issue.

Basically, there is a script named ‘MinigameHandler’ with a ModuleScript as a child with the name of ‘Obby’. The ModuleScript also has an IntValue below it named ‘PlrCount’. The MinigameHandler is located in a Folder inside of ServerScriptService.

image

Alright so with that out of the way…

Here’s the ‘MinigameHandler’ Script:

local Remotes = game.ReplicatedStorage.Remotes
local GameStorage = workspace.GameStorage
local ServerStorage = game:GetService("ServerStorage")

IntermissionTime = 6 -- // Intermission time (in seconds)
RequiredPlayers = 1 -- // Players required to start
LobbyPosition = workspace.Lobby.SpawnLocation.CFrame

Gamemodes = {}
for _,v in pairs(script:GetChildren()) do
	table.insert(Gamemodes, v.Name)
end

function newRound()
	local CurrentIntermissionTime = tonumber(IntermissionTime)
	repeat wait(1)
		CurrentIntermissionTime = tonumber(CurrentIntermissionTime)-1
		Remotes.UISendInfo:FireAllClients("Intermission: "..CurrentIntermissionTime)
	until tonumber(CurrentIntermissionTime) == 0

	local Gamemode = Gamemodes[math.random(1,#Gamemodes)]
	game.ReplicatedStorage.GameInSession.Value = true

	local MapStorage = ServerStorage.Maps[Gamemode]:GetChildren()
	local Map = MapStorage[math.random(1,#MapStorage)]
	game.ReplicatedStorage.Remotes.UIMapName:FireAllClients(Map.Name)

	local MapClone = Map:Clone()
	MapClone.Name = Gamemode
	MapClone.Parent = GameStorage

	local gamemodeScript = require(script[Gamemode])
	gamemodeScript.start(Map, LobbyPosition)
	wait(1)
	checkForPlayers()
end

function checkForPlayers()
	if game.ReplicatedStorage.GameInSession.Value == false then
		repeat wait(0.04)
			if #game.Players:GetPlayers() < RequiredPlayers then
				Remotes.UISendInfo:FireAllClients("Waiting for "..RequiredPlayers.." or more players")
			end
		until #game.Players:GetPlayers() >= RequiredPlayers
		newRound()
	end
end

checkForPlayers()

And here’s the ‘Obby’ ModuleScript:

--	// Server Variables

local module = {}
local ServerStorage = game:GetService("ServerStorage")
local Resources = ServerStorage.GameResources
local Remotes = game.ReplicatedStorage.Remotes
local GameStorage = workspace.GameStorage
local PlayerService = game:GetService("Players")

--	// Modifiable Variables

local TimeToStart = 10

--	// Main Script

module.start = function(map,lobbyPosition)
	local players = game.Players:GetPlayers()
	local spawns = map.Spawns:GetChildren()
	local obbyparts = GameStorage["Obby"].ObbyParts:GetChildren()

	for i,v in pairs(obbyparts) do
		v.Transparency = 0.5
		v.CanCollide = false
	end

	for _,v in pairs(players) do
		if v.Character ~= nil and v.Character.Humanoid.Health > 0 then

			v.Character.Humanoid.Died:Connect(function()
				for i,vv in ipairs(players) do
					if v == vv then
						table.remove(players,i)
						script.PlrCount.Value = #players
					end
				end
			end)
			Remotes.UISendInfo:FireAllClients("Race was chosen!")
			local spawnPoint = spawns[math.random(1,#spawns)]

			--	// Teleport Player

			if v.Character ~= nil then
				v.Character:MoveTo(spawnPoint.Position)
			end
		else
			--	// Remove Unnecessary Players
			for i,vv in ipairs(players) do
				if v == vv then
					table.remove(players,i)
				end
			end
		end
	end

	script.PlrCount.Value = #players

	--	// Start Minigame

	local CurrentTTS = tonumber(TimeToStart)
	repeat wait(1)
		CurrentTTS = tonumber(CurrentTTS)-1
		Remotes.UISendInfo:FireAllClients("Race starting in "..CurrentTTS)
	until tonumber(CurrentTTS) == 0

	Remotes.UISendInfo:FireAllClients("Race started!")
	local Map = GameStorage[script.Name]

	for i,v in pairs(obbyparts) do
		v.Transparency = 0
		v.CanCollide = true
	end

	--	// Wait for Winner

	wait(3)
	Remotes.UISendInfo:FireAllClients("Race in session on the map "..Map.Name)

	local TouchDebounce = false
	Map.WinPart.Touched:Connect(function(hit)
		if TouchDebounce == false and hit.Parent:FindFirstChild("Humanoid") and PlayerService:FindFirstChild(hit.Parent.Name) then
			TouchDebounce = true
			local WinnerPlr = game.Players[hit.Parent.Name]
			local Winner = tostring(WinnerPlr.Name)

			Remotes.UISendInfo:FireAllClients(Winner.." just won the race!")
			wait(2)
			if WinnerPlr ~= nil then
				WinnerPlr.Character.HumanoidRootPart.CFrame = lobbyPosition
				WinnerPlr.Character.Humanoid.Health = WinnerPlr.Character.Humanoid.MaxHealth
				WinnerPlr.Backpack:ClearAllChildren()
				for i,v in pairs(WinnerPlr.Character:GetChildren()) do
					if v:IsA("Tool") then
						v:Destroy()
					end
				end
			else
				WinnerPlr.Character.Humanoid.Health = WinnerPlr.Character.Humanoid.Health - WinnerPlr.Character.Humanoid.Health
			end

			--	// Calculate Amount of Crystals
			print("Calculating crystals...")

			local PlayerStats = PlayerService[Winner]:WaitForChild("PlayerStats")
			local RandomAmount = math.random(2,5)
			if PlayerStats["25Mult"].Value == true and PlayerStats["5Mult"].Value == false then
				RandomAmount = RandomAmount*1.25
			elseif PlayerStats["5Mult"].Value == true then
				RandomAmount = RandomAmount*1.5
			elseif PlayerStats["25Mult"].Value == false and PlayerStats["5Mult"].Value == false then
				RandomAmount = RandomAmount
			end

			--	// Change Player Values

			local function Round(n)
				return n % 1 >= 0.5 and math.ceil(n) or math.floor(n)
			end

			local RandomAmount = Round(RandomAmount)
			PlayerStats.Crystals.Value = PlayerStats.Crystals.Value+RandomAmount
			PlayerStats.TotalWins.Value = PlayerStats.TotalWins.Value+1
			PlayerStats.SessionWins.Value = PlayerStats.SessionWins.Value+1

			wait(3)
			print("Cleaning...")
			Remotes.UIMapName:FireAllClients("")
			Remotes.UISendInfo:FireAllClients("Cleaning up...")
			Map:Destroy()

			wait(1.5)
			print("Done cleaning...")
			Remotes.UISendInfo:FireAllClients("Done cleaning!")
		end
	end)
end

return module

I’m very unsure as to why it stops working. There are no errors in the Output tab, I have multiple other minigame scripts which used to work but don’t anymore either.

It works fine up until the very end, as it still prints “Done cleaning…” and fires the remote. Usually, the MinigameHandler script would then after pick another random minigame.
I’m not very knowledgeable when it comes to ModuleScripts.

I’ve messed with the code in little bits for so long that I eventually ditched the project for a few weeks, coming back now I still can’t find the fix. Any help would be so greatly appreciated! :grin:

I think the issue here is that you forgot to change the game.ReplicatedStorage.GameInSession value, at the start of the newRound function you did change its value to true, but when the race finished you didn’t and because the value was still true newRound didn’t got called again. To fix it you can either change the value at the end of the module script or at the end of newRound function.

1 Like

Unfortunately this didn’t fix it, I don’t think the issue is located in the MinigameHandler as other minigame ModuleScripts that I had before making the Obby ModuleScript still work. Thanks for trying to help though :slightly_smiling_face:

Hey! Would you be able to provide another minigame module that works for comparison?

1 Like

Sure, here’s one named FFA:

--	// Server Variables

local module = {}
local ServerStorage = game:GetService("ServerStorage")
local Resources = ServerStorage.GameResources
local Remotes = game.ReplicatedStorage.Remotes
local GameStorage = workspace.GameStorage
local PlayerService = game:GetService("Players")

--	// Modifiable Variables

local TimeToStart = 5

--	// Main Script

module.start = function(map,lobbyPosition)
	local players = game.Players:GetPlayers()
	local spawns = map.Spawns:GetChildren()
	for _,v in pairs(players) do
		if v.Character ~= nil and v.Character.Humanoid.Health > 0 then
			if v.Character.Head:FindFirstChild("StatusText") then
			else
				v.Character.Humanoid.Died:Connect(function()
					for i,vv in ipairs(players) do
						if v == vv then
							table.remove(players,i)
						end
					end
				end)
				Remotes.UISendInfo:FireAllClients("Free-for-all was chosen!")
				local spawnPoint = spawns[math.random(1,#spawns)]
				wait(5)

				--	// Teleport Player

				if v.Character ~= nil then
					v.Character:MoveTo(spawnPoint.Position)

					--	// General Setup

					local sSword = v.PlayerStats.SwordSkin
					if Resources:FindFirstChild(sSword.Value) then
						Resources[sSword.Value]:Clone().Parent = v.Backpack
					else
						Resources["Classic Sword"]:Clone().Parent = v.Backpack
					end

					local ff = Instance.new("ForceField",v.Character)
					game:GetService("Debris"):AddItem(ff, TimeToStart)
				end
			end
		else
			--	// Remove Unnecessary Players
			for i,vv in ipairs(players) do
				if v == vv then
					table.remove(players,i)
				end
			end
		end
	end

	--	// Start Minigame

	local CurrentTTS = tonumber(TimeToStart)
	repeat wait(1)
		CurrentTTS = tonumber(CurrentTTS)-1
		Remotes.UISendInfo:FireAllClients("Free-for-all starting in "..CurrentTTS)
	until tonumber(CurrentTTS) == 0
	Remotes.UISendInfo:FireAllClients("Free-for-all started!")
	local Map = GameStorage:FindFirstChild(script.Name)

	--	// Wait for Winner

	repeat wait(1) until #players <= 1
	local Winner = tostring(players[1])
	if #players == 1 then
		Remotes.UISendInfo:FireAllClients(Winner.." just won Free-for-all!")
		wait(5)
		if players[1].Character:FindFirstChild("HumanoidRootPart") then
			players[1].Character.HumanoidRootPart.CFrame = lobbyPosition
			players[1].Character.Humanoid.Health = players[1].Character.Humanoid.MaxHealth
			players[1].Backpack:ClearAllChildren()
			if players[1].Character:FindFirstChildOfClass("Tool") then
				players[1].Character:FindFirstChildOfClass("Tool"):Destroy()
			end
		else
			players[1].Character.Humanoid.Health = players[1].Character.Humanoid.Health - players[1].Character.Humanoid.Health
		end

		--	// Calculate Amount of Crystals

		local PlayerStats = PlayerService[Winner]:WaitForChild(	"PlayerStats")
		local RandomAmount = math.random(2,5)
		if PlayerStats["25Mult"].Value == true and PlayerStats["5Mult"].Value == false then
			RandomAmount = RandomAmount*1.25
		elseif PlayerStats["5Mult"].Value == true then
			RandomAmount = RandomAmount*1.5
		elseif PlayerStats["25Mult"].Value == false and PlayerStats["5Mult"].Value == false then
			RandomAmount = RandomAmount
		end

		--	// Change Player Values

		local function Round(n)
			return n % 1 >= 0.5 and math.ceil(n) or math.floor(n)
		end

		local RandomAmount = Round(RandomAmount)
		PlayerStats.Crystals.Value = PlayerStats.Crystals.Value+RandomAmount
		PlayerStats.TotalWins.Value = PlayerStats.TotalWins.Value+1
		PlayerStats.SessionWins.Value = PlayerStats.SessionWins.Value+1

		--	// Clean GameStorage

		wait(3)
		Remotes.UIMapName:FireAllClients("")
		Remotes.UISendInfo:FireAllClients("Cleaning up...")
		Map:Destroy()
		wait(1.5)
	end
end

return module

Oh, few things I didn’t explain:
Whenever someone clicks the AFK button there’s a BillboardGui put in their Head Instance named ‘StatusText’.
Also because the FFA minigame uses swords, there’s also a Sword Skin UI, which is what the sSword’s value should be.

After having a look over both modules, I don’t see anything wrong with the code. I would suggest debugging your code to find out where it stops by using prints or breakpoints.

1 Like

I actually found out that the FFA script isn’t working either… even though I tested it multiple times and could have sworn it did. I’ve tested it using prints but I get a bit confused since I’m not 100% knowledgeable with ModuleScripts.
Anyways it’s really late where I live so I’m going to head off, I’ll be back in the morning to resume debugging

1 Like

After more debugging I still can’t find the issue, I’ve made a place where it’s just those scripts and the things it needs to work if you’d like to have a look through it

Did everything print as expected?

1 Like

Yes, however, I’m not really 100% sure how to properly use ModuleScripts. It seems the main Script doesn’t know when it should reroll even though it did before.

Never mind, I somehow fixed it… I think it had something to do with the checkForPlayers() function, it now only checks whenever the GameInSession BoolValue is changed to false. Thanks for trying to help though! :slight_smile:

1 Like