It’s a local script. How can I fire a remote event to update the value?
i advise you update the data on the server doing it on client can make your game vulnerable to exploits.
Why is it a local script? Data stores only work towards the server, I recommend putting it in serverscriptservice as a (server)script. Make sure you define everything correctly too, and keep your output out so it can help you towards fixing things.
Judging by the fact that the saving script isn’t actually erroring, the save script itself is probably on the server. I believe the issue is that they’re using ContextActionService or UserInputService to decide when to update the values, which can only be done in a LocalScript, while the values can only be properly updated on the server. They’ll need to add some form of communication via RemoteEvents to tell the server to update the values.
Ok then, that would make sense, so I would go with what you are announcing to him.
I did this, but it doesn’t seem to work. Basically I replaced the part of the script that added one to the flex from the local script into the script to fire the server,
and on the script in server script service I wrote this
local Player = game.Players.LocalPlayer
local Flex = Player.leaderstats.Flex.Value
game.ReplicatedStorage.Flex.OnServerEvent:Connect(function(player)
Flex.Value = Flex.Value + 1
end)
Edit – figured it out. Your example script actually worked.
Here’s some test code using DS2, it’s a lot easier to use and I suggest getting used to it.
Sorry if this doesn’t solve your problem.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlayerData = require(ReplicatedStorage.PlayerData)
local MainKey = "NY_"
local Rounds = require(script.RoundHandler)
PlayerData.Combine(MainKey, "Stats", "Misc")
local function SetDefault()
local Dictionary = {
Stats = {
["Cash"] = 0;
["Wins"] = 0;
},
Misc = {
["MetTheOwner"] = false;
["AlphaTester"] = false;
},
}
return Dictionary
end
game.Players.PlayerAdded:Connect(function(Player)
local UserData = PlayerData(MainKey, Player):Get(SetDefault())
--[[ STATS ]]--
local PlrStats = Instance.new("Folder", Player)
PlrStats.Name = "leaderstats"
local Cash = Instance.new("IntValue", PlrStats)
Cash.Name = "Cash"
local Wins = Instance.new("IntValue", PlrStats)
Wins.Name = "Wins"
--[[ AWARDS/MISC ]]--
local MiscFolder = Instance.new("Folder", Player)
MiscFolder.Name = "Misc"
local MetTheOwner = Instance.new("BoolValue", MiscFolder)
MetTheOwner.Name = "MetTheOwner"
local AlphaTester = Instance.new("BoolValue", MiscFolder)
AlphaTester.Name = "AlphaTester"
--[[ LOADING/SAVING ]]--
local StatsSave = PlayerData("Stats", Player)
local MiscSave = PlayerData("Misc", Player)
local function UpdateStats(New)
Cash.Value = StatsSave:Get(New).Cash
Wins.Value = StatsSave:Get(New).Wins
end
local function UpdateMisc(New)
MetTheOwner.Value = MiscSave:Get(New).MetTheOwner
AlphaTester.Value = MiscSave:Get(New).AlphaTester
end
--[[ UPDATING ]]--
UpdateStats(UserData.Stats)
UpdateMisc(UserData.Misc)
StatsSave:OnUpdate(UpdateStats)
MiscSave:OnUpdate(UpdateMisc)
--spawn(function()
--while(true)do
--UserData.Stats.Cash = UserData.Stats.Cash + 5
--StatsSave:Set(UserData.Stats)
--if UserData.Misc.AlphaTester == false then
--UserData.Misc.AlphaTester = true
--MiscSave:Set(UserData.Misc)
--print(UserData.Misc.AlphaTester)
--end
--wait(1)
--end
--end)
--[[ ETC ]]--
end)
No, don’t do that. Don’t EVER give the client any power. Don’t even suggest that, because that is incorrect and risky. We don’t want beginner scripters looking for a quick fix to their problem to see that, and just do that until they learn better.
Okay… so how can I create a script that will update the servers values without giving the client power…
Follow what @RainScripts said, except probably don’t put DataStore2 in ReplicatedStorage and don’t do Instance.new(ClassName, Parent)
.
Well that won’t work, because the you increase flex value when the key e is pressed, which also toggles and animation so it needs to be under starter character
Use Postie to invoke the client when the client supposedly presses E to check if they have actually pressed it.
Server:
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local DataStore2 = require(ServerStorage.DataStore2)
local Postie = require(ReplicatedStorage.Postie)
local GameEvent = ReplicatedStorage.GameEvent -- Your RemoteEvent.
DataStore2.Combine("MainDataStore", "PointsData")
local INCREMENT_POINTS_KEY = Enum.KeyCode.E
local INCREMENT_POINTS_BY = 1
local MAX_STRIKES = 3
local PlayerStrikes = {}
local EventCalls = {
PlayerPressedE = function(Player)
local Success, PressedKey = Postie.InvokeClient("GetPressedKey", Player, 0.25)
local PassedCheck = Success and PressedKey == INCREMENT_POINTS_KEY
if PassedCheck then
local PointsData = DataStore2("PointsData", Player)
PointsData:Increment(INCREMENT_POINTS_BY)
else
PlayerStrikes[Player] = PlayerStrikes[Player] + 1
if PlayerStrikes[Player] >= MAX_STRIKES then
Player:Kick("Failed to provide last used key properly three times.")
end
end
end;
}
local function OnUpdateFenv(ValueObject)
return function(Value)
ValueObject.Value = Value
end
end
local function PlayerAdded(Player)
if not Player:FindFirstChild("leaderstats") then
PlayerStrikes[Player] = 0
local PointsData = DataStore2("PointsData", Player)
local Leaderstats = Instance.new("Folder")
Leaderstats.Name = "leaderstats"
local Points = Instance.new("IntValue")
Points.Name = "Points"
Points.Value = PointsData:Get(0)
Points.Parent = Leaderstats
Leaderstats.Parent = Player
PointsData:OnUpdate(OnUpdateFenv(Points))
end
end
local function PlayerRemoving(Player)
if PlayerStrikes[Player] then
PlayerStrikes[Player] = nil
end
end
local function OnServerEvent(Player, FunctionCall, ...)
local Function = EventCalls[FunctionCall]
if Function then Function(Player, ...) end
end
Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(PlayerRemoving)
GameEvent.OnServerEvent:Connect(OnServerEvent)
for _, Player in ipairs(Players:GetPlayers()) do PlayerAdded(Player) end
Client:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local Postie = require(ReplicatedStorage.Postie)
local GameEvent = ReplicatedStorage.GameEvent -- Your RemoteEvent.
local REMOVAL_TIME = 0.85
local LastPressedKey = nil
local AlreadyQueued = false
local function ResetKey()
if AlreadyQueued then
LastPressedKey = nil
AlreadyQueued = false
end
end
local function InputBegan(InputObject, GameProcessed)
-- I'm not sure how you have it working right now, but I'll assume this,
if not GameProcessed and InputObject.UserInputType == Enum.UserInputType.Keyboard and InputObject.KeyCode == Enum.KeyCode.E then
LastPressedKey = InputObject.KeyCode
GameEvent:FireServer("PlayerPressedE")
if not AlreadyQueued then
AlreadyQueued = true
delay(REMOVAL_TIME, ResetKey)
end
end
end
local function GetPressedKey()
return LastPressedKey
end
UserInputService.InputBegan:Connect(InputBegan)
Postie.SetCallback("GetPressedKey", GetPressedKey)
Made a mistake, my bad.
Why would you not use Instance.new(ClassName, Parent)
I’d also rather DS2 the module or put it in ServerStorage but either would do.
ServerStorage is better so the client can’t even see it. And Instance.new(ClassName, Parent)
is much slower than setting the parent last.
They won’t be able to change anything either way, but like I said:
I’d also rather DS2 the module or put it in ServerStorage but either would do. <
Also, I don’t see any performance issues with it being slower at all, i’ve actually done both methods and each on relatively big games?
With their specific scenario, that’s really the only option. There’s no other way to access the user’s inputs without getting the client involved.
My hacky solution kinda says otherwise, but it’s only mildly better than the client, I’m sure.
I’m laughing so hard right now, two tenths of a second.
Ok, I see.
Here is some articles explaining the issue. Set other properties before Parent after Instance.new and PSA: Don't use Instance.new() with parent argument
2/10 of a second isn’t much, but imagine instancing multiple objects into your game. This time only increases with the more properties the object has, for instance, parts, which can cause significant delays.