Is it reliable to send data to client when they first join?

I’m working on a inventory system and I want to send the client their inventory as soon as they join, and then update changes when removing or adding a item

this is an example on how I’d do it

-- Server
-- player joins
Event:FireClient(Player, Inventory)
-- localscript in player
Event.OnClientEvent:Connect(function(inventory)
-- will the client always recieve this event?
end)

will the client always recieve the event if its fired when they join, or would it be better for the client to request the inventory when they join?

You could use a RemoteFunction instead, where the server returns the inventory after the client requests it. This will make sure that the client gets the data when it is needed and when it can do something with it.

2 Likes

I have scripts that fire RemoteEvents when the player joins and I have never had any problems.

Game.Players.PlayerAdded:Connect(function(player)
    remoteEvent:FireClient(player)
end)

Never had an issue doing it like this. (A very laggy client might have problems tho idk)
If you want it to work 100% I would use a RemoteFunction.

1 Like

RemoteFunctions work but I wanted to shorten the code a bit, it seems so far with testing that the client always receives the event but it’s just slightly delayed so any code accessing the inventory locally right before the event is received will error

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")

local inventory

RemoteEvent.OnClientEvent:Connect(function(inventory)
	inventory = inventory
	for i, v in pairs(inventory) do -- works
		print(v)
	end
end)

for i, v in pairs(inventory) do -- error
	print(v)
end

but yeah I’ll use a RemoteFunction just in case, unless someone knows 100% that the event will always be received

As long as you wait until the player is added to fire the event you should be good.

That’s an issue that using a RemoteFunction will solve because it pauses the code until a response is received. Mitigating this issue without a RemoteFunction would be more complicated and long than just using a RemoteFunction (which I think is more robust). This behaviour does show us that it is likely scripts run before the player added event is called, but it is still best to use a RemoteFunction in this case to ensure you have the data.

Here is a post on the same issue. Basically like @Sublivion said I think RemoteFunction is your best option.

1 Like

Should of mentioned this before but yielding is not a issue with how I’m going to write the script

stuff will only happen whenever a inventory is updated

I was just worried if the event wouldn’t fire because I’d never get the data, but it seems that it will always fire so I don’t have to request the data then add to inventory and setup an additonal update inventory function

I could do it all with one event

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")

local inventory = {}

function PrintInventory()
	for i, v in pairs(inventory) do
		print(i .. " " .. v)
	end
end

function UpdateInventory(NewInventory)
	
	for i, v in pairs(NewInventory) do
		if not inventory[i] then
			inventory[i] = v
		end
	end
	
	PrintInventory()
	
end

RemoteEvent.OnClientEvent:Connect(UpdateInventory)

Oh right. When you said the code produces an error I thought you were relying on the inventory to be loaded for your code to work. But why is it set up like this? The client should know what the inventory is because all edits to it would be sent from the client to the server (except for initial loading) right?

It was just a basic example on how yielding wasn’t an issue, my actual script is not like that

and I’m not sure what you mean by the second part but the inventory should never be edited like that by the client as exploiters could just add their own items

but the general idea of what I’m going for is to be able to update stuff (gui inventory slots) on client only when something changes or is added/removed because looping through an entire inventory and checking if it exists or if it needs to be changed could cause performance issues especially if a player has a massive inventory

The idea is that the client requests a change and the server validates it, returning if it was a success (so the client inventory is consistent and the player is aware no changes were made). It would almost always be in exchange for something else e.g. points or finding something in game.

1 Like

Events in playeradded are guaranteed to be received only by the first client listener, so if you have two scripts listening on that event and they don’t manage to both connect before receiving the event, then only the first one to load will receive it.

I tested the fact that it’s guaranteed by adding a task.wait(60*5) before the localscript listener and having the event be called on playeradded, it fired correctly, even after a 5 minutes delay

I tested the race condition by having two localscripts listening, one on a wait of 5 and the other on a wait of 10, only the wait 5 was correctly received.

Hopefully this clears out the large amount of misinformation around this topic

2 Likes