Save your player data with ProfileService! (DataStore Module)

does anyone know how i can load a profile withoud a player being online or point me in the right way i am making an admin tool that can local change players data wich work but i also have a toggle to do it directly in the datastore if there offline
but going over the code im getting confused with the profile release and stuff

local Players = game:GetService("Players")

local ProfileService = require(game.ServerScriptService.PlayerData.ProfileService)
local ProfileTemplate = require(game.ServerScriptService.PlayerData.ProfileTemplate)

local ProfileStore = ProfileService.GetProfileStore(
	game.ServerStorage.Settings.DataStorePrefix.Value,
	ProfileTemplate
)

local Profiles = {}


local function onPlayerAdded(player)
	local profile = ProfileStore:LoadProfileAsync(
		"Player_" .. player.UserId,
		"ForceLoad"
	)

	if profile then
		profile:Reconcile() -- Fill in missing variables from ProfileTemplate (optional)
		profile:ListenToRelease(function()
			Profiles[player] = nil
			player:Kick("A1")
		end)

		if player:IsDescendantOf(Players) then
			Profiles[player] = profile
		else
			profile:Release()
		end
	else
		player:Kick("A2")
	end
end

local function onPlayerRemoving(player)
	local profile = Profiles[player]
	if profile then
		require(game.ServerScriptService.PlayerData.Save).skill(require(game.ServerScriptService.Var),player)
		profile:Release()
		print("saved player",player,profile)
	end
end


Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoving)

local DataManager = {}

function DataManager:Get(player)
	local profile = Profiles[player]

	if profile then
		return profile.Data
	end
end

return DataManager

any ideas how i convert this to also work with loading someone elses profile so i can edit it
it also seems to require an player object i only have a player id to work with if hes offline

Hi, I’m new to using ProfileService. Is there an open source wrapper over ProfileService? If not, is there a reason why not? like - are wrappers meant to be game-specific in terms of their interface (i.e. Wrapper.addCoins) - or are they just so simple that it doesn’t make sense for one to be released open source? or has just nobody bothered

There’ve been a few wrappers and none of them provide much useful functionality and just unnecessarily abstract ProfileService’s easy to understand API - hence why they’re barely used since their API is very bloated.

Thanks for the reply! Would you know of any examples for me to take a look at?

I made this module a while back but never published it:

local profileModule = require(...) --> path here
local template = {}
local profiles = profileModule.new("save",template)

methods.ProfileLoaded:Connect(function(player,profile)
--- that's it! the table passed as profile can be changed and it'll save
end)

Is this what you were referring to?

1 Like

+1 For Wally support if possible :slight_smile:

4 Likes

(Outdated)

5 Likes

How would this work? Wouldnt the table just be the second line as your just restating the value, so I wouldn’t be able to get one of the timeplayed of a certain weapon, because it’s just a number?

Hello! I used the Updated profileserive with my new game but I’ve experienced and got reported about data not loading sometimes when a player joins the game. It takes a very long time to load which breaks the whole game and I want to know if anyone else is having this issue as well? I’ve used the same datastore module that was shown in “EncodedLua” video. Personally I know nothing about datastores but profileservice helped me a tun.

Question: Is there a client checker I’m suppose to be doing to wait until data is loaded? It only breaks the client when data ain’t loaded in before client

My game: 🦩SUMMER🦩Throwing Simulator 🔥 - Roblox

I’ve had this issue as well. Sometimes it doesn’t seem to save my profile and undo the session lock.

1 Like

DataStore requests are not instant and sometimes they can take several seconds to complete. If a player is hoping between sessions that can take ProfileService up to like 14 seconds to resolve at times, but usually it can still be pretty fast.

However, if you fail to release the profile after every time a player leaves you’re going to see incredibly long load times, but I doubt it’s something you’re dealing with.

I tried joining your game and it seems to work fine - you should probably work on postponing the client from starting before server loads the data.

6 Likes

Yea it worked fine when you joined cause I added a big change to not load client until data is loaded. But before that I was getting lots of reports from new comers and old comers. I guess it works fine now after I did that.

I am having some data-loss issues in my game with ~4K people in it on average. Is there a limit to the amount of data one can save? For reference, my game is a drawing game, and it saves sometimes tens of thousands of parts’ CFrame, size, and color values. Most players have data loss issues when their paint count reaches over 15K.

This is an amazing module, but a short answer would be great so I can fix this issue for my players.

ProfileService’s data limit is DataStore’s data limit - the amount of extra data needed for session locking, MetaTags, GlobalUpdates, etc.

