Cloning Locally and not locally [Lua] - lua

I've been trying to make a sword fight game on Roblox studio. I've made a shop Gui so you can click the text button to buy the sword. It works well, You click it checks your kills and if you have enough you get the weapon. In this case, it's 0 kills. But when you take out the sword you cant use it. I've done my research and I believe that's because it's been cloned locally and not globally. Is this the case and if so how do I fix it?
The script in the Text Button:
local player = game.Players.LocalPlayer
script.Parent.MouseButton1Click:Connect(function()
if player.leaderstats.Kills.Value >= 0 then
local clonar = game.ServerStorage.ClassicSword:Clone()
clonar.Parent = player.Backpack
end
end)
Thanks in advance!

When work needs to be performed on the server (as opposed to locally on the client), you can use RemoteEvents to communicate across the client-server boundary.
So first, you'll need to create a RemoteEvent in a shared location, like ReplicatedStorage.
Next, update your client-side LocalScript to fire the RemoteEvent :
local player = game.Players.LocalPlayer
local buyEvent = game.ReplicatedStorage.RemoteEvent
script.Parent.MouseButton1Click:Connect( function()
buyEvent:FireServer()
end)
Finally, you need to create a Script in the Workspace or ServerScriptService that listens for that RemoteEvent and performs the work of giving the player the item :
local buyEvent = game.ReplicatedStorage.RemoteEvent
buyEvent.OnServerEvent:Connect( function(player)
if player.leaderstats.Kills.Value >= 0 then
local clonar = game.ServerStorage.ClassicSword:Clone()
clonar.Parent = player.Backpack
end
end)

Related

Script doesn't seem to be working, and I cannot understand why

