Trying to add +1 value in a attribute - Roblox Luau - lua

I was trying to make a code that if you touch a coin, then the value of your coins goes up 1 more, but i tried to make and haven't sucess. Here's the code.
script.Parent.Touched:Connect(function(Player)
if Player.Parent:FindFirstChild("Humanoid") then
local Players = game.Players:GetPlayerFromCharacter(Player.Parent)
local Money = Players:GetAttribute("Coin")
Players:SetAttribute("Coin", +1)
task.wait(.2)
script.Parent:Destroy()
end end)

You’ll want to add your previously amount + 1
local Money = Players:GetAttribute("Coin")
Players:SetAttribute("Coin", Money+1) -- Add Money + 1

Related

attempt to yield across metamethod/C-call boundary AND cannot resume non-suspended coroutine in ROBLOX STUDIO when using wait (00.1)

This is my code
-- Script by supermarioclub231 as known as marioroblox102, and special thanks to jacko for some scripts things
-- idk
-- Player
local plr = game.Players:CreateLocalPlayer(0)
game:GetService("Visit")
game:GetService("RunService"):run()
plr:LoadCharacter()
-- have to do this so that the same numbers arent generated every time
math.random(); math.random(); math.random()
digits = 4 -- the amount of times to add digits to the end of the player name
prefix = "NoName "
suffix = "" -- wouldnt wanna type anything here, the digits will be added here!
for i=1, digits do
suffix = suffix .. math.random(1,9)
i = i + 1;
end
plr.Name = prefix .. suffix
-- shopium brings to you...
shirt = Instance.new("Shirt", plr)
pants = Instance.new("Pants", plr)
shirt.ShirtTemplate = "rbxasset://shirts/jared.png"
pants.PantsTemplate = "rbxasset://pants/jeans.png"
while true do
wait (0.001)
if plr.Character.Humanoid.Health <= 0 then
wait(5)
plr:LoadCharacter(true)
elseif plr.Character.Parent == nil then
wait(5)
plr:LoadCharacter(true)
end
end
everytime i run it, i get this
the line 39 is wait(000.1),
why its not working?
its supossed to do something forever
like a loop
but it gives me a error
First of all you don't have to you use math.random() three times at the start so it doesn't generate the same script everytime as thats not how it works it will generate a random number between the range you specify every time and the number may be the same every once in a while but thats why its called math.random() but I'm also working on fixing the rest of you script just wanted to tell you that. Also just use the ROBLOX Health Changed Event and the link to the wiki of that event is here.

I want this script inside a gui to check if a player has a tool. ROBLOX STUDIO

