My script doesn't work as it should, I don't know how to fix it

I created a script for boost and when I have a boost and I buy a boost, both the new boost and the old one are written to me, but when I re-enter, it is corrected, help me fix it, I don’t know what’s wrong

local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local eventPsychic = game.ReplicatedStorage.AddPsychic
local eventStats = game.ReplicatedStorage.AddStat
local alertClients = game.ReplicatedStorage.ServerMessage
local moduleSc = require(game.ReplicatedStorage.Abbreviate)

local strengthPass = 951364908  -- Game pass ID for Strength
local endPass = 951033342        -- Game pass ID for Endurance
local gamepassId = 951923075     -- Game pass ID for Psychic

local eventMultiplier = 1  -- Initial multiplier value
local boostDurations = {
    ["15M"] = 15 * 60,
    ["1H"] = 1 * 60 * 60,
    ["6H"] = 6 * 60 * 60,
    ["12H"] = 12 * 60 * 60,
    ["1D"] = 24 * 60 * 60,
    ["1W"] = 7 * 24 * 60 * 60
}

local activeBoosts = {}
local playerBoostsDataStore = DataStoreService:GetDataStore("PlayerBoosts")

local function ownsGamePass(userId, gamepassId)
    local ownsGamepass = false
    local success, res = pcall(function()
        ownsGamepass = MarketplaceService:UserOwnsGamePassAsync(userId, gamepassId)
    end)
    return success and ownsGamepass
end

local function calculateTotalMultiplier(player)
    local multiplier = 1

    if ownsGamePass(player.UserId, strengthPass) then
        multiplier = multiplier * 2
    end

    if ownsGamePass(player.UserId, endPass) then
        multiplier = multiplier * 2
    end

    if ownsGamePass(player.UserId, gamepassId) then
        multiplier = multiplier * 2  -- Increase multiplier if player owns Psychic game pass
    end

    if activeBoosts[player.UserId] then
        multiplier = multiplier * 2  -- Increase multiplier by 2 for active boost
    end

    multiplier = multiplier * eventMultiplier

    return multiplier
end

local function showPopUp(player, value)
    local popUpGui = player.PlayerGui:FindFirstChild("PopUpGui") or Instance.new("ScreenGui", player.PlayerGui)
    popUpGui.Name = "PopUpGui"

    local newLabel = game.ReplicatedStorage.PopUpText:Clone()
    newLabel.Parent = popUpGui
    local random = math.random(1, 900)
    local newX = random / 1000
    newLabel.Position = UDim2.new(newX, 0, 1, 0)
    newLabel.Text = "+" .. moduleSc.abbreviate(value) .. " 🧠"
end

eventPsychic.OnServerEvent:Connect(function(player, value, operator)
    if operator == "-" then
        player.Psp.Value -= value
    else
        local class = player.leaderstats.Class
        local fusion = player.BestFusion.FusionMulti
        local mults = require(game.ServerStorage["classMults"])
        local classMult = mults[class.Value] or 1  -- Get class multiplier

        local pointsToAdd = (player.Character.SafeZone.Start.Value and value * player.pZoneMulti.Value * classMult * fusion.Value * eventMultiplier) or 0
        pointsToAdd = pointsToAdd + value * player.pZoneMulti.Value * classMult * fusion.Value * eventMultiplier

        local totalMultiplier = calculateTotalMultiplier(player)
        pointsToAdd *= totalMultiplier  -- Apply total multiplier

        player.Psp.Value += pointsToAdd
        showPopUp(player, pointsToAdd)
    end
end)

-- Update time in player's UI
local function updateBoostTimeUI(player, duration)
    local gui = player:WaitForChild("PlayerGui"):WaitForChild("GamepassShop"):WaitForChild("Frame"):WaitForChild("BoostFrame")
    local timeText = gui:WaitForChild("Time")

    local endTime = tick() + duration

    while tick() < endTime do
        local remainingTime = endTime - tick()
        local days = math.floor(remainingTime / (24 * 3600))
        local hours = math.floor((remainingTime % (24 * 3600)) / 3600)
        local minutes = math.floor((remainingTime % 3600) / 60)
        local seconds = math.floor(remainingTime % 60)

        timeText.Text = string.format("%d:%02d:%02d:%02d", days, hours, minutes, seconds)
        wait(1)  -- Update text every second
    end

    -- Reset text after completion
    timeText.Text = "0:00:00:00"
end

