In my server script called MainGameScript I have this code block:
local myRemoteFunction = Instance.new("RemoteFunction")
myRemoteFunction.Parent = game.Workspace
myRemoteFunction.Name = "GetBuildInfo"
game.Players.PlayerAdded:connect(function(player)
print("[MainGameScript] added player")
for i,v in pairs(Regions) do
if (v.Value == 0) then
Regions[i].Value = player.UserId
break
end
end
local success, result = pcall(function() return myRemoteFunction:InvokeClient(player) end)
if success then
print(result)
else
print("Error calling RemoteFunction GetBuildInfo")
end
end)
I have a LocalScript in game.Workspace called LocalBuildScript which contains this:
function game.workspace.GetBuildInfo.OnClientInvoke()
print("[GetBuildInfo] will send back local build info")
return "this will be returned to the server caller script"
end
The GetBuildInfo function is never called. I have added some debug print lines to the calling function and the process seems to die at the point where it uses pcall... This is almost verbatim the Remote Function Client Invoke example from the Roblox Wiki, no idea why it is not working and am hoping somebody here has some experience using InvokeClient scripts.
Thanks,
Andy
The reason it isn't running is because LocalScripts being referenced by RemoteFunctions are expected to be inside of the Player instance somewhere in it. I'm fairly certain this is the case, as I've implemented a similar test system, but I held my LocalScript inside of the Player instance.
Related
I was making an Egg-Open-Gui for a simulator and when I ran the script it always arrored this:
Attempted to call require with invalid argument(s)
Script Players.Robloxgamer_73738.PlayerGui.Menu.EggScript
the so called "Eggscript" is local
here is my script:
wait(game.Loaded)
wait(5)
local petmodule = require(game:GetService("ServerScriptService"):FindFirstChild("PetModule"))
local cost = script.Parent.Parent.Parent.Cost.Value
local player = game.Players.lo
local openOnceButton = script.Parent.OpenOnce
local autoOpenButton = script.Parent.AutoOpen
openOnceButton.MouseButton1Click:Connect(function()
if player.leaderstats["💸 Money 💸"].Value >= cost then
player.leaderstats["💸 Money 💸"].Value = (player.leaderstats["💸 Money 💸"].Value - cost)
local pet = petmodule.chooseRandomPet()
local petVal = Instance.new("StringValue")
petVal.Name = pet.Name
petVal.Parent = player.PetInventory
game.ReplicatedStorage.HatchEgg:FireServer(pet)
print(pet.Name.." selected")
end
end)
You cannot access ServerScriptService in the client. It will be empty, thus, there will be no child. The FindFirstChild call will return nil, which is obviously invalid. Move the module to ReplicatedStorage.
Besides, you don't seem to understand the client-server model. You can't really change a leaderstat value from the client; it will only affect the client and not the server, so other clients will be unaware of the change. You can use RemoteEvents but make sure that you structure them in a way that it will be safe.
I'm attempting to create a plugin that fetches additional code from a server before the user plays the game on roblox studio.
Basically, the user will use something like blockly to create luau code on a website and I want to sent that code to roblox studio. I've seen some plugins that fetch new data from a server from time to time and I've been able to do that, but I'd like to see if there's a way to only fetch the new code when the user clicks the play button because it could be expensive to request new data every 5 seconds or so.
Below is a simple plugin that attempts to send a request to the server when the game loads, but the script never goes beyond game.Loaded:Wait()
Main file:
local Request = require(script.Parent.Request)
local URL = "http://localhost:3333"
local toolbar = plugin:CreateToolbar("Test")
local button = toolbar:CreateButton("Test", "Test", "rbxassetid://4458901886")
local isListening = false
local request = Request.new()
local ok
local json
local function onClick ()
isListening = not isListening
if (isListening == false) then
return print("Not listening")
end
print("Listening")
if not game:IsLoaded() then
print(game.Loaded)
game.Loaded:Wait()
print("Game has started")
ok, json = request:Get(URL)
print(ok, json)
end
end
button.Click:Connect(onClick)
Request file:
local Request = {}
Request.__index = Request
function Request.new()
return setmetatable({}, Request)
end
function Request:Get(URL)
local ok, result = pcall(game.HttpService.GetAsync, game.HttpService, URL)
local json = game.HttpService:JSONDecode(result)
return ok, json
end
return Request
There isn't an explicit signal to detect when a game is about to start.
But, whenever you hit the Play button, the Edit session ends and the Play session begins. When a session ends, all of the plugins are unloaded. So you could use the plugin.Unloading signal to detect when the Edit session is ending, but it will also fire when the user closes the place, when you stop play testing, or when the plugin is disabled or uninstalled.
You could combine that signal with the RunService:IsEdit() function so that the behavior only triggers when exiting Edit mode, but this is still a really hazy signal.
So in a Script in your plugin, you could do something like this :
local RunService = game:GetService("RunService")
local Request = require(script.Parent.Request)
local URL = "<YOUR URL>"
-- listen for when sessions end
plugin.Unloading:Connect(function()
-- disregard sessions that aren't Edit Mode
if not RunService:IsEdit() end
return
end
print("Game about to start... maybe. The game might also be closing, or the plugin might be disabled from the PluginManager.")
local ok, json = request:Get(URL)
print(ok, json)
end)
Debugging this may be difficult as the Output console is cleared any time you start a Play session, so you won't see any of your print statements. But if you close the place, your logs will be preserved on the Welcome Screen. Just go View > Output to open the Output window.
When trying to create a code, that on FireServer with Specific Player chosen a GUI would've been cloned into their PlayerGui, But instead I get a nil value.
Code:
local Blinder = game.ReplicatedStorage.RCD.Blind
Blinder.OnServerEvent:Connect(function(player, PlayerToBlind)
if not player:IsInGroup(7465879) then return false end;
script.BL:Clone().Parent = PlayerToBlind:WaitForChild("PlayerGui")
print("Done")
end)
Basically what I try to reach is if my Admin Panel Remoteevent is fired, and a Target has been chosen, the Targeted Player will become a Cloned GUI into their PlayerGui
Any fix on this error?
The error message itself is telling you that you are calling a function that doesn't exist. This issue is caused by an object not being the type you expect.
Unfortunately, the message is pointing at a line that has a few function calls, so it's difficult to say what is causing the exact error. Either script.BL isn't an object with a Clone() function, or PlayerToBlind isn't an object with a WaitForChild() function.
If you can break the operations into a few different lines and add safety checks along the way, you can guarantee that your code is safe and being called properly.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Blinder = ReplicatedStorage.RCD.Blind
local BL = script.BL
Blinder.OnServerEvent:Connect(function(player, PlayerToBlind)
-- check that the person calling Blinder:FireServer actually provided a PlayerToBlind
assert(type(PlayerToBind) == "string", "Blinder expects PlayerToBind to be the name of a player")
-- escape if the player is not in the appropriate group
if not player:IsInGroup(7465879) then
return
end
-- find the Player object based on the name provided from PlayerToBlind
local blindedPlayer = Players:FindFirstChild(PlayerToBlind)
if not blindedPlayer then
warn("Could not find player named : ", PlayerToBlind)
return
end
-- create a blinding UI on the other player
local targetGui = blindedPlayer:WaitForChild("PlayerGui")
local newBL = BL:Clone()
newBL.Parent = targetGui
print("Done")
end)
By adding asserts into your code, it won't stop your code from breaking, in fact it will force your code to break faster and in expected ways.
The issue has been fixed,
I have been setting up the LocalScript wrong.
(I grabbed the Text from a TextButton, Instead of the TextBox)
I'm making my admin panel. I have a problem when I write this:
if script.Parent.Frame.PlayersTrollFrame.Textbox == game.Players.LocalPlayer.Name then
print("yes")
else
print("no")
How can I get this to loop check the name without a game script timeout
Instead of checking the textbox's contents in a loop, you should use the :GetPropertyChangedSignal(propertyName) functions to get the event that fires whenever a certain property is changed. In this case, we want to get the event that fires whenever the Text property changes:
script.Parent.Frame.PlayersTrollFrame.TextBox:GetPropertyChangedSignal("Text"):Connect(function()
if script.Parent.Frame.PlayersTrollFrame.Textbox == game.Players.LocalPlayer.Name then
print("yes")
else
print("no")
end
end)
:Connect(function) makes it so that whenever the event is fired, it runs the function that's passed through.
However, if you really need to use a loop for some reason, you can do so by putting the if statement in a while wait() do loop
while wait() do
if script.Parent.Frame.PlayersTrollFrame.Textbox.Text == game.Players.LocalPlayer.Name then
print("yes")
else
print("no")
end
end
well hello there,
So I'll get right to the point..
Everyone knows that in Roblox you have a ReplicatedStorage (for Client and Server) and a ServerStorage (only for Server).
So I want to store all my assets in ServerStorage .. you know, since exploiters/hackers can't see the ServerStorage if they tried.
However my game has virtual worlds..meaning that the client sees different objects than the other clients at any given time, so I can't just load an object from a server scripts because then everyone will see it.
Heres the question: Can I perhaps set up a remote function that lets the Client invoke the Server, and then the Server returns a model object or its location or something like that? And can I then use the Client to load the model into the player's workspace?
^That way I can securely store my important game assets in the serverstorage
The answer to your question is "Yes, you can!"
First off, you're going to want to create a RemoteFunction in the ReplicatedStorage. Call this RemoteFunction, 'GetModel'
Now, we're going to set up a local script inside of the StarterPack. This local script should have the following code:
local RS = game:GetService("ReplicatedStorage")
local RF = RS:WaitForChild("GetModel")
local model = RF:InvokeServer("ModelName") -- This code can go anywhere you'd like it to go. 'ModelName' is the name of the model you want to get.
print(model.Name) -- This will print the model's name.
Alright, so we've setup our code to invoke the remotefunction. Now, let's make that RemoteFunction do something. We'll create a server script inside of ServerScriptService. Here's the code:
local RS = game:GetService("ReplicatedStorage")
local RF = RS:WaitForChild("GetModel")
RF.OnServerInvoke = function(player, modelName)
local model = game.ServerStorage:FindFirstChild(modelName)
if model == nil then
return nil
else
return model
end
end
Most of this is basic code, and from what you said in the question it seems you understand lua fine. Hope I helped you! :)