Right, so I'm making an RPG game with some friends of mine and I need to be able to save data across multiple places in the same game.
I first thought I'd use Trello to accomplish this however, I ran into some problems with the Trello API that I couldn't figure out. Then I thought that I'd use loleris's ProfileService but, that didn't seem to work out either. (https://devforum.roblox.com/t/save-your-player-data-with-profileservice-datastore-module/667805)
Here's my current script that's meant to use loleris's ProfileServer:
local profileService = require(script.Parent:WaitForChild("ProfileService")); local _P = game:GetService("Players"); local profileStore = profileService.GetProfileStore( "PlayerData", { Race = "Human"; Exp = 0; Level = 1; Magic = false; Melee = true; Sprint = 23; Walk = 16; BaseDamage = 0.45; SkillPoints = 0; MaxHealth = 25; HealthSkills = 0; SpeedSkills = 0; DamageSkills = 0; UpperShirtColor = "Pastel violet"; LowerShirtColor = "Mid gray"; PantsColor = "Flint"; Hair = "Bald"; Eyes = "Eyes2"; Mouth = "Mouth7"; HairColor = "Black"; HasPlayed = false; Coins = 0; } ) local profiles = {}; local dataManager = {}; _P.PlayerRemoving:connect(function(player) local profile = profiles[player]; if profile then profile:Release(); end end) _P.PlayerAdded:connect(function(p) local profile = profileStore:LoadProfileAsync( "Player_"..p.userId, "ForceLoad" ); if profile then profile:ListenToRelease(function() profiles[p] = nil; p:Kick(); end) if p:IsDescendantOf(_P) then profiles[p] = profile; else profile:Release(); end else p:Kick(); end local pData = p:WaitForChild("Data"); local race = pData:WaitForChild("Race"); local exp = pData:WaitForChild("Exp"); local level = pData:WaitForChild("Level"); local magic = pData:WaitForChild("Magic"); local melee = pData:WaitForChild("Melee"); local sprint = pData:WaitForChild("Sprint"); local walk = pData:WaitForChild("Walk"); local baseDamage = pData:WaitForChild("BaseDamage"); local skillPoints = pData:WaitForChild("SkillPoints"); local healthSkills = pData:WaitForChild("HealthSkills"); local speedSkills = pData:WaitForChild("SpeedSkills"); local damageSkills = pData:WaitForChild("DamageSkills"); local hairName = pData:WaitForChild("HairName"); local eyesName = pData:WaitForChild("EyesName"); local mouthName = pData:WaitForChild("MouthName"); local hasPlayed = pData:WaitForChild("HasPlayed"); local maxHealth = pData:WaitForChild("MaxHealth"); local coins = pData:WaitForChild("Coins"); local hairColor = pData:WaitForChild("HairColor"); local tempPrimaryShirtColor = pData:WaitForChild("TempPrimaryColor"); local tempSecondaryShirtColor = pData:WaitForChild("TempSecondaryColor"); local tempPantsColor = pData:WaitForChild("TempPantsColor"); local tempHairColor = pData:WaitForChild("TempHairColor"); local mainQuests = p:WaitForChild("MainQuests"); local valk = mainQuests:WaitForChild("Valk"); local valkStage = valk:WaitForChild("ValkStage"); pData.Race.Value = profiles[p].Race; pData.MaxHealth.Value = profiles[p].MaxHealth; pData.Exp.Value = profiles[p].Exp; pData.Level.Value = profiles[p].Level; pData.Magic.Value = profiles[p].Magic; pData.Melee.Value = profiles[p].Melee; pData.Sprint.Value = profiles[p].Sprint; pData.Walk.Value = profiles[p].Walk; pData.BaseDamage.Value = profiles[p].BaseDamage; pData.SkillPoints.Value = profiles[p].SkillPoints; pData.HealthSkills.Value = profiles[p].HealthSkills; pData.SpeedSkills.Value = profiles[p].SpeedSkills; pData.DamageSkills.Value = profiles[p].DamageSkills; pData.TempPrimaryColor.Value = profiles[p].UpperShirtColor; pData.TempSecondaryColor.Value = profiles[p].LowerShirtColor; pData.TempPantsColor.Value = profiles[p].PantsColor; pData.TempHairColor.Value = profiles[p].HairColor; pData.HairName.Value = profiles[p].Hair; pData.EyesName.Value = profiles[p].Eyes; pData.MouthName.Value = profiles[p].Mouth; pData.HasPlayed.Value = profiles[p].HasPlayed; pData.Coins.Value = profiles[p].Coins; valk.ValkStage.Value = profiles[p].MainQuests.ValkStage; race.Changed:connect(function() profiles[p].Race = race.Value; end) exp.Changed:connect(function() profiles[p].Exp = exp.Value; end) level.Changed:connect(function() if not p.Data:FindFirstChild("JustJoined") then profiles[p].Level = level.Value; elseif p.Data:FindFirstChild("JustJoined") and p.Data:FindFirstChild("JustJoined").Value == false then p.Data:FindFirstChild("JustJoined").Value = true; elseif p.Data:FindFirstChild("JustJoined") and p.Data:FindFirstChild("JustJoined").Value == true then profiles[p].Level = level.Value; end end) magic.Changed:connect(function() profiles[p].Magic = magic.Value; end) melee.Changed:connect(function() profiles[p].Melee = melee.Value; end) sprint.Changed:connect(function() profiles[p].Sprint = sprint.Value; end) walk.Changed:connect(function() profiles[p].Walk = walk.Value; end) baseDamage.Changed:connect(function() profiles[p].BaseDamage = baseDamage.Value; end) coins.Changed:connect(function() profiles[p].Coins = coins.Value; end) skillPoints.Changed:connect(function() profiles[p].SkillPoints = skillPoints.Value; end) maxHealth.Changed:connect(function() if maxHealth.Value > 25 then profiles[p].MaxHealth = maxHealth.Value; end end) healthSkills.Changed:connect(function() print(p.Name.." gained 1 health point!") profiles[p].HealthSkills = healthSkills.Value; end) damageSkills.Changed:connect(function() print(p.Name.." gained 1 damage point!") profiles[p].DamageSkills = damageSkills.Value; end) speedSkills.Changed:connect(function() print(p.Name.." gained 1 speed point!") profiles[p].SpeedSkills = speedSkills.Value; end) hairColor.Changed:connect(function() profiles[p].HairColor = hairColor.Value; end) tempPrimaryShirtColor.Changed:connect(function() profiles[p].UpperShirtColor = tempPrimaryShirtColor.Value; end) tempSecondaryShirtColor.Changed:connect(function() profiles[p].LowerShirtColor = tempSecondaryShirtColor.Value; end) tempPantsColor.Changed:connect(function() profiles[p].PantsColor = tempPantsColor.Value; end) tempHairColor.Changed:connect(function() profiles[p].HairColor = tempHairColor.Value; end) hairName.Changed:connect(function() profiles[p].Hair = hairName.Value; end) eyesName.Changed:connect(function() profiles[p].Eyes = eyesName.Value; end) mouthName.Changed:connect(function() profiles[p].Mouth = mouthName.Value; end) hasPlayed.Changed:connect(function() profiles[p].HasPlayed = hasPlayed.Value; end) valkStage.Changed:connect(function() profiles[p].MainQuests.ValkStage = valkStage.Value; end) end) function dataManager:Get(player) local profile = profiles[player]; if profile then return profile.Data; end end return dataManager;
The problem I'm having is that first of all: when you first spawn all of your data should already have set values corresponding to the template. When you join, your race should be human. However the value of "race" is nil. And things like my BaseDamage should be 0.45 but instead is 0.
And when I change the values manually, they don't save either. So when if I were to change my race manually to "Human" then I left the game and rejoined, the race value would go back to nil.
If anyone has any idea how to work with loleris's profile service, please help me.
Using an external API seems unnecessary for this use-case, instead look into DataStoreService, which was designed for this exact purpose:
https://developer.roblox.com/en-us/articles/Data-store
https://developer.roblox.com/en-us/api-reference/class/DataStoreService