im genuinely fed up w this bs. so im making a game since ive been playin this 1 game and its insanely low effort, so i decided to make a remake, i got a round system working but whenever i play with my friend he gets teleported but i never get teleported, no matter if im on TeamA or TeamB. im sick of this.
----------------------- SERVICES & CONSTANTS -----------------------
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TeamsService = game:GetService("Teams")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local MapsFolder = ReplicatedStorage:FindFirstChild("Maps")
local GunsFolder = ReplicatedStorage:FindFirstChild("guns")
local ROUND_TIME = 90 -- Duration (seconds) for each round
local INTERMISSION_TIME = 30 -- Seconds between rounds
local WAITING_TIME = 60 -- Countdown before each round (if ≥2 players)
local gameTimer = WAITING_TIME
----------------------- GUI TIMER SETUP -----------------------
local function createTimerGUI(player)
local playerGui = player:FindFirstChild("PlayerGui") or player:WaitForChild("PlayerGui")
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "RoundTimerGUI"
screenGui.ResetOnSpawn = false
screenGui.Parent = playerGui
local textLabel = Instance.new("TextLabel")
textLabel.Name = "TimerLabel"
textLabel.Size = UDim2.new(0.2, 0, 0.1, 0)
textLabel.Position = UDim2.new(0.4, 0, 0, 10)
textLabel.BackgroundTransparency = 1
textLabel.TextScaled = true
textLabel.TextColor3 = Color3.new(1, 1, 1)
textLabel.Font = Enum.Font.SourceSansBold
textLabel.Parent = screenGui
end
for _, player in ipairs(Players:GetPlayers()) do
createTimerGUI(player)
end
Players.PlayerAdded:Connect(function(player)
createTimerGUI(player)
end)
----------------------- HELPER FUNCTIONS -----------------------
-- Fade Out: Fades a full-screen black overlay in each player's GUI
function fadeOutForAll(duration)
for _, player in ipairs(Players:GetPlayers()) do
if player:FindFirstChild("PlayerGui") then
local gui = player.PlayerGui:FindFirstChild("FadeFrame")
if not gui then
gui = Instance.new("Frame")
gui.Name = "FadeFrame"
gui.Size = UDim2.new(1, 0, 1, 0)
gui.Position = UDim2.new(0, 0, 0, 0)
gui.BackgroundColor3 = Color3.new(0, 0, 0)
gui.BackgroundTransparency = 1
gui.ZIndex = 100
gui.Parent = player.PlayerGui
end
for i = 0, 1, 0.1 do
gui.BackgroundTransparency = 1 - i
wait(duration / 10)
end
gui.BackgroundTransparency = 0
end
end
end
-- Fade In: Fades the black overlay out
function fadeInForAll(duration)
for _, player in ipairs(Players:GetPlayers()) do
if player:FindFirstChild("PlayerGui") then
local gui = player.PlayerGui:FindFirstChild("FadeFrame")
if gui then
for i = 0, 1, 0.1 do
gui.BackgroundTransparency = i
wait(duration / 10)
end
gui.BackgroundTransparency = 1
end
end
end
end
-- Update Timer GUI: Updates each player's timer label with the message provided.
function updateTimerGUI(message)
for _, player in ipairs(Players:GetPlayers()) do
local playerGui = player:FindFirstChild("PlayerGui")
if playerGui then
local timerGui = playerGui:FindFirstChild("RoundTimerGUI")
if timerGui then
local timerLabel = timerGui:FindFirstChild("TimerLabel")
if timerLabel then
timerLabel.Text = tostring(message)
end
end
end
end
end
-- Create Scoreboard: Creates a folder in Workspace to hold team scores.
function createScoreboard()
local scoreboard = Instance.new("Folder")
scoreboard.Name = "Scoreboard"
scoreboard.Parent = Workspace
local teamA_Score = Instance.new("IntValue")
teamA_Score.Name = "TeamA_Score"
teamA_Score.Value = 0
teamA_Score.Parent = scoreboard
local teamB_Score = Instance.new("IntValue")
teamB_Score.Name = "TeamB_Score"
teamB_Score.Value = 0
teamB_Score.Parent = scoreboard
return teamA_Score, teamB_Score
end
-- Assign Players to Teams: Sets teams for all players, gives them guns, and reparents their characters.
function assignPlayersToTeams(teamAFolder, teamBFolder, teamA_Score, teamB_Score)
-- Remove any existing teams.
for _, team in ipairs(TeamsService:GetTeams()) do
team:Destroy()
end
local teamA = Instance.new("Team")
teamA.Name = "TeamA"
teamA.TeamColor = BrickColor.new("Bright red")
teamA.Parent = TeamsService
local teamB = Instance.new("Team")
teamB.Name = "TeamB"
teamB.TeamColor = BrickColor.new("Bright blue")
teamB.Parent = TeamsService
local playersList = Players:GetPlayers()
-- Alternate assignment.
for i, player in ipairs(playersList) do
if i % 2 == 0 then
player.Team = teamA
else
player.Team = teamB
end
-- Give each player two random guns.
if GunsFolder then
local gunsList = GunsFolder:GetChildren()
if #gunsList >= 2 then
for j = 1, 2 do
local gun = gunsList[math.random(#gunsList)]:Clone()
gun.Parent = player.Backpack
end
else
warn("Not enough guns in Guns folder!")
end
end
local function setupCharacter(character)
wait(0.1) -- Allow character parts to load.
if character and character:FindFirstChild("HumanoidRootPart") then
if player.Team.Name == "TeamA" then
character.Parent = teamAFolder
elseif player.Team.Name == "TeamB" then
character.Parent = teamBFolder
end
end
end
if player.Character then
setupCharacter(player.Character)
end
player.CharacterAdded:Connect(function(character)
setupCharacter(character)
end)
end
end
-- Count Alive: Returns the number of players still alive in a folder.
function countAlive(folder)
local count = 0
for _, child in ipairs(folder:GetChildren()) do
local humanoid = child:FindFirstChildOfClass("Humanoid")
if humanoid and humanoid.Health > 0 then
count = count + 1
end
end
return count
end
-- Clear Player Guns: Unequips and deletes all tools from the player's Character and Backpack.
function clearPlayerGuns(player)
if player.Character then
local humanoid = player.Character:FindFirstChildOfClass("Humanoid")
if humanoid then
humanoid:UnequipTools()
end
for _, tool in ipairs(player.Character:GetChildren()) do
if tool:IsA("Tool") then
tool:Destroy()
end
end
end
if player.Backpack then
for _, tool in ipairs(player.Backpack:GetChildren()) do
if tool:IsA("Tool") then
tool:Destroy()
end
end
end
end
----------------------- FORCE TELEPORT FUNCTION -----------------------
local function forceTeleportPlayer(player, targetCFrame)
-- Wait until the player's character and its HumanoidRootPart load.
repeat wait() until player and player.Character and player.Character:FindFirstChild("HumanoidRootPart")
local character = player.Character
local hrp = character:FindFirstChild("HumanoidRootPart")
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
-- Temporarily disable collisions to avoid being blocked.
hrp.CanCollide = false
-- Try several teleport methods.
if character.SetPrimaryPartCFrame then
character:SetPrimaryPartCFrame(targetCFrame)
else
hrp.CFrame = targetCFrame
end
character:MoveTo(targetCFrame.Position)
if character.PivotTo then
character:PivotTo(targetCFrame)
end
-- Retry loop.
local attempt = 0
while (hrp.Position - targetCFrame.p).magnitude > 5 and attempt < 10 do
print("Retrying teleport for " .. player.Name .. " - Attempt: " .. attempt)
if character.SetPrimaryPartCFrame then
character:SetPrimaryPartCFrame(targetCFrame)
else
hrp.CFrame = targetCFrame
end
character:MoveTo(targetCFrame.Position)
if character.PivotTo then
character:PivotTo(targetCFrame)
end
wait(0.5)
attempt = attempt + 1
end
-- Final failsafe: if not close enough, reload the character and try again.
if (hrp.Position - targetCFrame.p).magnitude > 5 then
print("Force teleport failed for " .. player.Name .. ", reloading character.")
player:LoadCharacter()
wait(2)
forceTeleportPlayer(player, targetCFrame)
end
hrp.CanCollide = true
end
----------------------- TELEPORT PLAYERS TO SPAWN -----------------------
local function teleportPlayersToSpawn(teamAFolder, teamBFolder)
if not MapsFolder then
warn("Maps folder not found!")
return
end
local maps = MapsFolder:GetChildren()
if #maps == 0 then
warn("No maps available!")
return
end
local selectedMap = maps[math.random(#maps)]:Clone()
selectedMap.Name = "ActiveMap"
selectedMap.Parent = Workspace
print("Map cloned to Workspace:", selectedMap.Name)
local teamA_spawn = selectedMap:FindFirstChild("TeamA")
local teamB_spawn = selectedMap:FindFirstChild("TeamB")
if not (teamA_spawn and teamB_spawn) then
warn("Map is missing spawn points (TeamA and/or TeamB)!")
return
end
-- Fade out before teleporting.
fadeOutForAll(0.5)
for _, player in ipairs(Players:GetPlayers()) do
local targetCFrame = nil
if player.Team and player.Team.Name == "TeamA" then
targetCFrame = teamA_spawn.CFrame + Vector3.new(0, 5, 0)
elseif player.Team and player.Team.Name == "TeamB" then
targetCFrame = teamB_spawn.CFrame + Vector3.new(0, 5, 0)
end
if targetCFrame then
forceTeleportPlayer(player, targetCFrame)
-- Reparent the player's character to the corresponding team folder.
if player.Team.Name == "TeamA" then
player.Character.Parent = teamAFolder
elseif player.Team.Name == "TeamB" then
player.Character.Parent = teamBFolder
end
end
end
-- Fade in after teleporting.
fadeInForAll(0.5)
end
----------------------- ROUND FUNCTIONS -----------------------
local function startRound()
gameTimer = ROUND_TIME
-- Delete any previous ActiveMap.
local oldMap = Workspace:FindFirstChild("ActiveMap")
if oldMap then
print("Deleting previous ActiveMap at round start.")
oldMap:Destroy()
end
-- Create folders for team characters.
local teamAFolder = Instance.new("Folder")
teamAFolder.Name = "TeamA_Folder"
teamAFolder.Parent = Workspace
local teamBFolder = Instance.new("Folder")
teamBFolder.Name = "TeamB_Folder"
teamBFolder.Parent = Workspace
-- Setup the scoreboard.
local teamA_Score, teamB_Score = createScoreboard()
-- Assign players to teams, give them guns, and set up kill tracking.
assignPlayersToTeams(teamAFolder, teamBFolder, teamA_Score, teamB_Score)
-- Teleport players to their team spawns with fade transitions.
teleportPlayersToSpawn(teamAFolder, teamBFolder)
print("Round started! Timer set to " .. ROUND_TIME .. " seconds.")
-- Main round loop.
while gameTimer > 0 do
updateTimerGUI(gameTimer)
gameTimer = gameTimer - 1
local aliveTeamA = countAlive(teamAFolder)
local aliveTeamB = countAlive(teamBFolder)
print("Alive count - TeamA: " .. aliveTeamA .. ", TeamB: " .. aliveTeamB)
if aliveTeamA == 0 or aliveTeamB == 0 then
print("A team has no living players. Ending round early.")
break
end
wait(1)
end
-- Determine the winning team based on scoreboard values.
local winningTeam
if teamA_Score.Value > teamB_Score.Value then
winningTeam = "TeamA wins!"
elseif teamB_Score.Value > teamA_Score.Value then
winningTeam = "TeamB wins!"
else
winningTeam = "Draw!"
end
updateTimerGUI("ROUND OVER - " .. winningTeam)
print("Round over. " .. winningTeam)
wait(3)
----------------- CLEANUP & RESET -----------------
local activeMap = Workspace:FindFirstChild("ActiveMap")
if activeMap then
print("Deleting ActiveMap at round end: " .. activeMap.Name)
activeMap:Destroy()
else
print("No ActiveMap found during cleanup.")
end
-- Fade out before respawning.
fadeOutForAll(0.5)
for _, player in ipairs(Players:GetPlayers()) do
clearPlayerGuns(player)
player:LoadCharacter() -- Force respawn (and reset camera)
end
wait(1)
fadeInForAll(0.5)
-- Reparent any characters left in the team folders back into Workspace.
for _, folder in ipairs({teamAFolder, teamBFolder}) do
for _, child in ipairs(folder:GetChildren()) do
child.Parent = Workspace
end
folder:Destroy()
end
local scoreboard = Workspace:FindFirstChild("Scoreboard")
if scoreboard then scoreboard:Destroy() end
-- Intermission countdown shown in the GUI.
local intermissionTimer = INTERMISSION_TIME
while intermissionTimer > 0 do
updateTimerGUI("Next round in: " .. intermissionTimer .. "s")
wait(1)
intermissionTimer = intermissionTimer - 1
end
end
----------------------- MAIN CONTROL LOOP -----------------------
local function waitForPlayersAndRounds()
while true do
local playerCount = #Players:GetPlayers()
if playerCount >= 2 then
gameTimer = WAITING_TIME
print("Starting countdown for next round (" .. WAITING_TIME .. " seconds).")
while gameTimer > 0 do
updateTimerGUI(gameTimer)
wait(1)
gameTimer = gameTimer - 1
end
startRound()
else
updateTimerGUI("Waiting for players...")
wait(1)
end
end
end
waitForPlayersAndRounds()