badge giver help (roblox) - lua

So, I'm working on a Roblox game, I want to make a secret room and award players a badge for finding it, but the problem is that the badge giver is not working, my badge giver is also locked so that I don't accidentally put it in a map. It's also behind a code door and surrounded by locked parts. Here is my code.
local badgeService = game:GetService("BadgeService")
local id = 2133435079
script.Parent.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
badgeService:AwardBadge(plr.UserId,id)
end
end)
I tried unlocking the badge giver but that didn't work.
I also tried regular test but that also didn't work

Based on the error, it sounds like you're not protecting against the case that plr is nil. This can happen if hit.Parent isn't a player's character model.
local badgeService = game:GetService("BadgeService")
local players = game:GetService("Players")
local id = 2133435079
script.Parent.Touched:Connect(function(hit)
local plr = players:GetPlayerFromCharacter(hit.Parent)
if plr then
badgeService:AwardBadge(plr.UserId, id)
end
end)

Related

Keycard door not working when i put the keycard at replicates storage

I have a key card door but it don't work when I put it in replicatesStorage (it is a gamepass key) can somebody help me it only work when put in starterPack it is currently being given with a localScript at StartGui ** here is code:
script.Parent.Touched:Connect(function(hit)
if hit.Parent.Name == "Clearance1" then
script.Parent.CanCollide = false
script.Parent.Transparency = 0.5
wait(0.5)
script.Parent.CanCollide = true
script.Parent.Transparency = 0
end
end)
StarterPack is already replicated, in a way.
If you use ReplicatedStorage, you'll have to add it to PlayerInstance.Backpack.
Also, script.Parent.Touched is server-side only.
If you wanna access the player's backpack, you can use game.Players.PLAYERNAME.Backpack
The way you're doing this is actually not a very good idea. (no offense)
I would recommend leaving the item inside the StarterPack. If you really don't want to, you can programmatically do it by putting it in their Backpack. Like this:
-- Server script
game.Players.PlayerAdded:Connect(function(player) -- Runs when a player joins the game
player.CharacterAdded:Connect(function() -- Runs when that player respawns or their character loads
local itemCopy = game.ReplicatedStorage.Clearance1:Clone() -- Creates a copy of the item
itemCopy.Parent = player.Backpack -- Puts the item in the player's backpack (inventory)
end)
end)
What that code does is: Every time the player spawns, it clones the item and puts it in their inventory.
Now to check if the user has the item when they touch the door, you can do something like this:
-- Server script
script.Parent.Touched:Connect(function(part) -- Activates when a part touches the doorf
local player = game.Players:GetPlayerFromCharacter(part.Parent) -- Gets a player from the part that touched
if player and player.Backpack:FindFirstChild("Clearance1") then -- Makes sure there is a player, and the player has the keycard in their inventory
script.Parent.CanCollide = false -- Makes the part uncollidable
script.Parent.Transparency = 0.5 -- Sets the part to have transparency
wait(0.5) -- Waits half a second
script.Parent.CanCollide = true -- Makes the part collidable
script.Parent.Transparency = 0 -- Makes the part not transparent
end
end)
Every time the part is touched, it checks if it's a player. If it is, it checks if the player has the item. If so, it runs the code.

Lua leaderboard in roblox studio

I have my leader board but when i run this it gives me this error:
attempt to index nil with 'leaderstats'
local me = script.Parent
local function GiveMoney(part)
local hum = part.Parent:FindFirstChild("Humanoid")
if hum then
local money = player.leaderstats.Money
money.Value = money.Value + 1
me:Destroy()
end
end
me.Touched:Connect(GiveMoney)
local money = player.leaderstats.Money
or more specifically player.leaderstats causes that error. because player is a nil value and indexing nil values is not allowed as it does not make any sense.
Usually Humanoid's parent is a Model, stored as the Player instance's Character property.
Please read the Roblox documentation and search the web to find out how to access leaderboards and players.
local money = player.leaderstats.Money
I think you forgot to reference "player" because I can't see player variable anywhere

How do I make a shield that lasts for 30 seconds in Roblox using a dev product?

