I am creating a networking module, based on something I found a while ago but cannot find anymore.
Network Module (part of it)
function network:new(networkName) -- Server ONLY function to create a network.
if Networks:FindFirstChild(networkName) ~= nil then -- Check to see if it already exists.
error("A network with that name already exists!");
end
local self = setmetatable( {}, network );
--
-- Setup the network folder.
self.NetworkName = networkName;
self.NetworkFolder = Instance.new("Folder", Networks);
self.NetworkFolder.Name = self.NetworkName;
self.Ports = {};
--
table.insert(shared.Networks, self);
return self;
end
function network:DisplayName()
print(self.NetworkName);
end
This is a modulescript in replicatedstorage. When I require the module from the client, and do
local PartNetwork = Network:GetNetwork(âPartNetworkâ);
print(PartNetwork.NetworkName)
everything works fine.
But, if I do
PartNetwork:DisplayName()
I get this error: [attempt to call method âDisplayNameâ (a nil value)
Thereâs probably something really dumb I am forgetting to do. I swear I have done this same method many times and have had no problems.
Edit: Sorry for the ugly formatting, couldnât figure out how to just copy and paste the script in here, so I had to space out every line manually.
Iâm inserting it into shared.Networks because I get the Networks from another server script, for when the client requests it. The GetNetwork function is this:
function network:GetNetwork(networkName)
local IsClient = RunService:IsClient();
if not IsClient then
for _,a in pairs(shared.Networks) do
if a.NetworkName == networkName then
return a;
end
end
return nil;
else
local found = RS.GetNetServ:InvokeServer(networkName);
return found;
end
end
Edit: here is GetNetServ:
local GetNetworkServer = Instance.new("RemoteFunction", RS);
GetNetworkServer.Name = "GetNetServ";
local function GetNetwork(Player, networkName)
for _,a in pairs(shared.Networks) do
if a.NetworkName == networkName then
return a;
end
end
return nil;
end
GetNetworkServer.OnServerInvoke = GetNetwork;
I donât know why the formatting is so weird here. Sometimes it works, sometimes not.
-- Module
local network = {}
network.__index = network
function network:new(networkName)
local self = setmetatable({}, network)
self.NetName = networkName
return self
end
function network:DisplayName()
print(self.NetName)
end
return network
-- Server Script
local A = require(script.Parent.ModuleScript)
local B = A:new("yes")
B:DisplayName()
I ran this rough code in Studio and there wasnât any issues with it. Perhaps youâve set up your code incorrectly? If not, Iâll have to take another look at the code and see where yours is going wrong.
By the way, if youâre intending for this Network module to be a class, why not use the method network.new? Keep in mind that network:new(networkName) passes 2 arguments, not one - that is self (a variable representation of the table that the method is in) and any other arguments specified in the function. In this code, youâre basically overwriting self with something else and pushing that back out.
Iâm not sure if this is it, but it seems you canât pass functions within a table through a RemoteFunction. Iâm either doing something wrong, or you just really canât do that.
It seems more that OP is trying to pass a name through, not a function. The main issue seems to be that OP isnât receiving the methods for the table that is created and returned from the New method. However that may be, you are correct - you cannot pass functions through remotes.
Yes, this is my problem. I am recieving the metatable on the client, and I have the properties such as .NetworkName working, but when I try and use the methods, it does not work.
This means that when a table is created via network:new, it is not attaching the ânetworkâ table as __index. Try changing how the method is called (network:new â network.new) or using a variable that isnât self. Iâve also supplied some module code that I believe looks like yours and does function as far as Iâve tested.
Just to clarify, classes usually are set up like this:
local Class = {}
Class.__index = Class
function Class.new(args)
local this = {}
this.args = args
setmetatable(this, Class)
return this
end
function Class:Method(args)
print(self.args, args)
end
return Class
Youâre correct that the syntax for a constructor would be .new and not :new, but I donât think that causes much of an issue since âselfâ isnât used until after itâs changed.
Iâm pretty sure that he can invoke DisplayName up until it goes through the RemoteFunction, and then it loses all functions since they donât pass through.
OH. Okay, now that I read the RemoteFunction, I see what the problem is. âGetNetworksâ is supposed to return the table of networks, right? Youâre trying to access networks created on one environment on another? Chasing is right then - you cannot pass functions through remotes.
Maybe within your new function, you could check if itâs from the client, and simply apply the network metamethod to the function-less set of properties. Youâd have to do network:new(...) on whatever you receive from the server, though.
Alternatively, you could put that in another function, which would probably be more clean.