DataStore Not Working (Group Game)

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.

1 Like

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.

1 Like

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.

1 Like

It is slower as shown by my benchmark, and as well as what zeuxcg said.

1 Like

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.