Module function returns "-"

So, I have the following problem with my module:

When you call Module.GetDevice(plr) in a script, my Module sends a remote to the client. The Client then sends it back to the server with a string that matches the given Players’s Device.

It seems to work fine on the Client as well as in the Module (I checked by printing out the device’s type)

Module:

local replicated = game:GetService("ReplicatedStorage")
local remotes = replicated.Module.Remotes
local Players = game:GetService("Players")

local module = {}
module.GetDevice = function(plr)
	remotes.Main:FireClient(plr, "DeviceCheck")
	remotes.Main.OnServerEvent:Connect(function(plrFrom, device)
		if plrFrom ~= plr then return end
		print("Module: "..device) -->Module: Desktop
		return device
	end)
end

return module

Script:

local Players = game:GetService("Players")
local replicated = game:GetService("ReplicatedStorage")
local remotes = replicated.Module.Remotes
local Module = require(script.Parent.Modules.MainModule)

Players.PlayerAdded:Connect(function(plr)
	print(Module.GetDevice(plr)) --> -
end) 

As shown above, the Module prints what’s expected but the returned Value (device) seems to be “-”

No Errors. No Warnings

Any Ideas why this isnt’t working? Thanks in advance :smiley:

could you do “plr, device” instead? would it help?

1 Like

The “-” could be that there is no return at all, but instead just to indicate a line ending.

Are you attempting to send info across client-server boundry with the returns?

Also, when writing module scripts I’d recommend you writing them like this:

local module = {}

function module.GetDevice(plr: Player): string -- Always good to show values
    ... -- Your code here
end

return module

This allows for easy OOP implementation (using : instead of .) and makes everything a lot more readable!

Side note:
Do you intend to create a new connection for the event each and every time the function is called?

1 Like

Connected functions do not return to outer functions. If you want to return the first value received from an event use :Wait() like so, this will make your function async and yield.

module.GetDevice = function(plr)
	remotes.Main:FireClient(plr, "DeviceCheck")
	local player, device =  remotes.Main.OnServerEvent:Wait()
	return device
end

EDIT: This looks like you are trying to fake a remote function, just use a remote function. Everyone will tell you they are dangerous but this is just as dangerous if not more. If your client errors you will have a impossible to fix stalled thread instead of an error to act on or pcall.

3 Likes

Well even tho I did not fully understand this question I think that’s what you mean:

Server - Client - Server
I know this is not recommended to do but checking the device is not that important anyway: I use return only to read what the remote gave me so: Let’s say the player is using a desktop:

The remote would send a request to the client. → The Client will Fire the remote once again - this time with the Players device (which is, as you said, a string) → Now since I need the device in my Script and not the Module I do return device This should get get the device to the Script, right?

Yes, I have no idea how to do this differently.

Because using a remote function to go from server → client can cause big problems.

I printed the client’s response in the module for testing—and it worked, so that can’t really be the problem

Thanks for warning me I might have to look for alternatives in future.

I would move the :Connect() to wherever you create the remote event. One way you could do this is having a centralized place where you store all users devices for the remainder of their stay.

local playerDevices = {
    -- Player = Device
}

game.Players.PlayerAdded:Connect(function(plr: Player)
    playerDevices[plr] = "Desktop" -- Default value
end)

deviceEvent.OnServerEvent:Connect(function(plr: Player, device: String)
    playerDevices[plr] = device
end)

game.Players.PlayerRemoving:Connect(function(player: Player)
    playerDevices[player] = nil -- Prevent memory leak
end)
1 Like

i forgor that InvokeClient was bad💀

2 Likes

The module does not have a local variable named device, so I don’t understand how this can execute at all. Lua is not great.

Check this:

Thanks, this works. Will look at remote functions now

1 Like

I would argue using the modified version I provided is safer than this. While it is far from an elegant solution, it still circumvents most/all issues with remote functions and the initial pseudo function.

2 Likes

This looks like a great solution. Avoids unnecessary events :+1: Will definitely implement this

You’re snippet is certainly the best solution to the author’s use case. Remote functions can almost always be avoided and Server - Client - Server remote functions are extremely rare.

Caching solutions like yours introduce race conditions which are often terrible to debug but again, undoubtingly best for the author’s script.

2 Likes