Setting all keys in a larger dictionary to a template breaks individual properties

  1. What do you want to achieve? I want to make 6 creature folders, all with different properties and instances in the future. These should all be distinct from each other.

  2. What is the issue? This dictionary is used as the template for all instances. This is as all creatures will have the same property instances BUT different values for each (e.g. 1 creature may have 5mp while another may have 12, both being stored as int values) in their respective folders. This is the template being used below:

local BaseCreatureDictionary = {
	CreatureName = "default";
	DexNumber = -1;
	Exists = false;
	StatsFolder = {
		hp = -1;
		mp = -1;
		atk = -1;
		def = -1;
		spatk = -1;
		spdef = -1;
	};
	ActionFolder = {
		action1 = {};
		action2 = {};
		action3 = {};
		action4 = {};
	};
	VariantFolder = {
		shiny = false;
		shimmer = "default";
	};
	LevelFolder = {
		level = -1;
		xp = -1;
		xpuntilnext = -1;
	};
}

This is the dictionary being created in the script:

PartyCreatures = {
	PartyCreature1 = BaseCreatureDictionary;
	PartyCreature2 = BaseCreatureDictionary;
	PartyCreature3 = BaseCreatureDictionary;
	PartyCreature4 = BaseCreatureDictionary;
	PartyCreature5 = BaseCreatureDictionary;
	PartyCreature6 = BaseCreatureDictionary;
}

Full relevant program:

function transfer(stat, location1, location2) --Only works when at bottom folder + no  abnormal .Value
	print(tostring(location1[stat]))
	print(tostring(location2[stat].Value))
	location1[stat] = location2[stat].Value
	print(tostring(location1[stat]))
	print(tostring(location2[stat].Value))
end

function LoadStats(id)
	local CoreStatsFolder = game.ServerStorage:FindFirstChild(tostring(id))
	local Creatures = CoreStatsFolder:WaitForChild("TotalCreaturesFolder")
	local Party = Creatures.PartyFolder
	
	local BaseCreatureDictionary = {
		CreatureName = "default";
		DexNumber = -1;
		Exists = false;
		StatsFolder = {
			hp = -1;
			mp = -1;
			atk = -1;
			def = -1;
			spatk = -1;
			spdef = -1;
		};
		ActionFolder = {
			action1 = {};
			action2 = {};
			action3 = {};
			action4 = {};
		};
		VariantFolder = {
			shiny = false;
			shimmer = "default";
		};
		LevelFolder = {
			level = -1;
			xp = -1;
			xpuntilnext = -1;
		};
	}
	
	--Setting everything to dictionary may be breaking them being individual dictionaries? Can't set manually since formatting breaks/too line consuming 
	PartyCreatures = {
		PartyCreature1 = BaseCreatureDictionary;
		PartyCreature2 = BaseCreatureDictionary;
		PartyCreature3 = BaseCreatureDictionary;
		PartyCreature4 = BaseCreatureDictionary;
		PartyCreature5 = BaseCreatureDictionary;
		PartyCreature6 = BaseCreatureDictionary;
	}
	
	print("Before setting, party creature 6's dictionary name is "..PartyCreatures.PartyCreature6.CreatureName)
	print("Before setting, party creature 6's exists is "..tostring(PartyCreatures.PartyCreature6.Exists))
	
	for i = 1, 6, 1 do
		print("Transferring from Creature"..tostring(i).." to dictionary creature..")
		local TargetCreatureSet = PartyCreatures["PartyCreature"..tostring(i)] --Dictionary to set. This specifically needs no .Value.
		local TargetCreatureStat = Party:WaitForChild("Creature"..tostring(i)) --Instance to take values from. This needs .Value.
		transfer("Exists", TargetCreatureSet, TargetCreatureStat)
		
		print("After setting, party creature 5's exists is "..tostring(PartyCreatures.PartyCreature5.Exists))
		print("After setting, party creature 6's exists is "..tostring(PartyCreatures.PartyCreature6.Exists))
		if PartyCreatures["PartyCreature"..tostring(i)].Exists == true then
			transfer("CreatureName", TargetCreatureSet, TargetCreatureStat)
			transfer("DexNumber", TargetCreatureSet, TargetCreatureStat)
		else
			print("Slot "..tostring(i).." on the team is unfilled!")
		end
		
		print(PartyCreatures.PartyCreature1.CreatureName)
		print(PartyCreatures.PartyCreature6.CreatureName)
	end
	print(PartyCreatures.PartyCreature1)
	print(PartyCreatures.PartyCreature2)
	print(PartyCreatures.PartyCreature3)
	print(PartyCreatures.PartyCreature4)
	print(PartyCreatures.PartyCreature5)
	print(PartyCreatures.PartyCreature6)
