How should I go about making this?

Currently I’m trying to make a troll save system (similar to the games World of Trollge). Basically, you can store characters in an inventory. When you equip the characters, your avatar completely changes to the character. The problem is, I dont know how to go about making this. I thought of making a dress function but that would be impractical as I’d have to add that for every character in the game (a lot).

Any help is appreciated :cowboy_hat_face:

You can use ApplyDescription on the Humanoid to dress it as a player.

Humanoid:ApplyDescription(Description: HumanoidDescription)

You can get a description of a player via a UserID

local Players = game:GetService("Players");

local UserId = 1

local NewHumanoidDescription = Players:GetHumanoidDescriptionFromUserId(UserId)

I’ve looked around and I saw that, however I was wondering would that work if the rig has extra parts? Example:

You’ll need to add it yourself then. If you have the physical asset of it, you can just copy the body of it and then manualy get all the accessories/addons (for i,v loop) then place them onto the player.

Ah, alright. Thanks. I’ll give it a try!

I tried this, and it hasn’t worked. I think its because theres a StarterCharacter for the game. Is there any other way to fix this?

The real question here is what you want to save? For example if a player unlocks a troll, and you decide to update it afterwards, do you want them to have the old or the updated version? If you want their outfits to update you can simply store custom enums(they can be strings, numbers, or anything that acts as an identifier for a specific troll) to the database and basically load their outfits from a folder within the game itself(according to the troll identifiers in their data). Basically what we’re asking here is what’s the minimal but practical information we need to store in order to distinguish between the owned trolls. Just their names can be enough assuming they’re unique.

1 Like

Yes, I want their outfits to update, sorry for not being clear :sweat_smile:

I used your string method and for some reason, the strings values arent saving. Like, when I swap the characters it originally does change the string value(s) text to the the character’s name, however when I leave and rejoin, the string value(s) text shows up as blank, it didn’t save.

Server code:

--//Services
local DSS = game:GetService("DataStoreService")
local TROLL_DS = DSS:GetDataStore("TROLL_DATA")
local RS = game:GetService("ReplicatedStorage")
local PLAYERS = game:GetService("Players")
local save_trolls_event = RS:WaitForChild("SAVING_EVENTS").SAVE_TROLLS

--//Variables
local troll_folder = RS:WaitForChild("Trolls")

--//Save Trolls Remote
function trolls_remote(player, object, selected_troll, value)
	object.Parent.Value = selected_troll.Name
	value = true
end

--//OnPlayerAdded
function on_player_added(player)
	local troll_data = TROLL_DS:GetAsync(player.UserId) or {}
	
	--folder
	local troll_inventory = Instance.new("Folder");
	local troll_1 = Instance.new("StringValue", troll_inventory); troll_1.Name = "String_1"; local available_1 = Instance.new("BoolValue", troll_1);
	local troll_2 = Instance.new("StringValue", troll_inventory); troll_2.Name = "String_2"; local available_2 = Instance.new("BoolValue", troll_2);
	local troll_3 = Instance.new("StringValue", troll_inventory); troll_3.Name = "String_3"; local available_3 = Instance.new("BoolValue", troll_3);
	local troll_4 = Instance.new("StringValue", troll_inventory); troll_4.Name = "String_4"; local available_4 = Instance.new("BoolValue", troll_4);
	local troll_5 = Instance.new("StringValue", troll_inventory); troll_5.Name = "String_5"; local available_5 = Instance.new("BoolValue", troll_5);
	local troll_6 = Instance.new("StringValue", troll_inventory); troll_6.Name = "String_6"; local available_6 = Instance.new("BoolValue", troll_6);
	local troll_7 = Instance.new("StringValue", troll_inventory); troll_7.Name = "String_7"; local available_7 = Instance.new("BoolValue", troll_7);
	local troll_8 = Instance.new("StringValue", troll_inventory); troll_8.Name = "String_8"; local available_8 = Instance.new("BoolValue", troll_8);
	local troll_9 = Instance.new("StringValue", troll_inventory) troll_9.Name = "String_9" local available_9 = Instance.new("BoolValue", troll_9);
	
	local attribute = player:SetAttribute("Selected_Troll", "Boiling stars")
	
	for _, troll_saved in pairs(troll_data) do
		if troll_folder:FindFirstChild(troll_saved) then
			for _, value in pairs(troll_inventory:GetChildren()) do
				if value:IsA("BoolValue") then
					if value.Value == true then
						value.Parent.Value = troll_saved.Name
					end
				end
			end
		end
	end
	
	troll_inventory.Name = "Troll_Storage"
	troll_inventory.Parent = player
end

--//OnPlayerLeaving
function on_player_leaving(player)
	local trolls = {}
	local storage = player:WaitForChild("Troll_Storage")
	
	for _, troll_name in pairs(storage:GetChildren()) do
		table.insert(trolls, troll_name.Value)
	end
	
	local success, error_msg = pcall(function()
		TROLL_DS:SetAsync(player.UserId, trolls)
	end)
	
	if (error_msg) then
		warn(error_msg)
	else
		print("Trolls were successfully stored!")
	end
end

--//Connecting
PLAYERS.PlayerAdded:Connect(on_player_added)
PLAYERS.PlayerRemoving:Connect(on_player_leaving)
save_trolls_event.OnServerEvent:Connect(trolls_remote)

Client code:

local PLAYERS = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")

