How can I improve this round based sword fighting loop?

  • What does the code do and what are you not satisfied with?
    This script currently does an intermission, gets 2 random players, teleports them to a map and ends the round according to the outcome. I am not satisfied with the used of wait(n) and was wondering if there was another way to have pauses in between updating the text.

  • What potential improvements have you considered?
    One thing I tried for the timer is using roundTimer -= wait(1) as recommended already but had issues with the rounding when checking for the timer being equal to 0.

  • How (specifically) do you want to improve the code?
    I am wondering if there were any improvements I can make to what I currently have, or if there is another way to make it loop. I am not sure how most games do their round systems, and I don’t think they use while loops (I could be wrong). Also, is there a way for more accurate yielding rather than using wait(n) as much as I do?

Main game script:

local playersService = game:GetService("Players")
local serverStorage = game:GetService("ServerStorage")

local roundModule = require(script.RoundModule)

local status = workspace.Status.SurfaceGui.TextLabel

local function updateStatus(text, waitTime)
	status.Text = text
	
	wait(waitTime)
end

while true do
	--Check player count
	if not (#playersService:GetPlayers() >= 2) then
		updateStatus("Not enough players...", 1)
		
		continue
	end
	
	--Intermission
	for intermissionTimer = 10, 1, -1 do
		updateStatus("Intermission: " .. intermissionTimer, 1)
	end
	
	--Choose random players
	updateStatus("Choosing random players...", 3)
	
	local possiblePlayers = playersService:GetPlayers()
	
	if not (#possiblePlayers >= 2) then
		continue
	end
	
	local players = {
		table.remove(possiblePlayers, math.random(1, #possiblePlayers)), 
		possiblePlayers[math.random(1, #possiblePlayers)]
	}
	
	updateStatus("Players chosen: " .. players[1].Name .. " and " .. players[2].Name, 3)
	
	--Connect Died and PlayerRemoving events
	for index, player in pairs(players) do
		player.Character.Humanoid.Died:Connect(function()
			table.remove(players, index)
		end)

		playersService.PlayerRemoving:Connect(function(leavingPlayer)
			if player == leavingPlayer then
				table.remove(players, index)
			end
		end)
	end
	
	--Ready players
	roundModule.readyPlayers(players)
	
	updateStatus("Teleporting players...", 3)
	
	--Main game loop
	local roundTimer = 60
	
	while roundTimer > 0 and #players == 2 do
		updateStatus("Time remaining: " .. roundTimer, 1)
		
		roundTimer -= 1
	end
	
	--Handle round end
	if roundTimer == 0 then
		roundModule.roundEnd(players, nil)
		
		updateStatus("Time is up! There is no winner.", 3)	
	elseif #players < 2 then
		local winner = players[1]
		
		if winner then
			roundModule.roundEnd(players, winner)
			
			updateStatus("The winner was: " .. winner.Name .. "!", 3)
		else
			updateStatus("There was a tie! There is no winner.", 3)
		end
	end
end

Module:

local spawns = workspace.Map.Spawns
local sword = game:GetService("ServerStorage").Sword

local module = {}

function module.readyPlayers(players)
	for index, player in pairs(players) do
		if not table.find(players, player) then
			return
		end
		
		local character = player.Character
		local humanoid = character.Humanoid

		character:SetPrimaryPartCFrame(spawns["Spawn" .. index].CFrame)

		coroutine.wrap(function()
			humanoid.WalkSpeed = 0

			wait(3)

			humanoid.WalkSpeed = 16
			
			sword:Clone().Parent = player.Backpack
		end)()
	end
end

function module.roundEnd(players, winner)
	if winner then
		winner.leaderstats.Wins.Value += 1
		winner.leaderstats.Points.Value += math.random(12, 18)

		winner:LoadCharacter()

		return
	end
	
	for _, player in pairs(players) do
		player:LoadCharacter()
	end
end

return module
1 Like

Looks Like Something Alvin Made for a Tutorial im sure he made a sword fighting game correct me if im wrong! But code looks fine Just test is the key

I can assure you this isn’t from a tutorial

Im Not Saying Its a bad thing!. Alvin Puts them tutorials up not just for people to copy but to learn He does it for fun! I Might do the same thing

I didn’t say it was a bad thing either, but if this was from a tutorial I wouldn’t post it here

1 Like

Im Sure thats allowed to post just incase the tutorial is wrong

You can make your own way of making a wait function with RunService and tick().

local runService = game:GetService("RunService")
local heartbeat = runService.Heartbeat

local function wait(seconds)
    local t = tick()
    repeat
        heartbeat:Wait()
    until tick() - t >= seconds --if this doesnt work, do t - tick() instead, since i'm not sure
    return tick() - t
end

It does exactly what the normal wait() function does except it’s more accurate and you can go lower than .03 seconds.

I’ve seen this on other posts, so I’m confident with this method.

Thanks, I’ll do some testing with this. The only reason I’m looking for other methods is because I’ve seen people say they don’t use wait(n) at all so this is probably the method they’re talking about.