Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
792 views
in Technique[技术] by (71.8m points)

lua - 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.

question from:https://stackoverflow.com/questions/65938615/how-can-i-make-it-so-a-change-of-a-intvalue-is-permanent

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...