Detailed explanation here. I created a character customization menu and i stored the data on Server Storage. And then i created a function to load those each time the character respawns, which is player.Character.CharacterAdded. It works. The thing is, this script runs before the getAsync could get any data from the server so the first time a player joined. They will not load their customised character.
Now i temporarily fixed this by waiting around (5) to (10) after a character has been added, and then loading it. It works, but it isn't exactly giving my game a polished feel. Because it also affects the player respawn. Their custom char wont load until 5-10 sec.
Full script over here: https://pastebin.com/wKAkBTQn
(sorry if you cringe while reading the script. It's only been a few days since i started roblox studio with no experience in scripting at all so bear with me :> )
Alright. What should i do to make it run the load function after only after the data has been loaded from the server.
Any help would be greatly appreciated.
I think a module made by evaera called "Promise", a library ported from Java? (not too sure), which is a future-proofing method may be handy here. in fact, the examples they provide uses a http service get request, which is similar to datastore get request, so it may be very useful for you :D
https://devforum.roblox.com/t/promises-and-why-you-should-use-them/350825
--Example usage of promise with datastore, if you are confused with http example --Settings local DSS_NAME = "PlayerDataV1" local DATA_PREFIX = "_DataV1" --Services local DSS = game:GetService("DataStoreService") local Players = game:GetService("Players") --Modules / Libraries local Promise = require(path.to.promiseLibrary) --i'd recommend having it in replicated storage --Var local PlrDataStore = DSS:GetDataStore(DSS_NAME) --Funcs local dataGet(key) return Promise.async(function(resolve, reject) local success, result = pcall(PlrDataStore, PlrDataStore, key) if success then resolve(result) else reject(result) end end) end local function LoadData(plr) dataGet(plr.Name .. DATA_PREFIX) :andThen(function(body) --andThen() only runs when resolve() is called in dataGet() --do the plr.CharacterData. stuff here return body --returning body allows the next andThen() to read the body end) :andThen(function(body) --promise allows you to chain stuff, so you can do multiple stuff end) :catch(function(warning) --catch() is only ran when reject() is called in dataGet() --the data wasn't loaded, so either kick a player or retry the load data. warn(warning) LoadData(plr) end) :finally(function(body) --Finally is ran when the other calls above are all done running whether it successes or fails. print("Done Doing the Process of Promise!!") end) end --Main Players.PlayerAddedConnect(LoadData)
Yes, its very complicated, but trust me the Promise is one of the most useful library as roblox involves many asynchronous calls (mainly data store, other like remote functions, etc)