So to keep it simple, i have an server script firing a event which will be fired immidiatly when the player joins. For me this works everytime, but my concern about this is that slow pc’s will load in too slow which causes the data not to end up at the client.
As you said, slower clients may not fully load in on time and could miss the data, however I might be wrong.
Alternatively, you could try making a localscript that runs once the player finishes loading. The localscript would request info from the server via a RemoteFunction, and then the server then replies back, knowing that the player always receives the data.
That’s a good question. Laggy players may not receive that data, so I recommend doing the following (in order)
Local script connects event to function
Local script fires the server
Server takes this as a “I am ready”, and fires the client back with the appropriate information
Of course, make sure the the remote can not be abused by exploiters. Also make sure that firing the remote twice does not break everything.
If you have any questions with this method, feel free to ask them.
K
Example Demo:
Client (Local script)
RemoteEvent.OnClientEvent:Connect(function(data)
print(data)
--Do other stuff with the data or whatever you need
end)
RemoteEvent:FireServer('Loaded')
Server:
RemoteEvent.OnServerEvent:Connect(function(player, info)
if info=='Loaded' then
if not player:FindFirstChild('Loaded') then
--Exploit protection
local f = Instance.new('Folder')
f.Name = 'Loaded'
f.Parent = player
--Fetch data
RemoteEvent:FireClient(player, FetchedData)
end
end
end)
Note that this is not full code, and will require tweaks where indicated to work properly.
Yeah, I use it personally in all of my games. The playerAdded event does not gaurentee that client’s scripts have started run.
Just remember
Connect the event, then fire the server to fire the client back. If you do not do this, the event will not be connected when the data is sent.
Make sure it is not exploitable. My above demo shows a simple example of making sure the event is called only once. You can text by adding 3 fires to the event and seeing if it figures weird behavior.
I’d like to disagree. If PlayerAdded is being unreliable for you, then you most likely are doing something you shouldn’t, such as yielding before connecting to PlayerAdded or not accounting for players who weren’t caught from PlayerAdded. This is why you should always aim for a catcher function.
local function on PlayerAdded(Player)
print("Join by", Player)
end
game.Players.PlayerAdded:Connect(onPlayerAdded)
for _, Player in pairs(game.Players:GetPlayers()) do
onPlayerAdded(Player)
end
You could also be ordering your operations wrong and not accounting for the fact that where the server is mostly implicit, the client is not; maybe even using PlayerAdded where it doesn’t belong.
Sending data through remotes directly with playerAdded does not always work. Even simple print statements with no yielding can cause this. Local scripts have a delay from PlayerAdded. Even if they did not, this method would still be full proof.
What use case exactly do you have for sending data immediately from PlayerAdded when the client hasn’t even initialised yet? That’s not a case of unreliability on behalf of PlayerAdded, that’s your own code failing to account for clients that haven’t fully loaded in yet.
No. PlayerAdded doesn’t yield, it’s an event. LocalScripts are delayed connecting to this the same way they’re delayed from connecting to any other event or running any other code. LocalScripts don’t run until the server has replicated the game to the client.
The OP wanted this functionality. They wanted to use remotes to send initialization data to the player when they joined, but they did not want the data to not be picked up or missed. So, I suggested requesting the data instead. That way, you do not send data directly through player added (which is a bad practice). Instead, the client requests it.
That was the problem in the OP
I was not saying PlayerAdded yeiled, I was saying that PlayerAdded can fire before local scripts run. So the connection to the remote can be made too late.
It is bad practice to send data directly on playerAdded. It should be requested when needed instead.
This chain is getting a bit far away from the OP, also the problem was solved. I hope I cleared up the misconceptions. If you want to continue this, I suggest doing it through messages. Have a good day.
Just one more question about this, unlike the unsafety of firing an remote when playeradded, can it be done with characteradded? Exept for the first time. Or do i need to let the client request for data every time.
OP wanting initialisation data isn’t the same as calling PlayerAdded unreliable, because that’s false. That’s the main point I was trying to make in response to a part of what you said. Requesting data is definitely more powerful and efficient in the case of requesting data upon joining, but that doesn’t mean that PlayerAdded is unreliable.
Ideally, if you can have the client request when it needs data, that’s great. If it does not need the data, it does not need to have it. Allowing the client to request data (Safely with exploit protection) is not a problem.
Looking back, I did not realize I had made that bland of a statement. What I meant to say is that just because PlayerAdded fires does not mean the client’s scripts have run fully. “The playerAdded event is never 100% reliable that the client’s scripts have started running” I should have used does not gaurentee instead of reliable.
I have updated that reply accordingly so others are not given false information. Sorry for the misunderstanding, I made a pretty big mistake. Have a good day.
As long as you wait for the client to be sufficiently initialized, you can send that data. Just make sure that the client receives the data, otherwise the client will have issues using it (It can’t).
It should not continue to fail. If the client requests it, then send it. Make sure you have a limit, otherwise exploiters could spam attack the remotes. Also, exploiters can block requests that say “I got the data”, so do not rely on the client to tell you success. If it fails, just have the client request again.
Exactly. Have some kind of denounce per player. If you use a table, remember to remove the references when the player leaves. Make sure you do not run into memory leaks.
My demo that you marked a solution has a example using Folder objects, so use that same concept with a table.