Help with saving decal & player

Hello. I am currently working on a game where you can purchase a frame, and put any decal you want on it, and it says there forever. Currently, I have made the frame, and a metal plate below it saying the price. I want it to say when it has been bought, it displays the name of the buyer. I have never worked with DataStores before and I an quite new to scripting, and I want to work on this as my first project. I currently do not know how to save the owner of the frame, and the decal of the frame. (There will be multiple frames for sale)

3 Likes

There are many tutorials you can find on DataStorages but to start have a look at:

You’re going to most likely want to look at tutorials specifically at saving tables of data in datastorages so you can save a table of all the boards, the owner of them, and the decal ID.

1 Like

Okay. For example, if someone buys a frame, I save their Id, then save the decal id? Then when a server starts, I load the owners name and then change the image to the saved decal?

1 Like

You would have to save it in a table so you can save all the relevant data, but other than that yes.

2 Likes

Are there any examples of this?

1 Like

I think this would work?

local Event = game.ReplicatedStorage.RemoteEvent
local DSS = game:GetService("DataStoreService")
local DS = DSS:GetDataStore("DecalData")
-- have it fire this event when the player purchases it
-- have the "data" variable (or whatever you name it) be a table containing the UserId of the player who purchased it, the Decal being edited, and the Decal Id (Decal first, Decal Id second, Player UserId third)
-- also make sure in the script for purchasing that the Decals in the table are in the same order
Event.OnServerEvent:Connect(function(data)
	local DecalNumber = data[1]
	local DecalId = data[2]
	local UserId = data[3]
	local epicdata = { -- name this variable whatever you want
		DecalId,
		UserId
	}
	DS:SetAsync(DecalNumber, epicdata)
end)

and in another script

local DSS = game:GetService("DataStoreService")
local DS = DSS:GetDataStore("DecalData")
local Players = game:GetService("Players")
local Decals = {
	workspace.Part.Decal
	-- Define all the decals here
}
local TextLabels = {
	workspace.Part2.TextLabel
	-- Define all the textlabels here, also you can write this so that these don't have to be in the same order
	-- but for simplicities sake put the textlabels in the same order as the Decals
}
while wait(10) do
	for i in pairs(Decals) do
		local data = DS:GetAsync(i)
		if data then
			local textlabel = TextLabels[i]
			local decal = Decals[i]
			local ImgId = data[1]
			local Player = data[2]
			local PlayerName = Players:GetNameFromUserIdAsync(Player)
			textlabel.Text = PlayerName
			decal.Texture = ImgId
		end
	end
end
2 Likes

Would you be able to tell me where to put these scripts & what kind of scripts?

1 Like

those are both server scripts, and you would put them in serverscriptservice

2 Likes

The frame: image
In the Buy prompt:

script.Parent.Triggered:Connect(function(plr)
	
	print(plr.UserId)
	
	game.ReplicatedStorage.RemoteEvent:FireServer(script.Parent.Parent.Parent, 143751304, plr.UserId)
end)

image
In changepainting:

local DSS = game:GetService("DataStoreService")
local DS = DSS:GetDataStore("DecalData")
local Players = game:GetService("Players")
local FrameFolder = workspace.Frames
local Decals = {
	FrameFolder.FrameSM1,

}
local Plates = {
	FrameFolder.FrameSM1.MetalFrame,
}
while wait(10) do
	for i in pairs(Decals) do
		local data = DS:GetAsync(i)
		if data then
			local Plates = Plates[i]
			local decal = Decals[i]
			local ImgId = data[1]
			local Player = data[2]
			local PlayerName = Players:GetNameFromUserIdAsync(Player)
			Plates.Header.Donated.SurfaceGui.SIGN.Text = "This painting has been donated by:"
			Plates.Header.Giver.SurfaceGui.SIGN.Text = PlayerName
			decal.Image.Facer.Texture = ImgId
			decal.Curtain.Transparency = 1
		end
	end
end

in onserverevent:

local Event = game.ReplicatedStorage.RemoteEvent

local DSS = game:GetService("DataStoreService")

local DS = DSS:GetDataStore("DecalData")

-- have it fire this event when the player purchases it

-- have the "data" variable (or whatever you name it) be a table containing the UserId of the player who purchased it, the Decal being edited, and the Decal Id (Decal first, Decal Id second, Player UserId third)

-- also make sure in the script for purchasing that the Decals in the table are in the same order

Event.OnServerEvent:Connect(function(data)

print("caught")

local DecalNumber = data[1]

local DecalId = data[2]

local UserId = data[3]

local DataTable = { -- name this variable whatever you want

DecalId,

UserId

}

DS:SetAsync(DecalNumber, DataTable)

end)

do you see anything wrong that I have done? again, I don’t script that much.
Nothing changes, and it doesn’t print “Caught”

1 Like

i haven’t looked through all of it, but in the buy prompt localscript you sent the model instead of the decal

2 Likes

That was intentional. In changepainting, the decal is the model. I just didnt change the name of it. (sorry about that)

1 Like

i think i might’ve found the problem? I don’t think I made it clear that you should send the number of decals, not the decals themselves

2 Likes

How would I fix it? I don’t think I understand that.

1 Like

Make a table of all the decals, and when you send the data from the client to the server send #(name of the table) instead of the table itself.

2 Likes

Could you create an example of it while I try and do it myself? This is quite confusing for me.

1 Like

You’ll easily hit datastore limits with this, you need to leave 6 seconds between every datastore request to not exceed your limits.

1 Like

That is simply not true, I know this because I’ve sent multiple datastore requests at nearly the same time before and it work just fine

1 Like

I think this should work?

local Players = game:GetService("Players")
local plr = Players.LocalPlayer

script.Parent.Triggered:Connect(function()

	print(plr.UserId)
	
	local sendData = {
		1, -- change to be whatever number it coresponds to in the table in the "changepainting" script
		143751304,
		plr.UserId
	}
	
	game.ReplicatedStorage.RemoteEvent:FireServer(sendData)
	
end)
1 Like

Errors only occur when you try to send more than 10 requests per player in a minute (there is also an extra 20 requests that can be used, but it should be only used for server functions, as it doesn’t scale with players).

1 Like

I’ve changed the local script, but it’s still not even printing.

1 Like