Im making a Gui shop, inside this shop you can buy tools. I want to make it soo it doesn't give the tool if the player already has it in his inventory. I tried looking for an answer but i couldn't find one.
Here's the script :
player = script.Parent.Parent.Parent.Parent.Parent.Parent
money = player.leaderstats.Cash
price = 100
tool = game.Lighting:findFirstChild("Bigger")
function buy()
if money.Value >= price then
money.Value = money.Value - price
local tool1 = tool:clone()
tool1.Parent = player.Backpack
local tool2 = tool:clone()
tool2.Parent = player.StarterGear
end
end
script.Parent.MouseButton1Down:connect(buy) ```
The solution I found consists of checking every item in the player's backpack and checking if it matches the tool name. Here is the code:
player = script.Parent.Parent.Parent.Parent.Parent.Parent
money = player.leaderstats.Cash
price = 100
tool = game.Lighting:findFirstChild("Bigger")
function buy()
-- get's all items(tools) in the player's backpack
local toolsinbackpack = player.Backpack:GetChildren()
-- get's the number of items(tools) in the player's backpack
local numberoftools = table.getn(toolsinbackpack)
local playerhasthetool = false
for key = 1,numberoftools, 1 do
-- check's if the tool in the player's backpack matches the name of the
-- tool it want's to buy.
if toolsinbackpack[key].Name == tool.Name then
-- if the names match, the loop stops running and the variable is
-- set to true
playerhasthetool = true
break
end
end
-- if the player has enough money and doesn't have the tool, it's allowed to
-- buy the tool.
if money.Value >= price and playerhasthetool == false then
money.Value = money.Value - price
local tool1 = tool:clone()
tool1.Parent = player.Backpack
local tool2 = tool:clone()
tool2.Parent = player.StarterGear
end
end
script.Parent.MouseButton1Down:connect(buy)
Note that if the player has the tool equipped(using the tool) while the script runs, it won't show up in its backpack, and he will be able to buy the tool 2 times. The player won't be able to buy the tool more than 2 times, though. For a perfect solution, you are going to need to check the player's model and see if the tool is in there. You can also do something so players need to unequip their tools before accessing the shop.

How can i make it so a change of a IntValue is permanent?

So im trying to make a gamepass (developer products to get money via Robux) gui, and while testing it a few times, it worked, until i reached a certain value of around 400,000-500,000 bananas (thats my currency) it stopped working. Also, earlier when making my game, when i purchase something that has costs over 1 million bananas, it appears to decrease, but when i get some banana seeds (sellable item) and sell it, it resets back to before i bought the 1 million banana item (e.g from 1.3 million then i purchase it, then it becomes 300,000, but when the value gets modified (example: via selling seeds) it changes back to before it got bought (1.3 million)) and also im working on a Admin GUI and i wanna make a gui to give money, obviously i knew it wasn't going to work in the first place.
Leaderstats script:
Script name: leaderstats
Script type: server side
Script code:
game.Players.PlayerAdded:Connect(function()
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
local coins = Instance.new("IntValue", leaderstats)
coins.Name = "Bananas"
local resets = Instance.new("IntValue", leaderstats)
resets.Name = "Rebirths"
local bananaseeds = Instance.new("IntValue", leaderstats)
bananaseeds.Name = "BananaSeeds"
end)
My gamepass handler script (ServerScriptService):
Type: server side
Name: DevPrdctHndlr
Code:
local mps = game:GetService("MarketplaceService")
mps.ProcessReceipt = function(reciptInfo)
if reciptInfo.ProductId = 1146099164 then
--[Donate to me!]
local player = game.Players:GetPlayerByUserId(reciptInfo.PlayerId)
player.leaderstats.BananaSeeds.Value =
player.leaderstats.BananaSeeds.Value + 10000
player.leaderstats.Bananas.Value =
player.leaderstats.Bananas.Value + 50000
return Enum.ProductPurchaseDecision.PurchaseGranted
end
end
Buy SmoothPlasticWand script (its a shop gui textbutton):
Type: localscript
Name: BuyScript
Location: game.StarterGui.ShopGui.ShopFrame.SmoothPlasticWand.BuyScript
Code:
local Button = script.Parent
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local currency =
game.Players.LocalPlayer.leaderstats:WaitForChild("Bananas")
Button.MouseButton1Up:Connect(function()
if currency.Value >= 1000000 then
ReplicatedStorage.ReplicatedWands.SmoothPlasticWand:Clone().Parent = game.Players.LocalPlayer:WaitForChild("Backpack")
game.Workspace.Musounds.Buy:Play
currency.Value = currency.Value - 1000000
end)
Im sorry if this question is a duplicate, im still a noob at StackOverflow and im sorry if this question isn't detailed enough, i will provide additional details if you want.
The short answer to your question is : do the work on the server.
The server is the source of truth for all values. When the world is changed with a server Script, that change is replicated to out to all players. But when the world is changed with a LocalScript, that change only appears in that specific player's world.
So when you use the MouseButton1Up handler on your button in a LocalScript, you are only changing the player's local view of that value, and you are not changing the actual source of truth. One fix for this is to use a RemoteEvent in your LocalScript to signal to the server that there's a change that needs to be made.
So create a RemoteEvent in ReplicatedStorage and name it something like BuyItem
In your LocalScript :
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local BuyItem = ReplicatedStorage.BuyItem
local Button = script.Parent
Button.MouseButton1Up:Connect(function()
-- tell the server that the player would like to buy the item
BuyItem:FireServer("SmoothPlasticWand")
end)
And then, in a Script somewhere, handle the signal coming from the client:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local BuyItem = ReplicatedStorage.BuyItem
-- set up a price table for items
local prices = {
SmoothPlasticWand = 1000000,
-- add more items here
-- SomeOtherWand = 10,
}
-- listen for the player wanting to buy things
BuyItem.OnServerEvent:Connect(function(player, itemName)
-- check that it's a real item
assert(type(itemName) == "string", "Expected itemName to be a string")
assert(prices[itemName], "Could not find a price for " .. itemName)
-- check that the player has enough money
local itemPrice = prices[itemName]
local currency = player.leaderstats.Bananas
if currency.Value >= itemPrice then
-- give the player their wand
local wand = ReplicatedStorage.ReplicatedWands[itemName]:Clone()
wand.Parent = player.Backpack
-- subtract how much the wand cost
currency.Value = currency.Value - itemPrice
end
end)
Now, because the server Script is handling the change to currency.Value, that change will properly show up for everyone and make the change permanent.
Maybe for safety, do something like this to reset it to what it should be. Basically make a variable which captures the value of the currency, then make the currency that same value as a fail-safe
--Put This Right After The Item Is Bought
StoredBananas.Value = coins.Value
--This Goes After The Currency Change When Buying So That It Sets It To The Correct Price After It Glitches Out.
coins.Value = StoredBananas.Value

Roblox game script to detect "sole survivor" winner

I am working on a 6 player rounds-based Roblox game with each round ending if either time runs out OR if every player except for one survivor remains. After each round players (and those killed during the round) are teleported back to a lobby, followed by a brief intermission, and then teleported bak into a map to start a new round (there are lots of different maps chosen randomly). My strategy for this game was to create a large region surrounding all the maps and during the rounds as the timer is counting down, continually detect the # players in the region. When that number gets to 1 the round would end and a winner would be declared. There are 2 problems with this approach:
I had to create a huge region to encompass all the different maps and as I add more maps the region will have to get bigger and bigger. Is detecting # players in such a large region when at most 6 players will be in only one map at a time?
My player detection script isn't working. It detects one player but when there are 2 players it still returns "1" as # of players. To trouble shoot this problem I created a simple game that detects when a player is in a region (gray baseplate) and when they leave the region (red baseplate). When I run the game - https://www.roblox.com/games/6060804433/Rounds - publicly with 2 players in the game it only returns 1 player in the game (which I display in an upper left GUI). My code is below - I think the problem is with how the table / dictionary playersFound works.
CODE:
regionPart = game.Workspace.RegionFromThisPart -- I created a transparent cube to define the region
pos1, pos2 = (regionPart.Position - (regionPart.Size/2)),(regionPart.Position + (regionPart.Size/2))
region = Region3.new(pos1,pos2)
Status = game.ReplicatedStorage.Status
wait(5)
while wait(1) do
partsInRegion = workspace:FindPartsInRegion3(region, game.Workspace.Baseplate,1000)
playersFound = {} -- table of players found
for i, part in pairs (partsInRegion) do
if part.Parent:FindFirstChild("Humanoid") ~= nil then
playersFound["playerinregion"] = part.Parent -- add players character to table
print (i, part) -- 0
end
end
function Length(playersFound)
local counter = 0
for _, v in pairs(playersFound) do
counter =counter + 1
end
return counter
end
Status.Value = Length(playersFound) .." players in region"
end
Bonus question: The GUI I created to show the number of players in the region shows on my screen but not the other player's scree (it says "label" on their screen).
I have spent an incredible amount of time spinning my wheels and would GREATLY appreciate help solving this problem.
Thank you!
You're absolutely right that your issue stems from how you're putting players into your playersFound table. Because you are using the same key in the table every time, you are overwriting the old player with any new one you find.
Instead, try using a unique key to hold onto the players. This could be i or better yet, the player's name. And since you are just looping over the table again, why not just keep a counter of how many players there are.
local regionPart = game.Workspace.RegionFromThisPart -- I created a transparent cube to define the region
local pos1 = (regionPart.Position - (regionPart.Size/2))
local pos2 = (regionPart.Position + (regionPart.Size/2))
local region = Region3.new(pos1,pos2)
local Status = game.ReplicatedStorage.Status
local BasePlate = game.Workspace.Baseplate
local time = 30 -- seconds
wait(5)
while wait(1) do
-- count how many players are left
local playersFound = {}
local totalPlayersFound = 0
local partsInRegion = workspace:FindPartsInRegion3(region, baseplate, 1000)
for i, part in pairs(partsInRegion) do
if part.Parent:FindFirstChild("Humanoid") ~= nil then
-- keep track of all the players still alive
-- since a player's character is made of many parts, each player will show up multiple times,
-- so only hold onto each player once
local character = part.Parent
if (playersFound[character.Name] == nil) then
playersFound[character.Name] = character
print ("Found Player : ", character.Name)
totalPlayersFound = totalPlayersFound + 1
end
end
end
-- EDIT BASED ON COMMENTS --
-- update the UI based on the game state
if time == 0 then
Status.Value = "Round over!"
break
elseif totalPlayersFound == 1 then
-- since we know that there's only one entry in the playersFound table,
-- grab it using the next() function
local playerName, character = next(playersFound)
StatusValue = "Winner : " .. playerName
wait(5)
break
--elseif totalPlayersFound == 0 then
-- make sure to check in case no players are left
else
Status.Value = tostring(totalPlayersFound) .. " players in round"
time = time - 1
-- DEBUG :
-- print("There are " .. tostring(totalPlayersFound) .. " players in the round")
-- for playerName, character in pairs(playersFound) do
-- print(" - " .. playerName .. " is still in the game")
-- end
end
end
As for your bonus question, you should ask a follow up question and post the code that shows how you're creating the label and updating it.

How to run code when any object with the same name is touched

So I'm trying to develop a small coin collecting game on Roblox, and am pretty new to scripting. Basically Every 0.25 - 1.5 seconds, a small part is cloned from (-254, 2, -255) (one corner of the baseplate), to (254, 2, 255) (the opposite corner). That works, but im trying to loop over every object in workspace named coin, and when one is touched, run code (for now im just trying to destroy the object but ill probably just update the Coins leaderstat). It doesn't give me any errors, it just doesnt work. I've also looked all over the internet, and cant find anything.
Code in ServerScriptStorage (spawns cubes and already works, but showed it for help.):
local runservice = game:GetService("RunService")
local interval = math.random(0.25, 1.5)
local coin = game.ServerStorage.coin
local counter = 0
local x = math.random(-254, 254)
local z = math.random(-255, 255)
runservice.Heartbeat:Connect(function(step)
counter = counter + step
if counter >= interval then
counter = counter - interval
local copy = coin:Clone()
copy.Parent = workspace
copy.Position = Vector3.new(x, 2, z)
x = math.random(-254, 254)
z = math.random(-255, 255)
interval = math.random(0.25, 1.5)
end
end)
script in desktop that handles the touching:
for _, v in pairs(workspace:GetChildren()) do
if v.Name == "coin" then
print("foo")
end
end
I hope this is enough to help!
Well as you are new to scripting in roblox let me give you your answer with good practices that may help you a lot.
First in this scenario you dont need to use Heartbeat, instead you could simple use a while loop or a recursive function and a simple wait().
Also you better create a "Coins" Folder in workspace in order to not check other objects
local waitTime = math.random(25,150)/100 --random time between 0.25 and 1.5
while true do --forever loop
wait(waitTime) --waits desired time
local coin = game.ServerStorage.coin:Clone() --cloning your coin
coin.Parent = workspace.Coins --Coins folder
coin.Position = Vector3.new(math.random(0,10),2,math.random(0,10)) --you must use your own position
coin.Touched:Connect(function(hitPart) --here is the touched function
local plr = game.Players:FindFirstChild(hitPart.Parent.Name) --check if the hitPart is part of a player
if plr then
plr.leaderstats.Coins.Value = plr.leaderstats.Coins.Value + 1--here you can increment your coins value in your own value
coin:Destroy()--destroys the coin
end
end)
waitTime = math.random(25,150)/100 --set a new random value to wait next
end
Also you mentioned something about loop every coin in workspace, thats why I said it is better to create a separate folder. So I made a localscript inside StarterPlayerScripts with the following code:
local RunService = game:GetService("RunService") --service
RunService.RenderStepped:Connect(function() --function on every game frame
for i,v in pairs(workspace.Coins:GetChildren()) do --loop on every coin
v.Orientation = Vector3.new(v.Orientation.X,v.Orientation.Y+5,v.Orientation.Z) --increasing Orientation just on Y in order to rotate them
end
end)
I'm doing this on localscript because is just a visual effect and it is never a good idea to send that many functions that quickly serverside. Here is the game I made for you:
https://www.roblox.com/games/5842250223/Help-for-TextBasedYoutube
You can edit the place.
In other words to answer "How to run code when any object with the same name is touched?"
You need to set the function for the object when creating it.
Edit: Also is not a good idea to send to many request to the server in short periods of time, I would recommend you to create a coin ever 2 to 3 seconds or more.

Resources