--//Variables
local player = PLAYERS.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local inventory = player:WaitForChild("Troll_Storage")
local buttons = script.Parent
local trolls_folder = RS:WaitForChild("Trolls")
local save_trolls_event = RS:WaitForChild("SAVING_EVENTS").SAVE_TROLLS

for i, button: TextButton in buttons:GetChildren() do
	if not button:IsA("TextButton") then
		continue
	end
	
	for _, object in pairs(inventory:GetChildren()) do
		if object:IsA("StringValue") then
			button.Text = object.Value
			
			if (button.Text == "") then
				button.Text = "Troll"
			end
		end
	end
	
	button.MouseButton1Down:Connect(function()
		button.Text = player:GetAttribute("Selected_Troll")

		if (trolls_folder:FindFirstChild(player:GetAttribute("Selected_Troll"), true)) then
			local selected_troll = trolls_folder:FindFirstChild(player:GetAttribute("Selected_Troll"), true)
			
			for _, object in pairs(inventory:GetDescendants()) do
				if (object:IsA("BoolValue")) then
					if object.Value == false then
						save_trolls_event:FireServer(object, selected_troll, object.Value)
					end
				end
			end
		end
	end)
end

Alright so heres a little update I fixed that yet theres still a problem. When I open it all of the saved items are there besides one. So when I try to insert a new character, it doesnt save. Its hard to explain, sorry :sweat_smile: but here is a video that will hopefully show what I mean


Client code:

local PLAYERS = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")

--//Variables
local player = PLAYERS.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local inventory = player:WaitForChild("Troll_Storage")
local buttons = script.Parent
local trolls_folder = RS:WaitForChild("Trolls")
local save_trolls_event = RS:WaitForChild("SAVING_EVENTS").SAVE_TROLLS

for i, button: TextButton in buttons:GetChildren() do
	if not button:IsA("TextButton") then
		continue
	end
	
	task.wait(0.1)
	if inventory:GetChildren()[i] then
		button.Text = inventory:GetChildren()[i].Value
	end
	
	for _, object in inventory:GetChildren() do
		if (object:IsA("TextButton")) then
			button.Text = object.Value
			
			if (button.Text == "") then
				button.Text = "Troll"
			end
		end
	end
	
	
	button.MouseButton1Down:Connect(function()
		local current_string = inventory:FindFirstChild("String_"..button.Name)
		local selected_troll = player:GetAttribute("Selected_Troll")
		
		current_string.Value = selected_troll; button.Text = selected_troll
	end)
end

Server code:

--//Services
local DSS = game:GetService("DataStoreService")
local TROLL_DS = DSS:GetDataStore("TROLL_DATA")
local RS = game:GetService("ReplicatedStorage")
local PLAYERS = game:GetService("Players")
local save_trolls_event = RS:WaitForChild("SAVING_EVENTS").SAVE_TROLLS

--//Variables
local troll_folder = RS:WaitForChild("Trolls")

--//Save Trolls Remote
function trolls_remote(player, object, selected_troll)
	if (object) then
		object.Value = selected_troll.Name
		print("Server: Saved troll '" .. selected_troll .. "' to " .. object)
	else
		warn("Server: StringValue '" .. object .. "' not found in troll_inventory")
	end
end

--//OnPlayerAdded
function on_player_added(player)
	local troll_data = TROLL_DS:GetAsync(player.UserId) or {}
	
	--folder
	local troll_inventory = Instance.new("Folder");
	
	for i = 1, 9 do
		local troll_string = Instance.new("StringValue")
		troll_string.Name = "String_" .. i
		troll_string.Parent = troll_inventory
		
		if troll_data[i] and troll_data[i] ~= "" then
			troll_string.Value = troll_data[i]
			print("Server: Loaded troll '" .. troll_string.Value .. "' into " .. troll_string.Name)
		else
			troll_string.Value = "Troll"
			print("Server: Initialized " .. troll_string.Name .. " with default value 'Troll'")
		end
	end
	
	local attribute = player:SetAttribute("Selected_Troll", "SuperNova")
	
	for _, troll_saved in pairs(troll_data) do
		if troll_folder:FindFirstChild(troll_saved) then
			for _, value in pairs(troll_inventory:GetChildren()) do
				if value:IsA("BoolValue") then
					if value.Value == true then
						value.Parent.Value = troll_saved.Name
					end
				end
			end
		end
	end
	
	troll_inventory.Name = "Troll_Storage"
	troll_inventory.Parent = player
end

--//OnPlayerLeaving
function on_player_leaving(player)
	local trolls = {}
	local storage = player:WaitForChild("Troll_Storage")
	
	for i = 1, 9 do
		local troll_string = storage:FindFirstChild("String_" .. i)
		
		if troll_string then
			table.insert(trolls, troll_string.Value)
			print("Server: Preparing to save " .. troll_string.Name .. " with value '" .. troll_string.Value .. "'")
		end
	end
	
	local success, error_msg = pcall(function()
		TROLL_DS:SetAsync(player.UserId, trolls)
	end)
	
	if (error_msg) then
		warn(error_msg)
	else
		print("Trolls were successfully stored!")
	end
end

--//Connecting
PLAYERS.PlayerAdded:Connect(on_player_added)
PLAYERS.PlayerRemoving:Connect(on_player_leaving)
save_trolls_event.OnServerEvent:Connect(trolls_remote)

Any help is appreciated :cowboy_hat_face: