How would I pick random data from a datastore?

Hellooou,
Yesterday I succeeded in giving every player that joins my game a unique custom ID with the following script:

	game:GetService("Players").PlayerAdded:Connect(function(Player)
		Player.CharacterAdded:Connect(function(Character)
			local customID = script.PlayersJoined
			customID.Value = DataStore:GetAsync("PlayersJoined")

			if not DataStore:GetAsync("ID"..Player.UserId, customID.Value) then
				customID.Value = customID.Value + 1
				DataStore:SetAsync("PlayersJoined", customID.Value)
				DataStore:SetAsync("ID"..Player.UserId, customID.Value)
			end
			local ID = DataStore:GetAsync("ID"..Player.UserId)
			local Humanoid = Character:WaitForChild('Humanoid')
			Humanoid.DisplayName = 'Spectator #'..ID
		end)
	end)

I.e. Each player has a datastore key with “ID”…PlayerID and a value like “1” or “2” or “3” etc. etc. attached to them.
Now I need to be able to list all the IDs (both the Data Key and Value) in a table (Or something like that) and select them randomly. How would I achieve this? I know there’s a way to list data stores, but that confuses me a bit.

This is only with OrderedDataStores. You will need to keep a separate data store with a list of data store entries.

1 Like

It’s possible with :ListKeysAsync which is a part of DataStoreV2

See Version 2.0 → Listing and Prefixes

2 Likes

I’m still confused, I checked the API reference and learned how to select a random object from a table, but I’m still confused about how to add for example the id of the player to the said table in the data store

I managed to make it work the way I wanted and the script looks like this now;

local DataStore = game:GetService("DataStoreService")
local CustomIDs = DataStore:GetOrderedDataStore("CustomIDs")
local PlayersJoined = DataStore:GetOrderedDataStore("PlayersJoined")
local Decal = workspace.Part.Decal

game:GetService("Players").PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		local customID = script.PlayersJoined
		customID.Value = PlayersJoined:GetAsync("PlayersJoined")

		if not CustomIDs:GetAsync(Player.UserId, customID.Value) then
			customID.Value = customID.Value + 1
			PlayersJoined:SetAsync("PlayersJoined", customID.Value)
			CustomIDs:SetAsync(Player.UserId, customID.Value)
		end
		local ID = CustomIDs:GetAsync(Player.UserId)
		local Humanoid = Character:WaitForChild('Humanoid')
		Humanoid.DisplayName = 'Spectator #'..ID
	end)
end)
----------------------------------------------
local pages = CustomIDs:GetSortedAsync(false, 99)

while true do
	local PlayerIDs = pages:GetCurrentPage(math.random())
	local IDList = {}

	for i, v in pairs(PlayerIDs) do
		table.insert(IDList, i)
	end

	local randomNumber = math.random(#IDList)
	local randomKey = PlayerIDs[IDList[randomNumber]].key
	local randomKeyValue = PlayerIDs[IDList[randomNumber]].value
	Decal.Texture = 'https://www.roblox.com/headshot-thumbnail/image?userId='..randomKey..'&width=420&height=420&format=png'
	wait(1)
end

Okay so, every second the decal changes with a random Player ID that joined the game, And I can also use the Custom ID for other things. I am facing 1 issue though,

GetSortedAsync(value, number)

The number can be as big as 99, I have tried with math.huge and 900 or something like that but the page’s size won’t go over 99.
So basically only the first 99 players to join the game can appear on the decal, which is a problem for me.

I also have the problem that test accounts get saved in the Database
I.e. accounts with negative IDs in the local server that result in the decal to be blank.

I figured I’d try this:

		if not CustomIDs:GetAsync(Player.UserId, customID.Value) then
			if Player.UserId ~= '-'..Player.UserId then
			customID.Value = customID.Value + 1
			PlayersJoined:SetAsync("PlayersJoined", customID.Value)
			CustomIDs:SetAsync(Player.UserId, customID.Value)
			end
		end

But it does not work! :frowning: