Cant replicate parts from datatable

What are you trying to accomplish with your encoder/decoder?

I want to make a game where you can mod it in roblox, my idea for maps was to make a script people cna put in a place, then that script runs through a folder and converts all the parts into a table, then converts that to a json string so it can be copied.

Then in the actual game they can paste that json string and it will load the data as a map.

In that case you should do data compression.
Like checking if the part has default Instance.new() Properties and if they are just don’t include it in the JSON, and again I would highly recommend you use Roblox’s API Dump because it would mean your code would support ANY Instance ALWAYS.

Another way you could compress the strings more is not encoding them in Json.
Let’s say you have these properties:

{
	Position = Vector3.new(1, 5, 1),
	Color = Color3.fromRGB(255, 255, 255)
}

It could also be represented as

"1, 5, 1|255, 255, 255"

Which you could then decode by doing (I think)

local Position = Vector3.new(string.split(string.split(String, "|")[1], ","))

You could further compress this by encoding the numbers into something like Base90
so instead of 255 it’d be something like ZA

idk if im up to that, ill see if i can find one of my friends to do it later

I did the decompression thing u mentioned:
image
turns into:
" 0|106, 57, 9, |-1, 3.5, -13.000000953674316, 1, 0, 0, 0, 1, 0, 0, 0, 1, |false|Enum.Material.Brick|true|16, 7, 2, |Enum.PartType.Block|true|Default|0|true|false|0|Burnt Sienna|true|true|true|true|Part|"
But now i dont know what property is what

hey it went from 700kb to 300kbs though, and i havnt even done the other compressino things u said

image

You want to make it ordered by your own property table.
So lets say the order is
Position
Size
Anchored
BrickColor
etc
If Anchored is default then the text would be
Position|Size||BrickColor
Then when decoding it you’d want to ignore values that are nil.

Alright, ill do that. How does base64 or whatever u said work?

Also does brickcolor matter? or can i just use color alone

So, default numbers you have 0-9 (Base10) but with something like Base90 instead of the default 0-9 you’d have your numbers be something like
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890
Each character representing a number.
Here’s a basic function that should encode/decode strings into Base90.

local EncodeChars = [==[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-=_+[]{}\;:'"<>/?.!@#$%^&*()]==]
local Base = #EncodeChars

local function EncodeNumber(num)
	if num == 0 then
		return EncodeChars:sub(1, 1)
	end

	local encoded = ""
	while num > 0 do
		local remainder = (num % Base) + 1
		encoded = EncodeChars:sub(remainder, remainder) .. encoded
		num = math.floor(num / Base)
	end
	return encoded
end

local function DecodeString(encoded)
	local num = 0
	for i = 1, #encoded do
		local char = encoded:sub(i, i)
		local charIndex = EncodeChars:find(char, 1, true)
		if not charIndex then
			error("Invalid character found in encoded string: " .. char)
		end
		num = num * Base + (charIndex - 1)
	end
	return num
end

Brick color does not matter, because you’re already saving the Color3 value.

Now have a defaults table


So i can check through that and see if i need to actualyl care about the property

Is this efficent to do for checking if a property is already the default
image

Yes, but you should use a for loop on the defaults table.

for Property, DefaultValue in pairs(Proto.Defaults) do
	if Part[Property] ~= DefaultValue then
		InfoTable[Property] = Part[Property]
	else
		InfoTable[Property] = ""
	end
end

How do i implement this into this script:

local function Decode(Part)
	warn("Decoding part: "..Part.Name)
	
	local InfoTable = {}
	local Tags = {}
	
	--JSON does notsupport some things, so they are converted to strings/tables.
	
	--Appearance:
	--InfoTable.BrickColor = tostring(Part.BrickColor) --Brickcolor is useless to save.
	InfoTable.CastShadow = Part.CastShadow
	InfoTable.Color = {math.round(Part.Color.R*255), math.round(Part.Color.G*255), math.round(Part.Color.B*255)} --Rounded because floating points
	InfoTable.Material = tostring(Part.Material)
	InfoTable.Reflectance = Part.Reflectance
	InfoTable.Transparency = Part.Transparency
	
	--Data:
	InfoTable.Archivable = Part.Archivable
	InfoTable.Locked = Part.Locked
	InfoTable.Name = Part.Name
	--No Parent Required

	--Transform
	InfoTable.Size = {Part.Size.X, Part.Size.Y, Part.Size.Z}
	--InfoTable.CFramePos = {Part.CFrame.Position.X, Part.CFrame.Position.Y, Part.CFrame.Position.Z}
	--InfoTable.CFrameRot = {Part.Rotation.X, Part.Rotation.Y, Part.Rotation.Z}
	InfoTable.CFrame = {Part.CFrame:GetComponents()}
	
	--Behavior
	InfoTable.EnableFluidForces = Part.EnableFluidForces
	
	--Collision
	InfoTable.CanCollide = Part.CanCollide
	InfoTable.CanQuery = Part.CanQuery
	InfoTable.CanTouch = Part.CanTouch
	InfoTable.CollisionGroup = Part.CollisionGroup
	
	--Part
	InfoTable.Anchored = Part.Anchored
	InfoTable.CustomPhysicalProperties = Part.CustomPhysicalProperties
	InfoTable.Massless = Part.Massless
	InfoTable.RootPriority = Part.RootPriority
	InfoTable.Shape = tostring(Part.Shape)
	
	--Tags
	for _, V in Part:GetTags() do
		table.insert(Tags, V)
	end
	
	local FinalTable = {}
	table.insert(FinalTable, InfoTable)
	table.insert(FinalTable, Tags)
	local FinalFinalTable = {}
	
	warn("Finished Decoding: "..Part.Name)
	
	return FinalTable
end

Ideally you’d create a function that’d convert every Value into a string.
Like

local Conversions = {
	Vector3 = function(Vector3)
		return Vector3.X..Vector3.Y..Vector3.Z
	end
}

etc
You could detect what type the value is with typeof(Value)

CFrame does not come out of this
image

CFrame isn’t part of your defaults table.

i just added it manually, could we maybe start talking about this over PMs? we have gone off topic now