I've been working on some classes for a project and I've run into the problem of not really knowing how to keep the game consistently starting a new round, picking a new map, etc, etc.
Should I use a while loop, or perhaps a bindable event (this is what seems best to me) to detect the end of a game, or what?
I think this question is pretty discussion based, so let me know what you guys prefer to do. I'm honestly pretty stumped. Creating a frame work for a game is a lot tougher than it seems on the surface.
Btw, I'm not asking for any code, or requesting anything. This falls in the lines as a 'good question' haha. I just want to know how some people prefer to do things like this, especially if you have experience doing it.
Thanks.
I've made dozens of round based games before. What I usually do is make a bunch of functions each with it's own purpose (e.g the intermission or choosing specific maps).
function Intermission() --Intermission function for i = 30,0,-1 do --We run a loop 30 times and each time it runs it subtracts "i" by 1. print(i) --Print i wait(1) --wait a second end end function ChooseMap() --Choose map function local Maps = game:GetService("ReplicatedStorage"):GetChildren() --We get the children of the replicated storage (assuming its all maps, if not make a separate folder within replicated storage and get the children from there) local ChosenMap = Maps[math.random(1,#Maps) --We index the Maps table from a random number between 1 to the number of maps in the table. print(ChosenMap.Name.." is the chosen map!") --We print that its the chosen map. local Map = ChosenMap:Clone() --We clone it Map.Name = "Map" --We name it map for future reference Map.Parent = workspace --We parent it to the workspace. end function RunGame() local Map = workspace.Map --We grab the map and since it was named map beforehand its easier to get for i,v in pairs(game:GetService("Players"):GetPlayers()) do --We loop through the players if v.Character and v.Character.Humanoid.Health > 0 then --Run a simple conditional statement to see if the character of the specific player exists and if they're still alive Character.HumanoidRootPart.CFrame = Map.Spawns[i].CFrame + Vector3.new(0,3,0) --If thats the case then we modify the cframe of their humanoidrootpart to a spawn in the map and add Vector3.new() to ensure that they don't get stuck in the spawn. end end end while true do -- A while true do loop in which we run all three of these functions, and since when you run a function it yields the code we can easily do all three one by one. Intermission() ChooseMap() RunGame() end
Considering you're attempting to check if the game is reaching its win/lose conditions, I usually make a loop for the game timer and have a loop that runs each second that checks if any of the players are alive and I use a conditional statement to check.
function RunGame() local IngamePlayers = {} local Map = workspace.Map --We grab the map and since it was named map beforehand its easier to get for i,v in pairs(game:GetService("Players"):GetPlayers()) do --We loop through the players if v.Character and v.Character.Humanoid.Health > 0 then --Run a simple conditional statement to see if the character of the specific player exists and if they're still alive Character.HumanoidRootPart.CFrame = Map.Spawns[i].CFrame + Vector3.new(0,3,0) --If thats the case then we modify the cframe of their humanoidrootpart to a spawn in the map and add Vector3.new() to ensure that they don't get stuck in the spawn. table.insert(IngamePlayers,i) --We insert them into the table end end for time = 100,0,-1 do print(i) for index,plr in pairs(IngamePlayers) do if plr then --if the player exists local char= plr.Character if char.Humanoid.Health > 100 then --If they are alive --We do nothing. else table.remove(IngamePlayers,index) --remove them since theyre dead. end else table.remove(IngamePlayers,index) --remove them from the table since they probably left the game. end end if #IngamePlayers == 1 then print(IngamePlayers[1].Name.." has won!") elseif #IngamePlayers == 0 then print("everyone died! no one wins!") elseif i == 0 then print("ran out of time! no one wins!") end wait(1) --We do this every second. end end
Hey for anyone wondering; I did eventually find a way to do this, and in such a manner as I think its worth sharing with other people.
I basically went with mostly OOP, I created a class called the GameController and another class for matches.
The matches class holds the information like the match time, the game mode, the current map, etc. The GameController class holds all the functions that actually start the game (Like choosing the map, teleporting the players, updating the intermission sequences, etc).
Then I required them into a server script and ran a bit of code like this:
while true do gameController:StartIntermission() gameController:StartGame() wait() end
Its super clean and works really well, Im thinking about finishing it and open sourcing it for my buddies. If I ever do, I'll try and remember to post it here for other people to learn. Cheers.