How to make a client sided part that replicates to the server

Basically, I want to be able to make a part on my client and replicate that data to the server. And yes, the part will originate on the client. Also not just NetworkOwnership, but every property will replicate to the server. And if there is a way at all, please don’t just say it’s unsafe to use and not tell me. I’m just curious if this is possible. (preferably without RemoteEvents)

3 Likes

I’m pretty sure that without remotes this is kind of impossible, do you still want a response with the use of remote events or nah?

1 Like

If it’s impossible to do it without remotes then I guess I could use them, so sure

1 Like

No, you cannot replicate a client-created part to the server conventionally. This is what filtering enabled prevents!

I’m not simply looking for a setting to toggle such as FilteringEnabled to grant the client access to replicate parts to the server as they wish. I’m looking for a way to send the part’s data to the server and replicate it with the server’s permission

1 Like

You cannot toggle FilteringEnabled. If you wish to send the data to the server, then wrap the properties in a table and send it through a remote event/function as the instance itself cannot be sent through.

1 Like

I already know FilteringEnabled is not an option. I get what you’re saying but would such a system put an unnecessary strain on the server?

1 Like

It is possible, yes, with a remote function that continously sends a table of properties for the server to handle and set, however, I truly don’t know the reason you would want to do that as it’s as unsafe as it can get. It can also be preferably sped up with the new parallel luau methods.

It would be less costly than having a part replicated over the network if you reduce the number of properties you send over, unless you do it like, a hundred times a second.

More information on what you are doing can let us give you more help.

Even tho I don’t really get why someone would do this, you might have something in mind or just playing around.

⚠ WARNING ⚠

DO NOT USE IN YOUR GAME, VERY VULNERABLE

Client:

local Controller = {} do
    Controller.Parts = {}
    local Event = game:GetService("ReplicatedStorage").YourEvent

    function ReduceTableContent(NewTable, OldTable)
        local ReducedTable = {}

        for key, value in pairs(NewTable) do
            if OldTable[key] ~= value then
                ReducedTable[key] = value
            end
        end

        return ReducedTable
    end

    function Controller.IntializeReplication(Part: BasePart)
        if not Controller.Parts[Part] then
            Controller.Parts[Part] = {
                ["LastReplicatedData"] = {},
                ["Id"] = game.HttpService:GenerateGUID(false)
            }
        end
    end

    function Controller.Replicate(Part)
        if not Part:GetAttribute("ServerPart", true) then
            if Controller.Parts[Part] then
                local Data = {
                    ["Parent"] = Part.Parent,
                    ["CFrame"] = Part.CFrame,
                    ["Size"] = Part.Size,
                    ["Anchored"] = Part.Anchored,
                    ["CanCollide"] = Part.CanCollide,
                    ["Transparency"] = Part.Transparency,
                    ["Color"] = Part.Color
                }

                if Data ~= Controller.Parts[Part]["LastReplicatedData"] then
                    Event:FireServer({
                        ["Id"] = Controller.Parts[Part].Id, 
                        ["Properties"] = ReduceTableContent(Data, Controller.Parts[Part].LastReplicatedData)
                    })
                    Controller.Parts[Part]["LastReplicatedData"] = Data
                end
            else
                Controller.IntializeReplication(Part)
                Controller.Replicate(Part)
            end
        end

    end


    function Controller.Init()
        workspace.Replicatable.ChildAdded:Connect(function(Part: BasePart) 
            Controller.Replicate(Part)
        end)

        for i = 1,10 do 
            local part = Instance.new("Part") part.Name = "part"..i 
            part.Anchored = true 
            part.Position = Vector3.new(0, i, 0) 
            part.Parent = workspace.Replicatable 
            part.CollisionGroup = "replicatableparts"
        end

        
        for Index, Value in Controller.Parts do
            Index.Changed:Connect(function()
                Controller.Replicate(Index)
            end)
        end
        
        while task.wait() do
            for Index, Value in workspace:GetDescendants() do
                if Value:GetAttribute("ServerPart", true) and not Value:GetAttribute("HasBeenConfigured", true) then
                    Value.Transparency = 1
                    Value.CanCollide = false
                    Value.Locked = true
                    Value.Name = Value.name.."_SERVERPART"
                    Value:SetAttribute("HasBeenConfigured", true)
                end
            end
        end
        
    end

end

return Controller

Server:

local Controller = {} do
    Controller.Parts = {}
    local Event = game:GetService("ReplicatedStorage").YourEvent
    local InstanceNew = Instance.new

    function Controller.Replicate(Player, Info: {Id: number, Properties: table})
        local Part

        if not Controller.Parts[Info.Id] then
            Part = InstanceNew("Part")
            Controller.Parts[Info.Id] = Part
        else
            Part = Controller.Parts[Info.Id]
        end

        for Property, Value in pairs(Info.Properties) do
            if Part[Property] ~= Value then
                Part[Property] = Value
            end
        end

        Part:SetAttribute("ServerPart", true)
        Part.CollisionGroup = "ReplicatedParts"
    end

    function Controller.Init()
        Event.OnServerEvent:Connect(Controller.Replicate)
    end
end

return Controller

Note:
I made this for fun, I don’t have time to improve it, yet it gives more than a basic idea on how this can be done BUT AGAIN DONT USE IT! Also these scripts are modules so you need to require them to use them. If you don’t know how modules work, here is the doc page for them! Also even tho “GenerateGUID” is not the best thing to use (as far as I know) I used it to save time and because it doesn’t make such a difference as this is just an example and it wont be used anywhere. I fixed the lag issue and also it is suggested to use collision groups for the replicated and replicatable parts so issues are reduced, it is not suggested to drag move a part, and it is not suggested to unanchor them, it get messy!

1 Like

Fixing lag issue (I’m brainless) and also adding something to make it more smooth in a sec

Alright lag is fixed now and they are also less buggy now because of disabled collisions!

If you want to replicate property changes efficiently, use delta compression – sending properties only when they have changed. @Iampros33’s example uses this.

However, a large amount of data will be used to send over the string keys, and you would also be using an unnecessary amount of data to send certain properties, such as Transparency (Transparency is between 0 to 1, and by default would take 9 bytes because all numbers are 64-bit floats, but you can use only 1 to represent it with 2 digits of precision) and boolean properties (only 1 bit is necessary but Roblox uses 2 bytes by default). I would highly recommend using the following:

1 Like

Very well said, also it could be made so instead of firing an enormous amount of events when for example its position is changed, limit it and only fire for example every .5 second (this is just an example you can use whatever works best for you) or something. It might be less smooth but it is much more optimized.


(sorry for the rushed drawings, I have no time to make them look good)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.