How could I get an object from OOP from both client and server

im trying to make a custom system for a part using OOP that needs both the server and client on the same object. how could I do something like this?

Example of what i mean:

--server

local module = require(pathtomodule)

newObject = module.new(script.Parent)


-- client

newObject.returnPartPosition() --- this is obviously just an example, but you get what i mean
2 Likes

You could use game:GetService("RunService"):IsServer() in the module and write code for both server and client. To pass information between client and server, you could use a RemoteEvent or RemoteFunction, using sanity checks on the server to prevent exploiting if necessary.

I appreciate the response! but could you show me a quick example on how to implement this?

Sure thing:

-- In the module shared by the server and client

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

local IS_SERVER = RunService:IsServer()

local PartClassRemoteEvent = ReplicatedStorage.PartClassRemoteEvent

local PartClass = {}
PartClass.__index = PartClass

function PartClass.new(part)
    local self = setmetatable({}, PartClass)

    self.Part = part

    if IS_SERVER then
        -- Do server-only stuff to the part here
    else
        -- Do client-only stuff to the part here
    end

    return self
end

function PartClass:ReturnPartPosition()
    return self.Part.Position
end

function PartClass:ChangePosition(positionV3)
    if IS_SERVER then -- Change position on the server so change is visible to all players

        -- Do sanity checks in this area --

        -- Change position
        self.Part.Position = positionV3
    else
        PartClassRemoteEvent:FireServer(self.Part.Name, "ChangePosition", positionV3)
    end
end
-- In a server script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PartClassRemoteEvent = ReplicatedStorage.PartClassRemoteEvent

local PartClass = require(pathToModule)

local objects = {}

local part = pathToPart

local newObject = PartClass.new(part)

if newObject then
    objects[part.Name] = newObject
end

PartClassRemoteEvent.OnServerEvent:Connect(function(player, partName, functionName, ...) 
    local object = objects[partName]

    if object and object[functionName] then -- If object exists and function exists
        object[functionName](object, ...) -- Call the function on the object and pass the object (self) as the first argument
    end
end)
-- In a client LocalScript

local PartClass = require(pathToModule)

local part = pathToPartHere

local newObject = PartClass.new(part)

local examplePositionV3 = Vector3.new(0, 0, 0)

newObject:ChangePosition(examplePositionV3)

Basically, you have to create a twin object on the client with the same part as you used on the server. IS_SERVER lets you know if the code in the module is being run on the server or the client.

4 Likes

I am pretty sure you can add the metatables from module.new() into a universal table (unless Iā€™m wrong)?