Say for example you wanted a value from a client you can use a RemoteFunction to ask the client for the value, and it would return it to the server, whereas if you were using a RemoteEvent you would have to 2.
My explanation might be bad, I’ll find some posts about it.
Basically, a remote function works similar to how a normal function works.
local function a()
return b
end
local c = a()
print(c) --> prints b
As a remote function:
-- client
local a = RemoteFunction:InvokeServer()
print(a) -- prints b
-- server
RemoteFunction.OnServerInvoke = function(_)
return b
end
A RemoteEvent works similar to how normal events (like InputBegan
, TouchTap
and Changed
) works
You fire the event and whatever is connected to it, receives it and runs the thread.
RemoteFunctions are used when you need the client or server to return a value and a remote event is used when you don’t need it to return a value.
I am just going to summarise this post. So the infinite Yield happens here because you are trying to access ServerStorage from the clients side, this can’t be done since a client simply doesn’t have access to it.
A better way to do this is on the server, you can send an event to the client with the inventory data as a parameter, that way you client has access to that piece of data. However I would recommended add a more secure away, and add checks to make sure nothing can be exploited.
Also, when using RemoteFunctions the server should never invoke a client, unless it is necessary which is most cases its not. Scenario: The server script tries to get information from the client, but the client enters fake values, and this could either make the server script break, or this could give the exploiter an advantage, as they could enter anything they want. If you do this make sure to add checks.
Hopefully this helps, have a good day!
I understand a little more on both so thanks you both, but would it look like this?
remote.OnServerInvoke = function(player)
return dataStore2
end
Because im just trying to get the datastore2 from severstorage
You can’t return the module because it’s in ServerStorage, it’ll only exist on the server. So you’d have to run the module and get the player’s data then return that
remote.OnServerInvoke = function(player)
return dataStore2("Inventory", player) -- return the player's data
end
On the client, no. So you’d want to remove any code that references to ServerStorage from the client script because it’ll keep sending the warning.
It should look like this:
local inventoryData = RemoteFunction:InvokeSever()
-- inventoryData becomes the player's stored data
-- Server
local InvStore = dataStore2("Inventory", player)
Event:FireClient(player, InvStore) -- Very basic way | add your parameters here
-- Client
Event.OnClientEvent:Connect(function(data)
-- You now refer to you InventoryData as "data"
end)
This is a very basic example, you could invoke the server but I don’t see the need as you can get the same result by just sending it through the event! Either way is fine and hope this helps!
I tried your script but it says
What does the script look like now?
local replicatedstorage = game:GetService("ReplicatedStorage")
local armormodule = require(game.ReplicatedStorage:WaitForChild("ArmorHandler"))
-- client
local RemoteFunction = game:GetService("ReplicatedStorage").Events:WaitForChild("RemoteFunction") -- get the inventory data
local inventoryData = RemoteFunction:InvokeSever()
replicatedstorage.Events.UpdateInventory.OnClientEvent:Connect(function(player, armor)
local template = script.Parent.MainGui.Inventory.Templates.Template
local newTemplate = template:Clone()
local armorname = armor.Name
newTemplate.Parent = script.Parent.MainGui.Inventory.Duplicates
newTemplate.Visible = true
local newArmor = armormodule.chooseRandom():Clone()
local camera = Instance.new("Camera")
camera.CFrame = CFrame.new(newArmor.PrimaryPart.Position + (newArmor.PrimaryPart.CFrame.lookVector * 3), newArmor.PrimaryPart.Position)
camera.Parent = newTemplate.ViewportFrame
newArmor.Parent = newTemplate.ViewportFrame
newTemplate.ViewportFrame.CurrentCamera = camera
end)
Ok, now what does the entire error say?
Edit: I didn’t even notice the r was missing
Ok, so that error means that the server script is either creating a table that references itself in an infinite loop or there might be an issue in the datastore2 module.
What does the server script look like?
-- server
local remote = game:GetService("ReplicatedStorage").Events:WaitForChild("RemoteFunction") -- the remote function
local dataStore2 = require(game.ServerStorage:WaitForChild("DataStore2")) -- the data store 2 module script
remote.OnServerInvoke = function(player)
return dataStore2("Inventory", player) -- return the player's inventory data to the client
end
Ok, so I no experience with DataStore2 but I assume that calling the ModuleScript with the DataStore name and player as the key returns the player’s data?
yes
Ok, so there might a syntax error that we’re doing with the ModuleScript that’s causes a table to infinitely reference itself.
Ok, try this:
local remote = game:GetService("ReplicatedStorage").Events:WaitForChild("RemoteFunction") -- the remote function
local dataStore2 = require(game.ServerStorage:WaitForChild("DataStore2")) -- the data store 2 module script
dataStore2.Combine("DATA", "Inventory")
remote.OnServerInvoke = function(player)
return dataStore2("Inventory", player) -- return the player's inventory data to the client
end
it still says this