You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? I want some help to possibly fix some bugs in a script I have made.
-
What is the issue? I’m making a system where you buy a developer product and then it will spawn a certain amount of parts at a part in the workspace. The problem is, is sometimes the script works and spawns the parts but most of the time it only prompts me with my product and it doesn’t spawn the parts?
-
What solutions have you tried so far? I’ve tried to change different things inside my script to make it detect the folder in server storage with the parts so if it doesn’t find the folder it will keep trying. I’m really stuck on this and I could use some help. Thanks
local MarketplaceService = game:GetService("MarketplaceService")
local ServerStorage = game:GetService("ServerStorage")
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local promptConfig = {
{partName = "Prompt1", devProductId = 3418468965},
{partName = "Prompt2", devProductId = 3418479390},
{partName = "Prompt3", devProductId = 3418479558},
{partName = "Prompt4", devProductId = 3418479923},
{partName = "Prompt5", devProductId = 3418480074},
{partName = "Prompt6", devProductId = 3418480475},
{partName = "Prompt7", devProductId = 3418480567},
{partName = "Prompt8", devProductId = 3418480647},
{partName = "Prompt9", devProductId = 3418482472},
{partName = "Prompt10", devProductId = 3418482589},
{partName = "Prompt11", devProductId = 3418482854},
{partName = "Prompt12", devProductId = 3418482940},
{partName = "Prompt13", devProductId = 3418483009},
{partName = "Prompt14", devProductId = 3418483164},
{partName = "Prompt15", devProductId = 3418483233},
{partName = "Prompt250", devProductId = 3418502347},
}
local devProductIdToSpawnCount = {}
for i, config in promptConfig do
local promptNumber = tonumber(config.partName:match("%d+")) or 1
devProductIdToSpawnCount[config.devProductId] = promptNumber * 2
end
local function getPrompt(part)
for k, v in part:GetChildren() do
if v:IsA("ProximityPrompt") then
return v
end
end
return nil
end
local function spawnShapes(player, count)
print("[DevProductSpawner] spawnShapes called for player:", player and player.Name or "nil", "count:", count)
local objectsFolder = ServerStorage:FindFirstChild("Objects")
if not objectsFolder then
warn("[DevProductSpawner] ServerStorage.Objects folder not found at spawn time")
return false, "ObjectsFolderMissing"
end
local objects = objectsFolder:GetChildren()
local totalObjects = #objects
print("[DevProductSpawner] Objects in folder:", totalObjects)
if totalObjects == 0 then
warn("[DevProductSpawner] No objects found in ServerStorage.Objects")
return false, "ObjectsEmpty"
end
local spawnPart = Workspace:FindFirstChild("SpawnPart")
local baseCFrame
if spawnPart then
baseCFrame = spawnPart:GetPivot()
print("[DevProductSpawner] Using SpawnPart at:", tostring(baseCFrame.Position))
else
warn("[DevProductSpawner] Workspace.SpawnPart not found, spawning at origin")
baseCFrame = CFrame.new(0, 5, 0)
end
local spawned = 0
local objIndex = 1
for i = 1, count do
local obj = objects[objIndex]
if obj then
local clone = obj:Clone()
clone.Parent = Workspace
if clone:IsA("Model") then
clone:PivotTo(baseCFrame)
print("[DevProductSpawner] Spawned Model: " .. tostring(clone.Name) .. " at " .. tostring(baseCFrame.Position))
elseif clone:IsA("BasePart") then
clone.CFrame = baseCFrame
print("[DevProductSpawner] Spawned Part: " .. tostring(clone.Name) .. " at " .. tostring(baseCFrame.Position))
else
print("[DevProductSpawner] Spawned object: " .. tostring(clone.Name) .. " (type: " .. clone.ClassName .. ")")
end
spawned = spawned + 1
else
warn("[DevProductSpawner] Object index " .. tostring(objIndex) .. " not found in objects list")
end
objIndex = objIndex + 1
if objIndex > totalObjects then
objIndex = 1
end
end
local leaderstats = player and player:FindFirstChild("leaderstats")
if leaderstats then
local amountDropped = leaderstats:FindFirstChild("AmountDropped")
if amountDropped then
amountDropped.Value = amountDropped.Value + spawned
else
warn("[DevProductSpawner] AmountDropped leaderstat not found for player: " .. (player and player.Name or "nil"))
end
else
warn("[DevProductSpawner] leaderstats not found for player: " .. (player and player.Name or "nil"))
end
print("[DevProductSpawner] Finished spawning " .. tostring(spawned) .. " objects for " .. (player and player.Name or "nil"))
if spawned > 0 then
return true
else
return false, "NothingSpawned"
end
end
for i, config in promptConfig do
local part = Workspace:FindFirstChild(config.partName)
if part then
local prompt = getPrompt(part)
if prompt then
prompt.Triggered:Connect(function(player)
MarketplaceService:PromptProductPurchase(player, config.devProductId)
print("[DevProductSpawner] Prompted product purchase for " .. player.Name .. " (" .. config.partName .. ")")
end)
else
warn("[DevProductSpawner] No ProximityPrompt found in part: " .. config.partName)
end
else
warn("[DevProductSpawner] Part not found in Workspace: " .. config.partName)
end
end
local function getPlayerByUserIdWithRetry(userId, maxWait)
local player = Players:GetPlayerByUserId(userId)
local waited = 0
while not player and waited < maxWait do
task.wait(0.2)
waited = waited + 0.2
player = Players:GetPlayerByUserId(userId)
end
return player
end
local processedReceipts = {}
MarketplaceService.ProcessReceipt = function(receiptInfo)
print("[DevProductSpawner] ProcessReceipt called for ProductId: " .. tostring(receiptInfo.ProductId) .. ", PlayerId: " .. tostring(receiptInfo.PlayerId) .. ", ReceiptId: " .. tostring(receiptInfo.PurchaseId))
if processedReceipts[receiptInfo.PurchaseId] then
warn("[DevProductSpawner] Receipt already processed: " .. tostring(receiptInfo.PurchaseId))
return Enum.ProductPurchaseDecision.PurchaseGranted
end
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
print("[DevProductSpawner] Player not found for receipt: " .. tostring(receiptInfo.PlayerId) .. ", retrying for up to 5 seconds...")
player = getPlayerByUserIdWithRetry(receiptInfo.PlayerId, 5)
if not player then
warn("[DevProductSpawner] Player still not found after retry for receipt: " .. tostring(receiptInfo.PlayerId))
return Enum.ProductPurchaseDecision.NotProcessedYet
else
print("[DevProductSpawner] Player found after retry: " .. player.Name)
end
end
local spawnCount = devProductIdToSpawnCount[receiptInfo.ProductId]
print("[DevProductSpawner] spawnCount for ProductId:", receiptInfo.ProductId, "is", spawnCount)
if spawnCount then
local success, failReason = spawnShapes(player, spawnCount)
if success then
print("[DevProductSpawner] Purchase granted for " .. player.Name .. ", spawned " .. tostring(spawnCount) .. " objects.")
processedReceipts[receiptInfo.PurchaseId] = true
return Enum.ProductPurchaseDecision.PurchaseGranted
else
warn("[DevProductSpawner] spawnShapes failed for player: " .. player.Name .. " (reason: " .. tostring(failReason) .. ")")
if failReason == "ObjectsFolderMissing" then
warn("[DevProductSpawner] ServerStorage.Objects folder missing at time of spawn.")
elseif failReason == "ObjectsEmpty" then
warn("[DevProductSpawner] ServerStorage.Objects folder is empty.")
elseif failReason == "NothingSpawned" then
warn("[DevProductSpawner] No objects were spawned, possible logic error.")
end
return Enum.ProductPurchaseDecision.NotProcessedYet
end
else
warn("[DevProductSpawner] Unknown dev product ID: " .. tostring(receiptInfo.ProductId))
return Enum.ProductPurchaseDecision.NotProcessedYet
end
end
This is my first time posting im not sure how all of this works.
