GUI not showing intermission time?

StarterGui is nothing other than a folder that houses what gets copied to players’ guis.
The contents are cloned and parented to somePlayer.PlayerGui
It is also highly inadvisable to be manipulating GUIs on the server’s side (for a multitude of reasons). Find some way to send the time values from the server to the client, whether it be via remote events, values, or whatever. Then, on the client, change the text to match. What I usually do is send some sort of timestamp to clients and have them make their own countdown based on this. But, you can make it very simple with just an IntValue or StringValue and use val.Changed for your update function.

3 Likes

Interesting. I haven’t heard of many reasons why you wouldn’t want to do that, and even in my own games I’ve had times where I found it easier to simply clone the UI to the client after populating it on the server side. Why would it not be optimal?

Here’s an example:
in the Server Script Service:

local RoundGui = game:GetService("ReplicatedStorage").StringValue --Whatever the name is
local IntermissionTime = 20
while wait(1) do
RoundGui.Value = "Intermission: "..IntermissionTime.." Seconds"
IntermissionTime = IntermissionTime - 1
end

and in the text label itself:

local value = game:GetService("ReplicatedStorage").StringValue --Whatever the name is
script.Parent.Text = value.Value
value:GetPropertyChangedSignal("Value"):Connect(function()
script.Parent.Text = value.Value
end)
1 Like

There are over 20 reasons but I will be general and explain the most important ones:

  1. The server has extra load now that it has to be constantly manipulating people’s GUIs for no reason, when they could just be doing it themselves instead, especially if it is busy trying to make 200 people’s coins spin or something equally as useless
  2. GUIs are usually almost always only client-sided, meaning the server wouldn’t and shouldn’t be able to access them directly or even be able to interact with them
  3. The client’s GUI is on their computer, so if they’re the one manipulating it, it will always look far cleaner than if the server were to try and animate it themselves and replicate it over the network
  4. The server is completely incapable of listening to any GUI events, including those in SurfaceGuis and BillboardGuis, as GUI interaction is handled only client-side
  5. It is really bad practice. You want all visuals to be handled client-side. And, if using OOP, you will not be able to share your custom classes for your GUI across remote events and such, thus, you should use the server to initiate, verify, confirm, and communicate interactions and conversations. The server doesn’t need to care (at all) about what’s happening in the GUI, as long as the correct information is being relayed.
  6. Communication should be achieved by having conversations between the client and server, sending only what is necessary, and not by manipulating the client’s screen directly.
3 Likes

There’s different ways to accomplish this but here’s some things to keep in mind

  1. The server will have to know how much time Intermission has left for obvious reasons.
  2. Players that join during Intermission should also be given the gui.

Fair enough. I guess offsetting server load is better in most cases for all players.

Going back on topic, @SadWowow21, if you’re interested in learning more about how a server-wide countdown can be handled, you should check out this article right here. It helped me quite a bit in figuring out how to build the system.

1 Like

@LightningLion58 ‘s example is the way I would do it. Having the server set the time will keep the timer the same for all clients otherwise individual clients will become out of step.

1 Like

You don’t need a while loop, that’s inefficient

Yes, but while loop needs a small wait(), I think it’s much better to change it every time the value changes. While loop is also much less efficient, functions are better because they don’t run so many times as the while loop. Also, loops can’t run for an infinite amount of times. I once created a script and forgot to implement debounce, and my computer rebooted itself, it was too much for it. I was shocked.

1 Like

Is this solved? If not I can write a solution.

local RoundGui = game.PlayerGui.RoundGui
local IntermissionTime = 20

for i = IntermissionTime,0,-1 do
   	RoundGui.Frame.TextLabel.Text = "Intermission ".. i .." Seconds"
    wait(1)
end

Boom. If it wasn’t solved I think this’ll work. I tested it out.

Does it actually work for you? You refer here to the StarterGui, not the PlayerGui, does it actually change the GUI?

That’s how I did it but I used his locals. I think it’d be PlayerGui then.

We will see what works for him later I guess, I posted a solution too, but he did not respond yet.

to add onto what the others are saying, another reason why the script is not working (other than improper string concatenation) is that you’re changing the GUI on StarterGui and not PlayerGui.

StarterGui is a service used to clone anything in it into the Player’s PlayerGui when they spawn or join the game, and because of that, it doesn’t update unless you rejoin or die.

To counteract that, we’ll use StringValues, as they can easily be manipulated by the Server and can replicate to the client with events.

local TextLabel = script.Parent --The TextLabel
local Status = game:GetService("ReplicatedStorage"):WaitForChild("Status") --The StringValue 

Status.Changed:Connect(function() --An event that fires every time a property of the StringValue changed, in this case the Value
    TextLabel.Text = Status.Value --Change properties accordingly
end)

The code is relatively simple, and to comment on the reason why putting it in ReplicatedStorage is really important is because that can be accessed by the client/server. And for the server script, we’ll just use a simple script in ServerScriptService to change the Status.

local Status = game:GetService("ReplicatedStorage"):WaitForChild("Status") --The StringValue

for i = 30,0,-1 do --A loop that starts and repeats 30 times, with i being 30 at first and decreasing by -1 every time the loop completes.
   Status.Value = "Intermission: "..i.." Seconds" --We change the StringValue with the "i" variable and also with additional text
end

This unfortunately won’t work, since PlayerGui isn’t exactly a service but more as a folder within the Player object in the PlayersService that contains GUIs that are replicated from the StarterGui service.

How it works is that every time the player respawns or joins the game, all the contents within StarterGui is cloned immediately into the PlayerGui.

local Player = game:GetService("Players").LocalPlayer
local RoundGUI = Player:WaitForChild("PlayerGui"):WaitForChild("RoundGui")

Another thing is that we don’t need to use the PlayerGui to even access the RoundGui, alternatively and a much more efficient solution would be creating a local script within the RoundGui that changes the Text, though that only applies to the client (unless we use RemoteEvents/StringValues to change the text via Server)

That is exactly what I said, changing values is easier than firing events in my opinion.

Hey, have you been able to solve your script?

sorry i didn’t see your reply lol

this doesnt seem to be fixed, so ill do my best again

put this in a local script, inside the gui object

local RoundGui = script.Parent.RoundGui
local IntermissionTime = 20
while wait(1) do
RoundGui.Frame.TextLabel.Text = "Intermission: "..IntermissionTime.." Seconds"
IntermissionTime = IntermissionTime - 1
end 

as for how it’ll work with events, just send the value to the clients every 1,2,3,4,5 whatever seconds (if you use more than 1 second, just make it count down client-side

1 Like