When someone buys my dev product I want them to get a visible shield that lasts for 30 seconds.
Here's the code I have tried:
local mpService = game:GetService("MarketplaceService")
local Debris = game:GetService("Debris")
local function giveForcefield(player, duration)
local character = player.Character
if character then
local forceField = Instance.new("ForceField")
forceField.Visible = true
forceField.Parent = character
if duration then
Debris:AddItem(forceField, duration)
end
end
end
mpService.ProcessReceipt = function(purchaceInfo)
local plr = game:GetService("Players"):GetPlayerByUserId(purchaceInfo.PlayerId)
if purchaceInfo.ProductId == xxxxxxx then
game.Players.PlayerAdded:connect(function(plr)
repeat wait() until plr.Character
local char = plr.Character
giveForcefield(plr, 30)
local forceField = Instance.new("ForceField")
forceField.Visible = true
forceField.Parent = char
end)
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
I can buy the dev product but after the code runs nothing happens.
I have tried a lot of things but I am a bit lost.
Can I get some help, please?
Both of the ways that you have coded for creating and destroying the ForceField are valid, but as Piglet has suggested, your code simply isn't getting called. Your code is saying, "once someone buys this product, wait for another player to join and spawn into the game, then give that new player the forcefield."
Often times, game.Players.PlayerAdded:connect(function(plr) is used as a way to get access to a Player object, but you have already gotten the Player object by calling GetPlayerByUserId, so you can just use that to get access to the Character model.
On an unrelated note, you should only mark a product as PurchaseGranted once the product has been successfully given. By having PurchaseGranted as the default return state, you run the risk of someone buying a product that hasn't been configured yet, and you will just end up taking their money without giving them anything in return.
local PlayerService = game:GetService("Players")
local Debris = game:GetService("Debris")
mpService.ProcessReceipt = function(purchaceInfo)
-- make sure that the player is still in the game
local plr = PlayerService:GetPlayerByUserId(purchaceInfo.PlayerId)
if not plr then
warn("Player could not be found. They might have left")
return Enum.ProductPurchaseDecision.NotProcessedYet
end
if purchaceInfo.ProductId == xxxxxxx then
-- check if their character has spawned
local char = plr.Character
if not char then
warn("Could not find player's character in game")
return Enum.ProductPurchaseDecision.NotProcessedYet
end
-- grant the force field
local forceField = Instance.new("ForceField", char)
-- destroy the force field after a few seconds
local duration = 30
Debris:AddItem(forceField, duration)
-- mark this item as granted
return Enum.ProductPurchaseDecision.PurchaseGranted
end
-- not sure what thing they bought
warn("Unprocessed item receipt", purchaseInfo)
return Enum.ProductPurchaseDecision.NotProcessedYet
end

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

How do I add a Table to a DataStore in Roblox Lua?

GOAL: Make an Inventory system for Hats that saves So when you Buy a hat it adds it to your inventory.
What I have Currently: Right Now I have a IntValue that is added to the player(not character) when they join. This IntValue is named "CurrentHat" and is set to the value of the players last saved hat they were wearing. After this it waits until Character loads to add that hat using CurrentHat's value to the players head by getting it from ServerStorage. Then if CurrentHat's value ever changes it connects it to add player hat function and connects it to the datastore. Below is the portion of the code where the data is added to the game and where I think the inventory data should be added to the game. All the commented out stuff is what I already tried(which failed).
function playeradded(player)
print("hello")
player:LoadCharacter()
local leaderstats = Instance.new("IntValue")
leaderstats.Name = "leaderstats"
local hat = Instance.new("StringValue")
hat.Name = ("CurrentHat")
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Parent = leaderstats
leaderstats.Parent = player
hat.Parent = player
hat.Value = ds2:GetAsync(player.UserId) or math.floor(math.random(0,1))
--table.insert(hattable, hat.Value)
-- ds3:SetAsync(player.UserId,hat.Value)
--for index,value in pairs (hattable) do
-- ds3:UpdateAsync(index, function() return value end)
--end
--print(hattable[1])
--print(ds3)
local playerHat = hat.value
hat.Changed:connect(function()
ds2:SetAsync(player.UserId,hat.Value)
--ds3:SetAsync(player.UserId,table.insert(hat.Value))
--print(ds3)
end)
coins.Value = ds1:GetAsync(player.UserId) or 0
ds1:SetAsync(player.UserId,coins.Value)
A good example of what I would like to do is the popular Roblox game SwordBurst's Inventory system except with only clothing.
I would like to be able to call on the players datastore and if the hat is included in the datastore then show it in their inventory to allow them to put it on. If anyone could help me that would be awesome!
You can't save tables inside of :SetAsync() but you can inside of :UpdateAsync() so if you just do the following it should work:
local clothing = {"Hat1","Shirt1","etc"}
local datastore = game:GetService("DataStoreService"):GetDataStore("Clothing")
datastore:UpdateAsync("A_key",function()
return clothing
end)
These variables are just examples. Please change some things accordingly

Resources