Hi there guys,
I’m currently creating a script to create a store for the player using OOP and it’s been very efficient, especially in the datastore part, but I found myself in a slightly controversial situation.
I’m not able to find a viable way to send data from the server to the client efficiently - by that I mean without using remote events because they would probably be called several times.
Server:
local StoreManager = require(game.ReplicatedStorage:WaitForChild("StoreManipulationSystem"):WaitForChild("Modules"):WaitForChild("StoreModule"))
local ItemManipulation = game.ReplicatedStorage:WaitForChild("StoreManipulationSystem"):WaitForChild("Functions"):WaitForChild("ItemManipulation")
local Players = game:GetService("Players")
local Stores = {}
Players.PlayerAdded:Connect(function(player)
local store = StoreManager.new(player)
Stores[player.UserId] = store
print("print stores",Stores)
end)
Players.PlayerRemoving:Connect(function(player)
if Stores[player.UserId] then
Stores[player.UserId]:SaveData()
Stores[player.UserId] = nil
end
end)
-- (...)
Module stuff:
local StoreManager = {}
StoreManager.__index = StoreManager
local DataStoreService = game:GetService("DataStoreService")
local StoreData = DataStoreService:GetDataStore("PlayerStoreData")
function StoreManager.new(player)
local self = setmetatable({}, StoreManager)
self.Player = player
self.StorageCapacity = 50
self.Items = {}
local success, data = pcall(function()
return StoreData:GetAsync(player.UserId)
end)
if success and data then
self.StorageCapacity = data.StorageCapacity or 50
self.Items = data.Items or {}
end
return self
end
return StoreManager
-- (...)
some things like the current storage capacity and the items I need to display in a bar that is obviously on the client, but I can’t access it any other way other than through remote events or functions, which ends up weighing down my game because these requests are made almost every time.
any ideas?
This is a common dilemma, of which the common shortcuts are attaching Attributes or ValueObjects to the player object, and listening to property changes on the client. Very valid solution. Only minor change needed is to include the update to these values on your server code which is straightforward.
More elaborate solutions use networking libraries that allow you to cross communicate updates of state to the client, but underneath the hood these are just remote handshakes that feed this data.
Any of these options is fine, player data state changes aren’t frequent enough for you to be concerned about in regards to remotes and your network requests.
If you have slots, items and count of item, you can send SlotId, ItemId and Count, you can send Those 3, even if you want to optimize it further, you can send only ItemId and Count if you update the value, not change item
For further compression, you can turn those 8 bit numbers into strings, most of the time they wouldn’t pass 1000, so each string will have 4 bytes, which is 2x less than normal
Example:
--/ On client event
local DecompressedSlotId = tonumber(SlotId)
local DecompressedItemAmount = tonumber(ItemAmount)
local DecompressedItemId = tonumber(ItemId or 0)
if not DecompressedItemId then
Slots[DecompressedSlotId].Amount = DecompressedAmount
else
Slots[DecompressedSlotId].Item = DecompressedItemId
Slots[DecompressedSlotId].Amount = DecompressedAmount
end
If you have something player related, you should store remotes in player’s object, for organization and security + you don’t need to direct functions for specific players, only retrieve needed data
Other remotes that aren’t used very often or are simply global, use them in replicated storage
Remember that instances or remotes, bandwidth will still exist here, there is no difference in programming langugae either