Local Scripts and Script Errors

So, I have been working on a game, and for some reason, my LocalScript won’t understand the value (which is global) in my script in the ServerScriptStorage. The idea is to make a surface UI telling a variable, in this case, a goal.

This is part of the code from the script:

timeLeft = 90
while true do
    timeLeft -= 1
    wait(1)
end

And here is a fraction of the code from the local script.

while true do 
    script.Parent.Text = timeLeft
    wait(0.01)
end)

But it doesn’t understand timeLeft, and is underlined in blue.
Any help is absolutely greatly appreciated, even if it is an educated guess. Thank you for your time spent reading this post and hopefully you will find me a solution! :slight_smile:

Everyone of you 17 people you liked this comments, are pure legends!

2 Likes

Are you trying to pass timeLeft variable to another script? you can’t but you can use attributes to keep it in sync

Script:

TargetInstance = game:GetService("Players")
while task.wait(1) do
	local Current = TargetInstance:GetAttribute("timeLeft") or 0
	TargetInstance:SetAttribute("timeLeft", Current + 1)
end

LocalScript:

TargetInstance = game:GetService("Players")
TargetInstance:GetAttributeChangedSignal("timeLeft"):Connect(function()
	script.Parent.Text = TargetInstance:GetAttribute("timeLeft") or 0
end)

you can replace TargetInstance with the instance you want to keep the attribute.

2 Likes

That’s because ServerScriptService is only visible to the server. Use ReplicatedStorage instead.

2 Likes

RemoteEvents are required to exchange data between a server script & a local script and vice versa.

2 Likes

I know, I am a terrible developer, but can you give me an example please?

1 Like

Create a RemoteEvent in ReplicatedStorage called TimeLeftEvent
Then Create a Script in ServerScriptService that says this:

local timeLeft = 0
while true do
  timeLeft += 1
  for I,v in pairs(game.Players:GetPlayers()) do
    game.ReplicatedStorage.TimeLeftEvent:FireClient(v,timeLeft)
  end
  wait(1)
end

Then, create a LocalScript inside of the textLabel (or whatever shows the text that says how much time is left) that contains this code:

game.ReplicatedStorage.TimeLeftEvent.OnClientEvent:Connect(function(timeLeft)
   script.Parent.Text = timeLeft
end)

Try that and let me know if it works.

Another reason your code may have not been working is because on the fraction of the code from the local script, you put end) with “)”. On a while loop, you just write end without the “)”

3 Likes

Hey,I have tested this code and unfortunately it doesn’t work, but thanks for the help!

1 Like

Server Code:

local timeLeft = 0
local event = game.ReplicatedStorage.Event -- Change to your even path

while wait(1) do
   timeLeft += 1
   Event:FireAllClients(timeLeft)
end

Client Code:

local event = game.ReplicatedStorage.Event -- Change to your even path

event.OnClientEvent:Connect(function(timeLeft)
    script.Parent.Text = tostring(timeLeft)
end)

You can also insert an IntValue in ReplicatedStorage, and update its value every second, and the client can read that value and set the GuiObject’s text to that value. Which is what I assume you were trying to do.

Server Code:

local timeLeft = game.ReplicatedStorage.TimeLeft

while wait(1) do
   timeLeft.Value += 1
end

Client Code:

local timeLeft = game.ReplicatedStorage.TimeLeft

while wait() do
   script.Parent.Text = tostring(timeLeft.Value)
end
3 Likes

What would be the client in this case?

1 Like

I can understand why you think it would work, in order to understand why it doesn’t work you’ll need to understand the Roblox Client-Server model.

More info: Developer Hub

Basically, the server is well, the server, and the client is a player, so there can be multiple clients connected to a server.

LocalScripts are run on each client, while Normal/Server scripts run on the server.

Now, the reason why the code isn’t working is that variables are not shared across client and servers, since they run on separate computers.

To solve this problem, Roblox has RemoteEvents and RemoteFunctions, these objects are used to communicate from server to client, or from client to server.

More info: Developer Hub

In this case you would use a RemoteEvent and send a message to all clients.

See article linked above for the difference between Remote Events and Functions

Here is some simple example code that sends a message to all players/clients in the server.

-- Must be run on a Server Script

local myRemoteEvent = -- remote event here --

-- Run :FireAllClients() to send a message to all clients
-- In this case, we are sending the string "my message"
-- but it can be anything.
myRemoteEvent:FireAllClients("my message")

Alternate Solution

A simpler solution is the use a NumberValue or attribute, since changes of NumberValues or attributes from the server will replicate to all other clients, replication is basically the server telling all other clients that this has changed.

And another thing is, avoid using Global Variables, always try to use local instead.

2 Likes

Read @LukaDev_0 ‘s post to learn about Roblox’ client-server model.

2 Likes

Wait, so should it be like this?

game.ReplicatedStorage.RemoteEvent:FireAllClients()
     - - ?
end)
1 Like

There’s actually a simpler way to do this:

game.ReplicatedStorage.TimeLeftEvent:FireAllClients(timeLeft)

Are you are trying to connect it to a function like part.Touched:Connect(function(hit)? If so, you should instead use

game.ReplicatedStorage.RemoteEvent.OnClientEvent:Connect(function(timeLeft) --Connects it
--Do whatever
end)
2 Likes

No, I am trying to make a global 90 second countdown for my football game

1 Like

@Omnomc Check the code I provided above.

1 Like

But what is the client in this case I don’t understand

The client is the local player. When YOU play a game YOU are a local player to the game.

1 Like

but where should I put in the local script?

Wherever local scripts can be placed and will execute. Typically the StarterPlayerScripts folder.

1 Like

So could I put it in the text label?