The limit is ~4MB. See if these saves reach near that. If so, then that’s your issue.

The problem with ProfileService is that it’s opniated about compression which is something that could possibly help you. It’s not really possible to deal with compression in an optimized matter using ProfileService.

There are ways of reducing data usage without compression of course, compression should be a last resort anyhow, things like on drawing games like removing extra lines that aren’t actually needed, etc, it’s always nice to look into those types of optimizations.

But in certain cases, you already did all the optimizations you could but you would need compression.

AFAIK, ProfileService doesn’t have any APIs to help manage maximum data being stored.

2 Likes

Thank you! I will probably just categorize the parts into tables of duplicate sizes and colors instead of assigning colors and sizes to every part’s data as well as only store position and orientation (rather than an entire CFrame), which will definitely lower the size.

1 Like

Hello! It’s happening again! This is someone that just joined my server and I had it just before as well
image
It been like 1 min and the person takes a while to load. Weirdly the check I added fails to wait for the stat to be loaded and never kicks me if its not loaded

Game: https://www.roblox.com/games/7745767402/

It happens when the server has been open for at least a hour or so and longer

1 Like

I’m having an issue that I’ve never had with ProfileService before.

When setting up the DataManager, I use a ModuleScript so that player data can be easily referred to when needing to modify it from other scripts. In this case, I’m working on a game and when I try running the game with the DataManager as a module, it does not initialize/load and nothing happens at all. So I’m forced to use a regular Script which loads up fine, but is not ideal for modifying player data…

Any ideas or suggestions as to why and how I can fix this so I can use a module as my DataManager?

A ModuleScript does not run unless accessed by another Script, LocalScript, or ModuleScript using the ‘require()’ function. I would recommend leaving DataManager as a ModuleScript and using any of your other scripts to require it. Another option is to create a Script just for initializing your DataManager and other ModuleScripts you may have.

1 Like

if I were to worry about data loss, should I use this amazing, excellent, cool, efficient, good module?

I keep encountering this strange error.
image

From what I’ve gathered from my own research, it is when you attempt to store non-saveable values to the data store, such as an instance, or a userdata value.

However, in my data, there is only tables, numbers, strings, and booleans, all of which should be able to be converted and saved correctly.

Here is the data template I use:

-- // Module Table

local DefaultData = {
	XP = 0,
	Gems = 0,
	Coins = 0,
	
	Inventory = {
		Knife = {
			Equipped = 1,
			Owned = {
				{Name = "Stock", Kills = 0}
			}
		},
		
		Revolver = {
			Equipped = 1,
			Owned = {
				{Name = "Stock", Kills = 0}
			}
		},
		
		Effect = {
			Equipped = 1,
			Owned = {
				{Name = "Default"}
			}
		},
		
		Power = {
			Equipped = 1,
			Owned = {
				{Name = "Default"}
			}
		},
		
		Gear = {
			Equipped = 1,
			Owned = {
				{Name = "None"}
			}
		},
		
		Character = {
			Equipped = 1,
			Owned = {
				{Name = "None"}
			}
		},
		
		Radio = {
			Equipped = 1,
			Owned = {
				{Name = "None"}
			}
		},
		
		Boost = {
			{Name = "BeginnerLuck", Count = 1}
		},
		
		Chest = {
			{Type = "Wooden", UnlockTime = 0}
		}
	},
	
	Collection = {
		XP = 0,
		Knives = {},
		Revolvers = {},
		Effects = {}
	},
	
	Settings = {
		ChatEnabled = true,
		KillEffectsEnabled = true,
		ParticlesEnabled = true,
		ShadowsEnabled = true,
		MusicVolume = 100,
		InterfaceVolume = 100,
		EnvironmentVolume = 100,
		RadioVolume = 100,
		ControllerVibration = false
	},
	
	PlayerStats = {
		GemsEarned = 0,
		CoinsEarned = 0,
		CratesOpened = 0,
		ChestsOpened = 0,
		Kills = 0,
		Deaths = 0,
		RoundsPlayed = 0,
		RoundsWon = 0,
		GameModesWon = {}
	},
	
	LastLogin = 0,
	LoginStreak = 0,
	OwnedPasses = {},
	Achievements = {},
	ActiveBoosts = {},
	RedeemedCodes = {},
	RadioHistory = {}
}

return DefaultData

What am I doing wrong?
Might I add, this popped up randomly, having no alterations to the data scripts at all.

The DataManager I use is directly written based from the GitHub API tutorial, which includes the product purchase meta data features.

If anyone knows how to solve this issue, it would be greatly appreciated. Thank you!