-- Activate boost
local function activateBoost(player, boostType)
    local duration = boostDurations[boostType]
    if duration then
        -- Set active boost
        activeBoosts[player.UserId] = (activeBoosts[player.UserId] or 0) + duration  -- Save total active boost time

        -- Save boost info in DataStore
        playerBoostsDataStore:SetAsync(player.UserId, activeBoosts[player.UserId])

        -- Set timer for deactivating boost
        task.spawn(function()
            updateBoostTimeUI(player, duration)  -- Update time in UI
            activeBoosts[player.UserId] = activeBoosts[player.UserId] - duration  -- Decrease total active boost time
            print("Boost for player " .. player.Name .. " has ended.")
            playerBoostsDataStore:RemoveAsync(player.UserId)  -- Remove boost info from DataStore
        end)
    end
end

-- Load player's boost state on entry
local function loadPlayerBoost(player)
    local success, result = pcall(function()
        return playerBoostsDataStore:GetAsync(player.UserId)
    end)

    if success and result then
        activeBoosts[player.UserId] = result
        -- Start timer if boost is still active
        if result > tick() then
            local remainingTime = result - tick()
            updateBoostTimeUI(player, remainingTime)
        else
            activeBoosts[player.UserId] = nil  -- Remove boost if time is up
        end
    end
end

-- Event handler
eventStats.OnServerEvent:Connect(function(player, stat, val, op)
    local value = val
    local playerStat = player:FindFirstChild(stat) or player.leaderstats:FindFirstChild(stat)

    if not playerStat then
        warn("Stat not found for player:", player.Name, "Stat:", stat)
        return
    end

    if op == "activateBoost" then
        activateBoost(player, value)  -- value will be the boost type
        return
    end

    local totalMultiplier = calculateTotalMultiplier(player)

    if op == "+" then
        local inSafeZone = player.Character and player.Character:FindFirstChild("SafeZone") and player.Character.SafeZone.Start.Value

        if not inSafeZone then
            playerStat.Value += value * totalMultiplier

            if stat == "Endurance" or stat == "Strength" or stat == "Psp" then
                local random = math.random(1, 900)
                local newX = random / 1000

                local newLabel = game.ReplicatedStorage.PopUpText:Clone()
                newLabel.Parent = player.PlayerGui:WaitForChild("PopUpGui")
                newLabel.Position = UDim2.new(newX, 0, 1, 0)
                newLabel.Text = "+" .. moduleSc.abbreviate(value * totalMultiplier) .. (stat == "Endurance" and " 🛡" or stat == "Strength" and " 💪" or " 🧠")
            end
        end
    elseif op == "set" then
        if typeof(value) == "number" and not string.match(stat, "Multi") then
            playerStat.Value = value * totalMultiplier
        else
            playerStat.Value = value
        end
        if string.match(stat, "Class") then
            alertClients:FireAllClients(player.Name .. " has ranked up to " .. value .. "!")
        end
    end
end)

-- Purchase handler
MarketplaceService.ProcessReceipt = function(receiptInfo)
    local playerId = receiptInfo.PlayerId
    local productId = receiptInfo.ProductId

    local player = Players:GetPlayerByUserId(playerId)
    if not player then
        return Enum.ProductPurchaseDecision.NotProcessedYet
    end

    if productId == 2320871950 then -- Product for Strength
        activateBoost(player, "15M") -- Example: activate 15-minute boost
    elseif productId == 2320871955 then -- Product for Endurance
        activateBoost(player, "1H") -- Example: activate 1-hour boost
    elseif productId == 2320871956 then -- Product for Endurance
        activateBoost(player, "6H") -- Example: activate 6-hour boost
    elseif productId == 2320871957 then -- Product for Endurance
        activateBoost(player, "12H") -- Example: activate 12-hour boost
    elseif productId == 2320871958 then -- Product for Endurance
        activateBoost(player, "1D") -- Example: activate 1-day boost
    elseif productId == 2320868212 then -- Product for Endurance
        activateBoost(player, "1W") -- Example: activate 1-week boost
    end

    return Enum.ProductPurchaseDecision.PurchaseGranted
end

-- Load player boosts when they join the game
Players.PlayerAdded:Connect(loadPlayerBoost)

print("Game pass system is ready.")
1 Like

robloxapp-20241028-2044357.wmv (2.4 MB)

1 Like

This is still relevant and I don’t understand what the problem is and haven’t solved the problem

1 Like

This is still relevant I didn’t fix it Any help is appreciated

If I’m not mistaken, the problem lies in the way you call the function updateBoostTimeUI.

The while loop will continue to run in the background until the conditions are met. When you call updateBoost the second time, you’re starting another while loop and not ending the first, resulting in two while loops running simultaneously.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.