Listening to nested indexes with replicaService?

I’m using profileService and replicaService for my player’s data. I am trying to use :ListenToChange() from ReplicatedService. I am getting it to work with values that are one index deep in my table, but I can’t figure out how to use a “deeper” index (ex. I can access [4] but not [4][1]) This is my code for updating data to the client Local Script:

replicaController.ReplicaOfClassCreated("DataToken_"..player.UserId,function(replica)
	print(replica.Data)
	
	replica:ListenToChange({"cash"},function(newVal) 
		standalones.cash.Value = replica.Data["cash"]
	end)
	
	replica:ListenToChange({"exp"},function(newVal)
		standalones.exp.Value = replica.Data["exp"]	
	end)
	
	replica:ListenToChange({"level"},function(newVal) 
		standalones.level.Value = replica.Data["level"]	
	end)
	
	replica:ListenToChange({replica.Data["guns"]["brocc"]["speedBoost"]},function(newVal) 
		standalones.guns.brocc.upgrades.speedBoost.Value = replica.Data["guns"]["brocc"]["speedBoost"]
		print(replica.Data["guns"]["brocc"]["speedBoost"])
	end)
	cashTextLabel.Text = "Cash: "..replica.Data["cash"] .. " ||| Exp: " .. replica.Data["exp"] .. " ||| Brocc's speedBoost: " .. replica.Data["guns"]["brocc"]["speedBoost"]
end)
replicaController.RequestData()

And this is the data profile it’s using Module Script:

local playerProfileStore = profileService.GetProfileStore("playerProfileStore",{
	cash = 0,
	level = 1,
	exp = 1,
	guns = {
		brocc = {
			level = 1,
			strength = 1,
			range = 1,
			fireRate = 1,
			reloadRate = 1,
			growRate = 1,
			speedBoost=1
		},
		pea = {
			level = 1,
			strength = 1,
			range = 1,
			fireRate = 1,
			reloadRate = 1,
			growRate = 1,
			speedBoost=1
		},
		karrot = {
			level = 1,
			strength = 1,
			range = 1,
			fireRate = 1,
			reloadRate = 1,
			growRate = 1,
			speedBoost=1
		},
	}
})

In the first block, the other listeners work because they’re only one index deep, but the last function containing [“guns”][“brocc”][“speedBoost”] path does not. I’m not sure if another function should be used or if there’s a way to pass it.

I also get no errors because the function still runs it just logically is wrong. I’ve checked the docs but it was not able to help me, and I have seen someone ask the question before but only buried in a post and I cannot find it again.

Should I make a separate data store? a new function? is there a way to pass longer paths that I’m missing? Please ask me to elaborate on anything if my explanation doesn’t resonate. Thanks for reading, any tips are appreciated!

I haven’t worked with ReplicaService before, but my replication system looks similar. From what I understand, what I would do is this. It listens for the “guns” value to change, and checks for if the “speedBoost” value changed.

local lastSpeedBoost = replica.Data.guns.brocc.speedBoost

replica:ListenToChange({"guns"}, function(newVal)
	local newSpeedBoost = newVal.guns.brocc.speedBoost
	
	if newSpeedBoost  ~= lastSpeedBoost then
		-- Speed boost value changed, do stuff
		lastSpeedBoost = newSpeedBoost 
	end
end)
1 Like

Good idea but just listening for guns doesn’t work when the deeper value changes. I changed the if statement and put it in the exp listener like this:

replica:ListenToChange({"exp"},function(newVal)
		if replica.Data["guns"]["brocc"]["speedBoost"] ~= gunVals.brocc.upgrades.speedBoost.Value then
			gunVals.brocc.upgrades.speedBoost.Value = replica.Data["speedBoost"]
		end
	end)

and it works, it checks the values everytime exp is updated. So to make this work right would it be a bad idea to add a playTime value and increment it every second and put this if statement check + the roughly 50-80 others in the playTime listener? I know its not the conventional way to track time but it would work to also update this. I could crosscheck with real playtime too when player leaves. That’s my first thought.

That would work if the speedBoost is only changed when exp is updated. But, if the speedBoost changes and the exp doesn’t, you’ll likely need a new un-nested value e.g. “gunsUpdateIteration” to update whenever the speedBoost changes, so it can actually be detected. Hope this helps