end

workspace.EncounterPart.Touched:Connect(function(hit)
	for i, v in game.Players:GetPlayers() do
		--Get the player who touched the part (if player)
		if hit.Parent.Parent == v.Character then
			local LinkedId = v.UserId
			
			--If the encounter spot is unpaired and the player isn't in an encounter:
			if workspace.EncounterPart.LinkedId.Value == -1 and game.ServerStorage:FindFirstChild(tostring(LinkedId)).InEncounter.Value == false then
				--Link the encounter spot and player is in encounter
				workspace.EncounterPart.LinkedId.Value = LinkedId
				game.ServerStorage:FindFirstChild(tostring(LinkedId)).InEncounter.Value = true
				
				--Initialise encounter
				print(v.Name.." with player id "..tostring(LinkedId).." has an encounter!")
				local LinkedPlayer = v
				LoadStats(LinkedId)
			end
		end
	end
end)
  1. What solutions have you tried so far? I tried checking similar DevForum posts, though did not find any relevant ones with keywords such as ‘template dictionary’ (only one being how to sync 2 dictionaries continuously). Originally, I believed that there was an error in setting. However, the values are set correctly until 6 (the only one with an intended difference). This reflects in ALL dictionaries in the console (e.g. below) but does NOT reflect in the instances themselves that the dictionaries are taking values from.
    This leads me to believe that there is an issue with a sync intended for 1 dictionary reflecting to all 6.

I apologise if this is obvious/if there are already existing posts in documentation/Devforum relevant to this. Thank you for reading this post and any help provided!

3 Likes

Don’t worry, this is what the forum is for.

The problem is that your “template table” is a variable that references a single table you created at the start of your script, and by setting it to multiple keys they are all referencing the same variable/table, not creating a new one from the template, which I believe is what you may be trying to do:

^ these are all sharing the same table! not having individual copies.

the solution is straight forward, actually create new tables from the template by using a function

function newPartyCreature()
	return {
		CreatureName = "default";
		DexNumber = -1;
		Exists = false;
		StatsFolder = {
			hp = -1;
			mp = -1;
			atk = -1;
			def = -1;
			spatk = -1;
			spdef = -1;
		};
		ActionFolder = {
			action1 = {};
			action2 = {};
			action3 = {};
			action4 = {};
		};
		VariantFolder = {
			shiny = false;
			shimmer = "default";
		};
		LevelFolder = {
			level = -1;
			xp = -1;
			xpuntilnext = -1;
		};
	}
end

and therefore, you use it like so:

PartyCreatures = {
	PartyCreature1 = newPartyCreature()
	PartyCreature2 = newPartyCreature()
	PartyCreature3 = newPartyCreature()
	PartyCreature4 = newPartyCreature()
	PartyCreature5 = newPartyCreature()
	PartyCreature6 = newPartyCreature()
}
3 Likes

Thank you so much!! Do you know if using a for loop to create multiple dictionary keys/values this way would work (e.g. for i = 1, 6, PartyCreatures[PartyCreature…tostring(i)] = newPartyCreature) or if it would be better to hard code the keys first?

2 Likes

It would work, but it would get rid of the autocomplete. I also don’t see how that’s better than using an array.