script dont work
I am incredibly new to scripting, and I was just fooling around in ROBLOX studio and I made a script that was INTENDED to put an item stored in ReplicatedStorage into a specific players StarterPack, but no matter what I change it does not want to work.
Could anyone explain why?
local playerName = "plr name"
local toolName = "tool name"
game.Players.PlayerAdded:Connect(function(player)
if player.Name == playerName then
local tool = game.ReplicatedStorage:FindFirstChild(toolName)
player.StarterPack:AddItem(tool)
end
end)
You are using an :AddItem() function which doesn't work. You must first clone the tool and add it into the players inventory.
Check the documentation on StarterPack if you are having issues: https://create.roblox.com/docs/reference/engine/classes/StarterPack
Try this:
local playerName = "plr name"
local toolName = "tool name"
local tool = game.ReplicatedStorage:FindFirstChild(toolName)
game.Players.PlayerAdded:Connect(function(player)
if player.Name == playerName then
local newTool = tool:Clone()
newTool.Parent = player.Backpack
end)
end`
The StarterPack is used to determine a set of Tools that all players will spawn with. If a developer wants to ensure that certain Tools are available to specific players, then they will need to parent the Tools directly to the player's Backpack instead.
Your code is mostly fine, but you didn't close your PlayerAdded function, and the StarterPack doesn't have an AddItem function.
If you are having issues, you can always check the documentation for the StarterPack. One issue that I think you'll run into is that putting a tool into the StarterPack will give it to all players, not just the one who matches the name.
The StarterPack is used to determine a set of Tools that all players will spawn with. If a developer wants to ensure that certain Tools are available to specific players, then they will need to parent the Tools directly to the player's Backpack instead.
So instead let's clone the tool into the player's Backpack. But since the backpack gets cleared every time the player respawns, let's move this code into the CharacterAdded event, so it fires every time the character loads into the Workspace.
local playerName = "plr name"
local toolName = "tool name"
local tool = game.ReplicatedStorage:FindFirstChild(toolName)
game.Players.PlayerAdded:Connect(function(player)
if player.Name == playerName then
player.CharacterAdded:Connect(function()
local newTool = tool:Clone()
newTool.Parent = player.Backpack
end)
end
end)

Other players can not see an object duplicate

I have this script that duplicates an object and teleports it to the player when the GUI button is pressed (You can think of GMod to make things easier). It is stored in a LocalScript inside the button and when you press it, but it's only visible for the player that clicked the button.
I'm not exactly sure how I would solve the problem or what the problem is, but I think it's because it's all stored into a LocalScript. I'm new to Lua and Roblox game development and I didn't really take any lessons on it, I'm just working from my memory and experience. Any and all suggestions are greatly appreciated. Also, if I need to give more information, please ask and I will provide it.
My script:
local player = game.Players.LocalPlayer
script.Parent.MouseButton1Click:Connect(function()
local rag = game.Lighting.ragdolls_presets["Wood Crate"]:Clone()
local X = player.Character.UpperTorso.Position.X
local Y = player.Character.UpperTorso.Position.Y + 10
local Z = player.Character.UpperTorso.Position.Z
rag.Parent = game.Workspace.ragdolls
local children = rag:GetChildren()
for i = 1, #children do
local child = children[i]
child.Position = Vector3.new(X,Y,Z)
end
end)
Thank you in advance!
When you clone something in a LocalScript, it only clones on the client side. Changes done on the client side never gets replicated to the server side, however all changes done on the server side would get replicated to all clients, which are the players.
So to fix this you'd need to use RemoteEvents, which is a way for the client to tell the server to do something.
So instead of doing this in a LocalScript
local player = game.Players.LocalPlayer
script.Parent.MouseButton1Click:Connect(function()
local rag = game.Lighting.ragdolls_presets["Wood Crate"]:Clone()
local X = player.Character.UpperTorso.Position.X
local Y = player.Character.UpperTorso.Position.Y + 10
local Z = player.Character.UpperTorso.Position.Z
rag.Parent = game.Workspace.ragdolls
local children = rag:GetChildren()
for i = 1, #children do
local child = children[i]
child.Position = Vector3.new(X,Y,Z)
end
end)
Put a new RemoteEvent in game.Replicated Storage, then:
This should be the LocalScript
local Event = game.ReplicatedStorage.RemoteEvent
script.Parent.MouseButton1Click:Connect(function()
Event:Fire()
end)
And this should be the ServerScript (or Script for short)
local Event = game.ReplicatedStorage.RemoteEvent
Event.OnServerEvent:Connect(function(player)
local rag = game.Lighting.ragdolls_presets["Wood Crate"]:Clone()
local X = player.Character.UpperTorso.Position.X
local Y = player.Character.UpperTorso.Position.Y + 10
local Z = player.Character.UpperTorso.Position.Z
rag.Parent = game.Workspace.ragdolls
local children = rag:GetChildren()
for i = 1, #children do
local child = children[i]
child.Position = Vector3.new(X,Y,Z)
end
end)
Also, it is very important to do server-side validation when using RemoteEvents, for example: instead of checking whether a player has enough money to spawn something in a LocalScript before the RemoteEvent is fired, it should be done in both LocalScript and the ServerScript. The cause for this is that players can change anything in their client side, so information from the client can NOT be trusted. Optionally you can also have time-outs in each side because, lets say a player has millions of money, he can keep executing the RemoteEvent hundreds of times in under a minute which can crash the server or cause extreme lag. So a 3 second - 1 minute time out is sometimes necessary
More information about Roblox's Client-Server Model: https://create.roblox.com/docs/scripting/networking/client-server-model
More information about Roblox RemoteEvents: https://create.roblox.com/docs/reference/engine/classes/RemoteEvent

Roblox Lua: Issue defining a value in a player's leaderstats folder (no error message)

I have a system in my game where when a player steps on a checkpoint, a Stage value in the leaderboard will go up, and then that value is saved to that player's userId.
I want there to be a button that resets that value back to 0, and this is the code I tried for it.
local textButton = script.Parent
local Players = game:GetService("Players")
textButton.MouseButton1Up:Connect(function()
local player = game.Players.LocalPlayer
local stage = Players:WaitForChild(player):WaitForChild("leaderstats").Stage
if stage.Value > 1 then
stage.Value = 1
end
end)
I've tried debugging it by putting print commands in different places to see where the code gets, and when I try to run print(stage) it does not show anything.
LocalScripts cannot change the value on the server. To change a value once a button is clicked, RemoteEvents should be used.
There is a page documenting about them here: https://create.roblox.com/docs/scripting/networking/remote-events-and-functions
To use a RemoteEvent, first you need to put it in a place that is replicated across the server and the client. A good example of this would be to put it in ReplicatedStorage. After that, you need to set up a script that listens for the .OnServerEvent event of the RemoteEvent. To do this, you need to connect a function. As seen in your script, you already know how to do this. So I will get straight to the point.
On the server, set up a script that listens for .OnServerEvent. Next, on the client, edit your script to fire the client instead of trying to set the value. Go back to the server script, and set the value there. The event also passes the Player object, so you can utilize that to actually reset the value.
TLDR;
LocalScript inside of your TextButton:
local textButton = script.Parent
local Players = game:GetService("Players")
local RemoteEvent = 'RemoteEvent location'
textButton.MouseButton1Up:Connect(function()
RemoteEvent:FireServer()
end)
Server Script in anywhere, preferably ServerScriptService:
RemoteEvent.OnServerEvent:Connect(function(player)
local Players = game:GetService("Players")
local stage = Players:WaitForChild(player):WaitForChild("leaderstats").Stage
if stage.Value > 1 then
stage.Value = 1
end
end)
Good luck!

IntValue changing but not shown

I'm scripting a lawn-mowing game in Roblox Studio and I've come across a problem. So every time I cut the grass(trawa) the IntValue goes up by 1. It works fine when it is assigned to a pick-up object and the points go straight to Player's Inventory folder:
local trawa = script.Parent
local function collect(otherPart)
local player = game.Players:FindFirstChild(otherPart.Parent.Name)
if player then
local trawaType = trawa.Name
local trawaStat = player.Inventory:FindFirstChild(trawaType)
if trawaStat then
trawa:Destroy()
trawaStat.Value = trawaStat.Value + 1
end
end
end
trawa.Touched:Connect(collect)
So that script works fine, but that's not the way I want it to work. I want the points to be assigned directly after cutting grass, not after I collect a pick-up it drops. So I changed the script above so that the points are assigned to the tool's inventory and then are copied to player's inventory.
local trawa = script.Parent
local function onTouch(otherPart)
local tool = otherPart.Parent
if tool:IsA('Tool') and tool.Kosa.Value == true then
trawa.Parent = nil
local trawaType = trawa.Name
local trawaStat = tool.Inventory:FindFirstChild(trawaType)
trawaStat.Value = trawaStat.Value + 1
print(trawaStat.Value)
wait(3)
trawa.Parent = workspace
end
end
trawa.Touched:Connect(onTouch)
The value does indeed change because it goes up when I print it, but it's not changing in the properties and is not registered by other scripts, because it's not copied to player's inventory.
Then this is the script in ServerScriptService that should transfer points from the tool to player:
local starter = game:GetService("StarterPack")
local tool = starter:FindFirstChildWhichIsA('Tool')
local player = game:GetService("Players").LocalPlayer
function points(player)
player.Inventory.Trawa2.Value = player.Inventory.Trawa2.Value + tool.Inventory.Trawa2.Value
tool.Inventory.Trawa2.Value = 0
end
tool.Inventory.Trawa2.Changed:Connect(points)
Changing IntValue to NumberValue doesn't solve the problem.
Use a local script with a RemoteEvent that runs it in server script, local scripts are client side. So they don't save to the server, but if you run it on the server, it saves.
Click this link if you want to know more about RemoteEvents.
https://roblox.fandom.com/wiki/Class:RemoteEvent

Removing a player's leaderstats if they click a gui on roblox

Some simple code
script.Parent.MouseButton1Up:connect(function()
????.leaderstats.lvl.Value = 0
????.leaderstats.xp.Value = 0
????.leaderstats.gold.Value = 0
It's not even working. So the player clicks the gui, but how can it reset the players leaderstats, specifically lvl, xp, and gold, I run a fairly popular roblox rpg game with about 400 people right now and this would be an immense help.
You could put the following code in a LocalScript inside your button.
Player = game.Players.LocalPlayer --Only works inside a localscript, replace with the line below it if you need it as a Script.
-- Player=script.Parent while (not Player:IsA("Player")) do Player = Player.Parent end
script.Parent.MouseButton1Up:connect(function()
local index, stat
for index, stat in pairs(Player.leaderstats:GetChildren()) do
stat.Value = 0
end
end)
It should be in a LocalScript, so you can just use the LocalPlayer variable to get the leaderstats and set them.

Resources