If I use invoke client to get the client’s mouse in a more updated position, i believe there may be risks where people can yield the scripts, however what If i place it in a coroutine so it doesn’t yield the whole script and affect other players if an exploiter were to try and yield?
E.g:
--Server:
local MousePos = nil
coroutine.resume(coroutine.create(function()
MousePos = game.ReplicatedStorage.RemoteFunction:InvokeClient(Player)
end))
if Mouse then
print("Got Mouse")
end
print("Past potential yield")
--Client:
game.ReplicatedStorage.RemoteFunction.OnClientInvoke = (function()
return Mouse.Hit
end)
One thing i’d also like to know is if there’s possibly delays (regardless of exploits) in remotefunctions, or is it almost instant that the Mouse.Hit would return when it’s called? reason i’m asking is because what if the client is invoked in order to get the mouse however, what if a delay occurs in sending the mouse and since there’s no yielding in the script due to that delay there’s a potential cause of the MousePos variable remaining nil.
And just to clarify, I know about fireserver(mouse.hit) however that just fires the mouse-position “once” (unless i do a loop cliently), whereas in some cases i’d like to get the fully updated mouse position for example if i had a move that shot 5 fire balls, i’d like to maybe get the fully updated mouse position per each fireball shot so it goes to that updated mouse position.
Another question is if PCALL would be applicable here? so to wait at-least a certain amount of time then continue in the script, (i’d appreciate if someone could show a demonstration)
Because If i create a skill that fires multiple projectiles and I want it to go to the updated mouse position of the player each projectile I’d need a way to keep retrieving the updated mouse position. If i just fireserver once, and i use that position then all the multiple projectiles would go to that One Single Position.
You could handle all that code on the client, essentially doing the same thing.
There’s no need for :InvokeClient(), as it’s an anti-pattern and can be solved otherwise.
As an example, you could avoid all that by firing the server repeatedly for as many times you need to repeat that action. Keep in mind, you may want to keep the number of arguments sent to the server low (using mouse.Hit.p instead of CFrame, etc.) to limit the amount of lag that may cause
The thing is that, the way I set up my current skills system wasn’t based to implemented those type of methods, hence why i’d like to find out other ways to do so rather than firing server repeatedly
unfortunately a lot of methods that can access mouse position from the server are no longer replicated. the biggest example was the humanoid.targetposition property. i believe it was just a change meant to save network space, but it ended being sort of detrimental to a lot of older games who relied on that property to make weapons and other things of that nature
“pcall()” just provides a way to determine whether or not a function successfully executed.
--Server:
local MousePos = nil
task.spawn(function()
while task.wait() do
coroutine.wrap(function()
MousePos = game.ReplicatedStorage.RemoteFunction:InvokeClient(Player)
coroutine.yield()
end)()
end
end)
if MousePos then
print("Got Mouse")
end
--Client:
game.ReplicatedStorage.RemoteFunction.OnClientInvoke = (function()
return Mouse.Hit
end)
How often do you intend the coroutine to execute? The above implementation would be creating a new coroutine every frame, executing it and then yielding it as its last line of execution. I would strongly advise against doing it like this in a loop and instead opt to have a mouse click detected on the client side trigger a “FireServer()” call which then sends the necessary information to the server to carry out the ability/projectile creation and handling etc.
thank you very much for this example, the thing is with fireserver the way I set up my current skills system i didn’t take into consideration those methods like firing server in a loop, i’m wonder if there’s an alternative to this, like can i possibly do this?
--Server
local mousehit
remoteevent.onserverevent:connect(function(player, mouse)
mousehit = mouse
end)
for i = 1,5 do
local fireball = ...
remoteevent:fireserver(player, "updatedmouse")
fireball.cframe = cframe.lookat(fireball.position, mousehit)
end
--client
remoteevent.onclientevent:connect(function(arg)
if arg == "updatedmouse" then
remoteevent:fireserver(mouse.hit)
end
end)