I wanted to try out making a simple inventory system using ProfileService and ReplicaService. I quickly put together a data manager script and some client code to handle the replication but not only does my data manager module not run at all, ReplicaService is constantly throwing this warning:
[ReplicaController]: Missing folder “ReplicaRemoteEvents” in ReplicatedStorage; Please check setup documentation.
I looked through the docs of ReplicaService but couldn’t find any info on that. I have searched the devforum too and haven’t found anything.
Here is my code:
Data Manager:
local Template = {
CurrentPower = 0,
Inventory = {
Equipped = {}
}
}
local profileService = require(script.Parent.ProfileService)
local replicaService = require(script.Parent.ReplicaService)
local players = game:GetService("Players")
local RunService = game:GetService("RunService")
local expStore = profileService.GetProfileStore(
"Player",
Template
)
local Profiles = {}
local Replicas = {}
local Manager = {}
local function updateReplica(player, value, valueKey)
local dataReplica = Replicas[player]
dataReplica:SetValue({valueKey}, value)
end
function Manager:Get(player)
local profile = Profiles[player]
if profile then
return profile
else
warn("[MANAGER]: Could not get data from: "..player.UserId)
end
end
function Manager:Append(player, item, quantity)
local profile = self:Get(player)
local dataReplica = Replicas[player]
if profile and dataReplica then
if profile.Data.Inventory[item] then
profile.Data.Inventory[item] += quantity
else
profile.Data.Inventory[item] = quantity
end
dataReplica:ArraySet(dataReplica.Data.Inventory, item, profile.Data.Inventory[item])
end
end
local function onAdded(player)
local playerProfile = expStore:LoadProfileAsync("player-"..player.UserId, "ForceLoad")
if RunService:IsStudio() then
playerProfile = expStore.Mock:LoadProfileAsync("player-"..player.UserId, "ForceLoad")
end
playerProfile:AddUserId(player.UserId)
playerProfile:Reconcile()
playerProfile:ListenToRelease(function()
Profiles[player] = nil
Replicas[player] = nil
player:Kick()
end)
if playerProfile then
if player:IsDescendantOf(players) then
Profiles[player] = playerProfile
local newReplica = replicaService.NewReplica({
ClassToken = replicaService.NewClassToken("player-"..player.UserId),
Data = playerProfile.Data,
Replication = player
})
Replicas[player] = newReplica
else playerProfile:Release() end
else player:Kick() end
end
local function onRemoving(player)
local playerProfile = Profiles[player]
if playerProfile then playerProfile:Release() end
end
for _, player in ipairs(players:GetPlayers()) do
task.spawn(onAdded, player)
end
players.PlayerAdded:Connect(onAdded)
players.PlayerRemoving:Connect(onRemoving)
return Manager
Client:
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local replicatedStorage = game:GetService("ReplicatedStorage")
local replicaController = require(replicatedStorage.ReplicaController)
local Items = require(replicatedStorage.Items)
local invFrame = script.Parent
local GUI_ASSETS = replicatedStorage.GUI_ASSETS
local templateGridElement = GUI_ASSETS.TemplateIcon
function updateGrid(replica)
for _, element in pairs(invFrame:GetChildren()) do
if element:IsA("ImageLabel") then
element:Destroy()
end
end
for item, quantity in pairs(replica.Data.Inventory) do
if item ~= "EquippedPets" then
for i = 1, quantity do
local newGridElement = templateGridElement:Clone()
local associatedItem = Items[item]
newGridElement.Image = associatedItem.IconID
newGridElement.Power.Text = associatedItem.Power
newGridElement.Parent = invFrame
end
end
end
end
replicaController.ReplicaOfClassCreated("player-"..player.UserId, function(replica)
replica:ListenToChange({"Inventory"}, function()
updateGrid(replica)
print("Updated inventory!")
end)
updateGrid(replica)
end)
What’s interesting is that the warning only appears when the client script is enabled. Any help kindly appreciated!