Converter Module: Instance ↔ Table | Save Instances to DataStores and More!

This is very helpful!

Is there any way to instead of have excluded properties, We can also have a whitelist?
I’d like to save only a couple of properties, Without having to set all other properties excluded.

1 Like

Thanks for the feedback!

Yep, that feature is planned to be included with the next module version but it might be a while until that update gets released.

1 Like

For some reason my script keeps giving me the error “Script Exceeded Allowed Execution Time”
Here’s my loading script:

`local DataStoreService = game:GetService(“DataStoreService”)
local Converter = require(9768577563)
local playerData = DataStoreService:GetDataStore(“playerData”)

game.Players.PlayerAdded:Connect(function(player)

local data 
local success, errormessage = pcall(function()
	data = playerData:GetAsync(player.UserId.." stats4") 
end)

if success and data ~= nil then 
	local loaded = Converter:Convert(data)
	print("loaded stats")
	for i, v in pairs(loaded:GetChildren()) do
		v.Parent = player
		wait()
		end
else
	print("made new stats")
	local leaderstats = Instance.new("Folder")
	local kills = Instance.new("NumberValue")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	kills.Name = "Kills"
	kills.Value = 0
	kills.Parent = leaderstats
	local money = Instance.new("NumberValue")
	money.Name = "$"
	money.Value = 100
	money.Parent = leaderstats
	local opps = Instance.new("NumberValue")
	opps.Name = "Opps"
	opps.Value = 0
	opps.Parent = leaderstats
	local data = Instance.new("Folder")
	local stamina = Instance.new("NumberValue")
	data.Name = "Data"
	data.Parent = player
	stamina.Name = "Stamina"
	stamina.Value = 7
	stamina.Parent = data
	local incombat = Instance.new("BoolValue")
	incombat.Name = "incombat"
	incombat.Value = false
	incombat.Parent = data
end
if player.Data.incombat.Value == true then
	player.Data.incombat.Value = false
	player.leaderstats["$"].Value -= 50
end

end)`

Saving Script:

`local DataStoreService = game:GetService(“DataStoreService”)
local Converter = require(9768577563)
local playerData = DataStoreService:GetDataStore(“playerData”)

game.Players.PlayerRemoving:Connect(function(player)

local success, errormessage = pcall(function()
	playerData:SetAsync(player.UserId.." stats4", Converter:Convert(player))
end)

if success then
	print("Data successfully saved!")
else
	print("There was an error while saving the data")
	warn(errormessage)
end

end)`

1 Like

your saving player instance into table and you load the data which your recreating leaderstats which is parented on player?

You ran into that error from converting a Player instance which holds the Character model (which can exist while parented to nil!). Thanks for the bug report! :smiley: I went ahead a pushed a quick fix for that.

As for your data methods, I would not suggest saving the entire Player instance for a couple reasons:

  1. It’ll take up a lot more data than necessary.
  2. You might end up with duplicated instances if you don’t check them before reparenting, which will exponentially fill up your data.
  3. Scripts/modules can’t make Player instances (shown below), which might lead to incompatible data if you don’t make accommodations in your code for it.

If you’re looking to do a bunch of leaderstats or player data, I’d suggest converting and saving just the leaderstats folder instead. And to reduce space even further, you can do something like the Easy Player Data Management example where you use folders and assign attributes, resulting in smaller tables with basic key-value pairs.

Can this work with the client though? You completely disregarded client-sided chunk loading systems like Minecraft based games. I get the world chunks data from the server then transform that data back to Instances on each client. But I can’t do that is what you’re saying? Why? How is that a security issue?

No, this cannot work on the client. You have to require this module on the server.

Using a tool for one of its features does not prevent all other capabilities of that tool. Just like a knife can be used for cooking, it can also be used maliciously. Without security measures, just like any other tool, modules can be used outside of their intended purpose, which is why Roblox prevents the client from executing remote code and disables module require-requests (via link). It’s up to the developer to make smart and secure client methods and to decide which modules the client should be allowed to access.


This would be the main misuse of the module by a bad actor. This is just how Roblox works as an open-end client platform. In Roblox, your building data isn’t encrypted to the client due to how the game needs to communicate with client code in order to replicate properties. Without it, Roblox would be very limited on what users could create.

Copying the building data with an external tool is all it takes to mimic what some developers have spent hundreds or even thousands of hours crafting. I’m sure you’ve seen stolen assets and copied games on the platform because of that. Roblox has always had this issue since the game was created. They frequently add security patches that prevent those external programs from working, then another one comes along. This script has safeguards to prevent it from being used in that way.


You can convert your chunks on the server and send the conversion data to the client with a remote function/event. You just need to create a local script for the clients to make chunks since this module can’t be accessed by the client.

A) I’m not requiring the module, I put it in ReplicatedStorage in Studio.

B) I removed your HttpService:GetAsync(DumpURL) call and just copied the CloneTrooper dump to a lua table and put it in its own ModuleScript in ReplicatedStorage.

C) You can’t pass Instances or UserData between client/server boundaries. That’s why I have to convert it and convert it back on both sides.
[Argument Limitations for Bindables and Remotes | Documentation - Roblox Creator Hub]

Non-Replicated Instances
If an event or function passes a value that’s only visible to the sender, Roblox doesn’t replicate it across the client-server boundary and passes nil instead of the value. For example, if a Script tries to pass a descendant of ServerStorage, the client listening to the event receives a nil value because that object isn’t replicable for the client. Similarly, if you create a part in a LocalScripts and try to pass it to a Script, the server sees nil because the part isn’t replicable for the server.”

Once I’m finished reprogramming your module to adapt to my needs, I’ll repost it here for anyone else who needs similar features.

Also, the method of copying player’s build through the module is A LOT HARDER. Exploiters can just use an external function called saveinstance() to steal the entire clients side of the game: Replicated Storage, workspace, Lighting, StarterGui, Local Scripts, ModuleScripts, anything accessible by the client they can see and save to file. So it’s easier for them to just do that anyways instead of going through a module to look at lua tables to recreate a model which they could just world download to a RBXL file. I already am WELL familiar with Roblox exploits and security issues, and I’m telling you, your module could be client-sided easily and without any issues or security flaws.

Why does my PlayerAdded Function Break when i require the module script?