I’m working on a claimable house system where players can buy a house. Each house will have a sign with a proximity prompt that says "Buy House." Once purchased, the player will own the house and be able to lock/unlock the door. The sign will also display their avatar and username.
However, nothing works. The coins do not deduct from my leaderboard, and the info on the sign doesn’t update either.
I would really appreciate any help with this!
Sign Script.
local ProximityPrompt = script.Parent.ProximityPrompt local SurfaceGui = script.Parent.SurfaceGui local ProfileService = require(game.ServerScriptService.Modules.ProfileService) local COST = 400 ProximityPrompt.Triggered:Connect(function(player) if not ProfileService or not ProfileService.GetProfileAsync then warn("ProfileService is not loaded or missing GetProfileAsync function!") return end local profile = ProfileService.GetProfileAsync(player.UserId) if not profile then warn("Failed to retrieve profile for player: " .. player.UserId) return end if profile.Coins < COST then game:GetService("StarterGui"):SetCore("SendNotification", { Title = "Insufficient Coins"; Text = "You do not have enough coins to purchase this."; Duration = 3; }) return end profile.Coins = profile.Coins - COST SurfaceGui.NameLabel.Text = player.Name SurfaceGui.AvatarImage.Image = "rbxthumb://type=AvatarHeadShot&id=" .. player.UserId .. "&w=100&h=100" ProximityPrompt.Enabled = false script.Parent:SetAttribute("Owner", player.UserId) end)
Door Script:
local ProximityPrompt = script.Parent.ProximityPrompt local ownerID = script.Parent.Parent.BuyHouseSign:GetAttribute("Owner") local doorLocked = false local function updateDoor(locked) doorLocked = locked ProximityPrompt.ActionText = locked and "Unlock" or "Lock" script.Parent.Transparency = locked and 0 or 0.7 script.Parent.CanCollide = locked end ProximityPrompt.Triggered:Connect(function(player) if player.UserId ~= ownerID then player:warn("Only the house owner can lock/unlock this door.") return end updateDoor(not doorLocked) end)
If the issue lies with the profile service then this is what I have:
DataManagerScript
local Players = game:GetService("Players") local serverScriptService = game:GetService("ServerScriptService") local modules = serverScriptService:WaitForChild("Modules") local ProfileService = require(modules:WaitForChild("ProfileService")) local template = require(script:WaitForChild("Template")) local leaderstats = require(script:WaitForChild("Leaderstats")) local datakey = "_DataStore" local profileStore = ProfileService.GetProfileStore(datakey, template).Mock local dataManager = {} dataManager.Profiles = {} local function PlayerAdded(player: Player) local profile = profileStore:LoadProfileAsync("Player_"..player.UserId) if profile ~= nil then profile:AddUserId(player.UserId) profile:Reconcile() profile:ListenToRelease(function() dataManager.Profiles[player] = nil player:Kick() end) if player:IsDescendantOf(Players) then dataManager.Profiles[player] = profile leaderstats:Create(player, profile) else profile:Release() end else player:Kick() end end local function PlayerRemoving(player: Player) local profile = dataManager.Profiles[player] if profile ~= nil then profile:Release() end end for _, player in Players:GetPlayers() do task.spawn (PlayerAdded, player) end Players.PlayerAdded:Connect(PlayerAdded) Players.PlayerRemoving:Connect(PlayerRemoving) return dataManager
Instead of grabbing the player’s profile directly from the ProfileService module, why don’t you just get it from your cached table of profiles inside dataManager?
function dataManager.GetProfile(player) if not player:IsDescendantOf(Players) then return end local profile = dataManager.Profiles[player] while profile == nil do profile = dataManager.Profiles[player] task.wait() end return profile end
Put this function inside your dataManager module, require the dataManager module instead of ProfileService and get the player’s profile from there
Update: I got it working, but the issue is the money doesn’t deduct when buying the house.
Door Script:
local ProximityPrompt = script.Parent.ProximityPrompt local SurfaceGui = script.Parent.SurfaceGui local dataManager = require(game.ServerScriptService.Modules.DataManager) local COST = 400 ProximityPrompt.Triggered:Connect(function(player) local profile = dataManager.GetProfile(player) if not profile then warn("Failed to retrieve profile for player: " .. player.UserId) return end if profile.Data.Coin < COST then game:GetService("StarterGui"):SetCore("SendNotification", { Title = "Insufficient Coin", Text = "You do not have enough Coin to purchase this.", Duration = 3, }) return end profile.Data.Coin = profile.Data.Coin - COST print(player.Name .. " has " .. profile.Data.Coin .. " Coin(s) remaining.") -- Debug SurfaceGui.OwnerName.Text = player.Name SurfaceGui.PlayerImage.Image = "rbxthumb://type=AvatarHeadShot&id=" .. player.UserId .. "&w=100&h=100" ProximityPrompt.Enabled = false script.Parent:SetAttribute("Owner", player.UserId) end)
The script of the sign and the door are both client, but the Profileservice is all in ServerScriptService
The infinite yield of the proximity prompt comes from StarterPlayerScripts which has this script:
local ProximityPrompt = script.Parent:WaitForChild("ProximityPrompt") local doorOwnerId = script.Parent.Parent:GetAttribute("Owner") ProximityPrompt.Triggered:Connect(function(player) if player.UserId == doorOwnerId then if ProximityPrompt.ActionText == "Lock House" then -- Lock the door: only the owner can enter script.Parent.CanCollide = true script.Parent.Transparency = 0 ProximityPrompt.ActionText = "Unlock House" else script.Parent.CanCollide = false script.Parent.Transparency = 0.7 ProximityPrompt.ActionText = "Lock House" end end end)
The proximity prompt isn’t being found, that is why it is giving that error. Try checking if it is in the right place.
Try this code, I didn’t check if it works because I wrote this on my phone, it just adds a save feature right after you purchase the house
local ProximityPrompt = script.Parent.ProximityPrompt local SurfaceGui = script.Parent.SurfaceGui local dataManager = require(game.ServerScriptService.Modules.DataManager) local COST = 400 ProximityPrompt.Triggered:Connect(function(player) local profile = dataManager.GetProfile(player) if not profile then warn("Failed to retrieve profile for player: " .. player.UserId) return end if profile.Data.Coin < COST then game:GetService("StarterGui"):SetCore("SendNotification", { Title = "Insufficient Coin", Text = "You do not have enough Coin to purchase this.", Duration = 3, }) return end profile.Data.Coin = profile.Data.Coin - COST print(player.Name .. " has " .. profile.Data.Coin .. " Coin(s) remaining.") -- Debug dataManager.SaveProfile(player, profile) SurfaceGui.OwnerName.Text = player.Name SurfaceGui.PlayerImage.Image = "rbxthumb://type=AvatarHeadShot&id=" .. player.UserId .. "&w=100&h=100" ProximityPrompt.Enabled = false script.Parent:SetAttribute("Owner", player.UserId) end)
Forgive me for my late reply. I’ve had a hectic week. I attempted your code, and this is what I got in the output.
[ProfileService]: Roblox API services available - data will be saved - Server - ProfileService:2307 User has 0 Coin(s) remaining. - Server - Script:25 Infinite yield possible on 'Players.User.PlayerScripts:WaitForChild("ProximityPrompt")' - Studio Stack Begin - Studio Script 'Players.User.PlayerScripts.HousePurchaseClient', Line 1 - Studio - HousePurchaseClient:1 Stack End - Studio
The proximity prompt isn’t being found, that is why it is giving that error. Try checking if it is in the right place.
That script is in Starterplayerscripts. Perhaps I should specify it more where the prompt can be found initially? That proximity prompt is actually in workspace → Houses (folder) → Door (part) → Proximityprompt