Hey!
What exactly you mean by “game to restart”? what is the game?
What I see in your client side script is:
Server fires a remote, your local script catch that (ChangeStatus remote)
Change text to “Waiting”
Connecting a button function to “leave”
“waiting” for a value.
Do an statement after found the value. If value becomes false status text to: " "
If the value is true, wait 3 seconds, start a song, change camera, enable some guis
When the song is over change text to Game Ended!
So, your game started depends on a call from server to client, to play a song, when the song is over, game is over?
And you want to? let the client to play a song again, change some text in the GUI and wait for the song to end again?
My game is a dancing minigame where the player presses keyboard buttons to play (similar to FNF).
Here’s a video of what I have so far: https://vimeo.com/791416746
*The video will load in a few minutes, it has to optimize
Yes, when the song ends, the game is over. After the game is over, there will be two buttons for the player to click on— ‘Replay’ or ‘Leave’.
Also, I have a RE in ReplicatedStorage named ‘Leave’ and another named ‘ChangeStatus’ and finally, in my ServerScriptService I have a script (see below).
game.ReplicatedStorage.Remotes.Leave.OnServerEvent:Connect(function(player, Stadium)
local MainStadium = workspace:FindFirstChild(Stadium.Name)
for i, v in pairs(MainStadium:GetDescendants()) do
if v.Name == 'Full' then
v.Value = false
end
if v.Name == "ProximityPrompt" then
v.Enabled = true
end
end
player.Character.Humanoid.WalkSpeed = 16
player.Character.Humanoid.JumpHeight = 7.2
end)
In server side you are firing this at some point: ChangeStatus:FireClient(player) to tell the client to start the song, showing GUIs and connecting buttons.
You would need to fire that again for a player to play the song again along with the GUIs states, etc
So you could connect the retry button in your GUI to a remote, asking the server to fire the ChangeStatus again for that player.
When the player clicks the retry button, the remote fires, server catches that signal, and decide if player can restart game or not, if its allowed, fire ChangeStatus:FireClient(player) for that player.
Just make sure you are not double connecting the buttons when that signal is get by the client.
So in my ServerScriptService script, I have to add something like:
game.ReplicatedStorage.Remotes.Replay.OnServerEvent:Connect(function(player, Stadium)
local MainStadium = workspace:FindFirstChild(Stadium.Name)
for i, v in pairs(MainStadium:GetDescendants()) do
if v.Name == 'Full' then
v.Value = true
end
if v.Name == "ProximityPrompt" then
v.Enabled = false
end
end
player.Character.Humanoid.WalkSpeed = 0 player.Character.Humanoid.JumpHeight = 0
end)
Before helping you with your issue you may want to read this:
Looking at your code I think you need to start learning about how to format code and use variables.
First, to make your code readable (not just to yourself! it’s also so others can read the code easier.), declare any Service or Instance at the start of the script:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
Here are a few tips:
Don’t use game.Players or game.Workspace. Use game:GetService("Players") and the word workspace.
Let’s put an example, what’s easier to do here?
script.Parent.Parent.Value = true
Or…
local value = script.Parent.Parent
value.Value = true
To yield the script please use task.wait() instead of wait(). It is way more efficient.
This way, if you ever need it again, you don’t need to type script.Parent.Parent.Parent.Parent.Parent… You can just declare it once!
Not mad because you’re not doing it right, it’s just a suggestion here!
Reading through the post, you have to manage buttons correctly and, as @Dev_Peashie said, keep things server-sided rather than keeping everything on the client.
For example, notes should be kept on the client in the case of a lag spike.
What you don’t want the client to see or know, in the server.
Sorry, I’d help you rewrite stuff and fixing your script but I can’t right now. If you still need help later, reply to this post and I’ll get back to you.
I recommend you if want do a “replay” button for a history game or something like it do rejoin like here:
function rejoin()
local ts = game:GetService("TeleportService")
local p = game:GetService("Players").LocalPlayer
ts:Teleport(game.PlaceId, p)
end
-- here call rejoin function when rejoin button is clicked
rejoin()
It is simple, and works fine, too many games use it, it will be fast, simple and will works better than other things. If you want save data you can use DataStores.
I think it’s better for me to go in Studio in order to help you out, but that’s obviously up to you. I’ve tried to fix the code, but since I am getting confused because you left out some functions or remotes I can’t do much. However I tried what I could…
...Or I think I did.
--- Server ---
local ReplicatedStorage: ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players: Players = game:GetService("Players")
local Remotes: Folder = ReplicatedStorage:WaitForChild("Remotes")
local Replay: RemoteEvent = Remotes:WaitForChild("Replay")
local function BeginGame(Stadium: Model)
local MainStadium = workspace:FindFirstChild(Stadium.Name)
for _, part in pairs(MainStadium:GetDescendants()) do
if part.Name == "Full" then
part.Value = true
end
if part.Name == "ProximityPrompt" then
part.Enabled = false
end
end
end
Replay.OnServerEvent:Connect(function(player: Player, Stadium: Model)
BeginGame(Stadium)
end)
--- Client ---
local ReplicatedStorage: ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players: Players = game:GetService("Players")
local Remotes: Folder = ReplicatedStorage:WaitForChild("Remotes")
local Songs: Folder = ReplicatedStorage:WaitForChild("Songs")
local ChangeStatus: RemoteEvent = Remotes:WaitForChild("ChangeStatus")
local Leave: RemoteEvent = Remotes:WaitForChild("Leave")
local frame = script.Parent.Main
local Main = {
["Leave"] = frame.Leave,
["Replay"] = frame.Replay,
["GameStatus"] = frame.GameStatus,
["Up"] = frame.Up,
["Down"] = frame.Down,
["Left"] = frame.Left,
["Right"] = frame.Right
}
local cam = workspace.CurrentCamera
local song: Sound = nil
local function ChangingStatus(Stadium: Model)
Main.GameStatus.Text = "Waiting..."
Main.Leave.Visible = true
local connection
connection = Main.Leave.Activated:Connect(function()
Leave:FireServer(Stadium)
Main.GameStatus.Text = ""
for _, ui in Main do
if not ui:IsA("TextLabel") then
ui.Visible = false
end
end
cam.CameraType = Enum.CameraType.Custom
connection:Disconnect()
end)
connection:Disconnect()
end
local function BeginSong(Stadium)
while not workspace:FindFirstChild(Stadium.Name) do task.wait() end
task.wait(3)
song = Songs:GetChildren()[math.random(#Songs:GetChildren())]
song:Play()
cam.CameraType = Enum.CameraType.Scriptable
cam.CFrame = workspace:FindFirstChild(Stadium.Name).CamPart.CFrame
Main.GameStatus.Text = "Started!"
for _, ui in Main do
if not ui:IsA("TextLabel") then
ui.Visible = true
end
end
while task.wait(song.Difficulty.Value) and not finished do
local number = math.round(song.PlaybackLoudness/math.random(40,65))
local chosenArrow = math.clamp(number,1, #arrowTypes)
coroutine.wrap(AddArrow)(arrowTypes[chosenArrow])
local connection
connection = song.Ended:Connect(function()
connection:Disconnect()
finished = true
Main.GameStatus.Text = "Game Ended!"
Main.Leave.Visible = true
Main.Replay.Visible = true
return nil
end)
connection:Disconnect()
end
end
Main.Replay.Activated:Connect(function()
BeginSong(Stadium)
end)