Trying to make a zone system like pet sim x

Basically i got a script inside a proximityprompt:

local plr = game:GetService("Players").PlayerAdded:Connect(function(plr)
local leadestats = plr:FindFirstChild("leaderstats")
local goldStats = leadestats and leadestats:FindFirstChild("Cash")
	script.Parent.TriggerEnded:Connect(function()
		if goldStats then
			goldStats.Value -= 300
			script.Parent.Parent:Destroy()
			plr.Bools.zone1.Value = true
		else
			print("you cant buy this lol")
		end
	end)
end)

and it just takes away 300 cash and sets ur boonlean to be true, (and that datastore script should save it which it does i think)

and heres a different script that deletes the thingy if the boonlean value is true:

local plr = game.Players.LocalPlayer
if plr.Bools.zone1.Value == true then
	script.Parent:Destroy()
end

A few things:

Using TriggerEnded will activate even if the user does not finish activating the prompt. If a player starts to activate the prompt to buy the zone, but then changes their mind and stops before the prompt has finished activating, it will still attempt to buy the zone. I would change it to Triggered instead.

Assuming this is a server script: When one player buys the zone, the server script will destroy the proximity prompt for every single player, meaning no one else will be able to purchase the zone. You can fix this by using a LocalScript to destroy the prompt once the player buys it (since LocalScripts only affect the client they are running on), and a Server script to take their money and enable their boolValue.

The script is immediately trying to get the player’s leaderstats folder as soon as the player joins. If it isn’t created within that very short time frame, then it will equal nil; when you’re getting the goldStats folder, it will also equal nil as leaderstats doesn’t exist. You can fix this by using :WaitForChild instead of :FindFirstChild when trying to get both leaderstats and goldStats.

Well i changed everything and now i can’t even buy the zone.

It just doesn’t work on a local script

My fault, I didn’t realize ProximityPrompt.Triggered only works on the server. In that case, you can use a RemoteEvent to tell the client to destroy the prompt.

Server Script inside ProximityPrompt
local zonePurchasedEvent = game:GetService("ReplicatedStorage").ZonePurchasedEvent
script.Parent.Triggered:Connect(function(player)
	local leaderstats = player:FindFirstChild("leaderstats")
	local goldStats = leaderstats:FindFirstChild("Cash")
	if goldStats then
		if goldStats.Value >= 300 then
			goldStats.Value -= 300
			player.Bools.zone1.Value = true
			zonePurchasedEvent:FireClient(player, script.Parent)
		else
			print("you cant buy this lol")
		end
	end
end)
Local Script inside StarterPlayerScripts
game:GetService("ReplicatedStorage"):WaitForChild("ZonePurchasedEvent").OnClientEvent:Connect(function(promptToDestroy)
	promptToDestroy:Destroy()
end)