Thank you very much being French I had a little trouble on the video, now I know how it works thank you very much for your help you had me a lot help
Thank you for pointing that out I have fixed it
`local Players = game:GetService("Players")
local DataStoreModule = require(game.ServerStorage.DataStore)
local Red = require(game.ReplicatedStorage.Red)
local remoteEvent = Red.Server("AllEvent")
local template = {
--[[
IN LEADERSTATS
]]
Wins = 0,
--[[
IN OTHER
]]
Grade = "Beginer",
StoreCoins = 0,
Codes = {}
}
local function StateChanged(state, dataStore, player)
while dataStore.State == false do
if dataStore:Open(template) ~= "Success" then
task.wait(6)
end
end
end
Players.PlayerAdded:Connect(function(player)
local dataStore = DataStoreModule.new("Player", player.UserId)
dataStore.StateChanged:Connect(StateChanged)
StateChanged(dataStore.State, dataStore, player)
remoteEvent:Fire(player, "dataStoreEvent", player, dataStore.Value) --EVENT WITH RED
end)
Players.PlayerRemoving:Connect(function(player)
local dataStore = DataStoreModule.find("Player", player.UserId)
if dataStore ~= nil then
dataStore:Destroy()
end
end)`
Suphis vairement desoler de te rederanger, but when I create a remote event in playerData it works but the dataStore (in RemoteEvent) since it is under playerAdded it will take the game start data while I want that if there is a data change during the game the event takes it into account. I look for a lot of things but I’m nothing
Thank you for your help I hope not to bother.
Use a metatable.
Code:
local Players = game:GetService("Players")
local DataStoreModule = require(game.ServerStorage.DataStore)
local Red = require(game.ReplicatedStorage.Red)
local remoteEvent = Red.Server("AllEvent")
local template = {
--[[
IN LEADERSTATS
]]
Wins = 0,
--[[
IN OTHER
]]
Grade = "Beginer",
StoreCoins = 0,
Codes = {}
}
local function StateChanged(state, dataStore, player)
while dataStore.State == false do
if dataStore:Open(template) ~= "Success" then
task.wait(6)
end
end
end
Players.PlayerAdded:Connect(function(player)
local dataStore = DataStoreModule.new("Player", player.UserId)
dataStore.StateChanged:Connect(StateChanged)
StateChanged(dataStore.State, dataStore, player)
local proxyTable = dataStore.Value
dataStore.Value = {}
setmetatable(dataStore.Value, {
__index = function(self, index)
return proxyTable[index]
end,
__newindex = function(self, index, value)
proxyTable[index] = value
remoteEvent:Fire(player, "dataStoreEvent", player, dataStore.Value)
end,
})
remoteEvent:Fire(player, "dataStoreEvent", player, proxyTable)
end)
Players.PlayerRemoving:Connect(function(player)
local dataStore = DataStoreModule.find("Player", player.UserId)
if dataStore ~= nil then
dataStore:Destroy()
end
end)
Whenever you edit dataStore.Value
, it will send the event.
@5uphi, if there is a built in way to do this, please tell me.
One option is to use custom functions
-- Custom functions that we will add to all player datastore objects
local function Set(dataStore, key, value)
if dataStore.State ~= true then return false end
dataStore.Value[key] = value
remoteEvent:Fire(dataStore.Player, key, value) -- Tell the client there data changed
return true
end
local function Increment(dataStore, key, delta)
if dataStore.State ~= true then return false end
dataStore.Value[key] += delta
remoteEvent:Fire(dataStore.Player, key, dataStore.Value[key]) -- Tell the client there data changed
return true
end
game.Players.PlayerAdded:Connect(function(player)
local dataStore = DataStoreModule.new("Player", player.UserId)
dataStore.Player = player -- Add what player owns this datastore object
dataStore.Set = Set -- Add the set function to the datastore object
dataStore.Increment = Increment -- Add the increment function to the datastore object
end)
once you have added the function inside the datastore object you can call it from any script like this
local dataStore = DataStoreModule.find("Player", player.UserId)
if dataStore == nil then error("DataStore not found") end
-- lets use are custom functions
local success = dataStore:Set("StoreCoins", 100)
local success = dataStore:Increment("Wins", 1)
and by calling the set function it will also fire the remote event
@5uphi, I tried your method but I still can’t I’ll show you my scripts
--PlayerData (ServerScriptService)
local Players = game:GetService("Players")
local DataStoreModule = require(game.ServerStorage.DataStore)
local Red = require(game.ReplicatedStorage.Red)
local remoteEvent = Red.Server("AllEvent")
local template = {
--[[
IN LEADERSTATS
]]
Wins = 0,
--[[
IN OTHER
]]
Grade = "Beginer",
StoreCoins = 0,
Codes = {}
}
local function StateChanged(state, dataStore, player)
while dataStore.State == false do
if dataStore:Open(template) ~= "Success" then
task.wait(6)
end
end
end
Players.PlayerAdded:Connect(function(player)
local dataStore = DataStoreModule.new("Player", player.UserId)
dataStore.StateChanged:Connect(StateChanged)
StateChanged(dataStore.State, dataStore, player)
end)
Players.PlayerRemoving:Connect(function(player)
local dataStore = DataStoreModule.find("Player", player.UserId)
if dataStore ~= nil then
dataStore:Destroy()
end
end)
--the script you sent me (ServerScriptService)
local DataStoreModule = require(game.ServerStorage.DataStore)
local Red = require(game.ReplicatedStorage.Red)
local remoteEvent = Red.Server("AllEvent")
local function Set(dataStore, name, value)
if dataStore.State ~= true then return false end
dataStore.Value[name] = value
remoteEvent:Fire(dataStore.Player, name, value)
return name
end
local function Increment(dataStore, name, delta)
if dataStore.State ~= true then return false end
dataStore.Value[name] += delta
remoteEvent:Fire(dataStore.Player, name, dataStore.Value[name])
return true
end
game.Players.PlayerAdded:Connect(function(player)
local dataStore = DataStoreModule.new("Player", player.UserId)
dataStore.Player = player
dataStore.Set = Set
dataStore.Increment = Increment
end)
-- Custom Function (ServerScriptService)
local DataStoreModule = require(game.ServerStorage.DataStore)
game.Players.PlayerAdded:Connect(function(player)
local dataStore = DataStoreModule.new("Player", player.UserId)
local state = dataStore.StateChanged:Wait()
if state ~= true then return end
local success = dataStore:Set("Grade", dataStore.Value.Grade)
local success = dataStore:Increment("Codes", dataStore.Value.Codes)
end)
--ManageCode (ReplicatedStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local player = game.Players.LocalPlayer
local Red = require(ReplicatedStorage.Red)
local rewardModule = require(ReplicatedStorage.InformationModule)
local remoteEvent = Red.Client("AllEvent")
local codeFrame = player.PlayerGui.CenterGui.CodeFrame.InfoFrame
local code = {}
code.__index = code
function code.new(text: string?, storeCoins: number?, Expired)
local newCode = {}
setmetatable(newCode, code)
newCode.Code = text
newCode.StoreCoins = storeCoins
newCode.Expired = Expired
newCode.Redeem = false
return newCode
end
function code:CodeEnter(codesValue)
if self.Expired == true then
rewardModule:cloneVotingText(codeFrame, "This code Expired")
else
if table.find(codesValue, self.Code) then
rewardModule:cloneVotingText(codeFrame, "Code already Redeem")
else
remoteEvent:Fire("codeRedeem", self.Code, self.StoreCoins)
rewardModule:cloneVotingText(codeFrame, "Code Redeem")
end
end
end
return code
--MainScript (Client)
--CodeFrame:
remoteEvent:On("Codes", function(codesValue)
enterCode.FocusLost:Connect(function()
local code = orderedCode[enterCode.Text]
if code then
code:CodeEnter(codesValue)
else
informationModule:cloneVotingText(codeGui, "This Code Doesnt exist")
end
end)
end)
I understood your method, but this is not what I seek I badly forumulate excuse me what I wanted to say is that when we insert a value in "codes(in the dataStore) bah the problem is that its reverifies not every time the dataStore so when I enter an example code ("Code"1) its tells me well “Redeem” but when I rerentre its me “Redeem” instead of "Code already reedem) and its adds the code in the code(dataStore)
I really apologize for the derangement
If I add something to the template it adds it to dataStore.Value, but when I remove it from the template again, it doesn’t remove it from dataStore.Value. Is it possible to make a fix for this?
I enjoyed your video comparing DataStore2 vs ProfileService vs Suphi’s DataStore Module and it was very interesting to learn about how each module’s method works and the pros and cons of them.
The API of the module is concise and the code is relatively easy to read compared to ProfileService. I also like how it’s built on newer Roblox technologies like Memory Stores.
I think the only thing holding it back is that the other modules are so old and have been deployed in massive games to the point where most people have confidence in them being battle-tested.
I attached a place file I used for testing the module and built a PlayerData module around it that utilizes both this module and ReplicaService together. It works perfectly but is there anything I should look out for by utilizing it in this way?
datastores.rbxl (98.5 KB)
Unfortunately that is not possible without you writing custom code to remove values
The reason why is let’s say you give the player a sword that is not in the template if the module removed things not in the template the player would lose there sword
So hopefully that shows why the module is not able to workout what things to keep and what things to remove
But if you want to remove something manually all you have to do after you have opened the datastore is dataStore.Value.Key = nil
Hey there! The datastore seems to work well from the tests i’ve made. But everytime i test my game this error pops up, i’m not sure what it means, nor what it can cause to my game.
The error code is the following:
MemoryStoreService: RequestThrottled: Recent MemoryStores requests hit one or more limits. API: SortedMap.Update, Data Structure: Bob/global/Good.
Just curious, if I set the data of a player like “dataStore.Value = “Test”” from one server and the player is in a different server. Will they get the data without having the other server having to close and save the datastore?
It’s a current bug affecting everyone right now.
No because the player in the other server will be using a locally cached version
in the advanced video I show how you can use Queue
+ ProcessQueue
to communicate between servers you can also make your own communication system
Would you consider adding a third find
constructor that takes a DataStore.Id
as its sole argument? My wrapper (a word I am using loosely as I feel that I have added so much that “wrapper” does not properly describe it anymore) for your module is cross-state and I use DataStore.Id
for keying items like Changed
events I have been implementing. I can do the string manipulation in the wrapper itself, I just think it is a feature worthy of being a built-in.
Lets say I want to save if a player has an emote or a sword equipped through intvalues though the player that is cloned to the player to get an animation id, should I use this module or another module such as ProfileService?
Whenever I try to open a hidden datastore it says failed and the datastore value is nil. Am I doing something wrong?
both modules can work
you would simply do
datasStore.Value.Key = intvalue.Value
and
intvalue.Value = dataStore.Value.Key
to move the values back and forth
what does the error say if you have the same key open already then you cannot open the same key twice