I am making a zone system, where the player touches a part, and then various effects happen on the client.
I have multiple zones set up in a module script like so:
The server script works exactly how I want it to work, but here it is for context:
local ReplicatedStorage = game.ReplicatedStorage
local UpdateZone = ReplicatedStorage:WaitForChild("UpdateZone")
local ZoneParts = workspace.ZoneParts
for _, v in pairs(ZoneParts:GetChildren()) do
v.Touched:Connect(function(hit)
local Player = game.Players:GetPlayerFromCharacter(hit.Parent)
local Backpack = Player.Backpack
if Backpack.CurrentZone.Value == v.Name then return end
--print(v:GetFullName())
if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
--print(hit:GetFullName())
if Player == nil then return end
Backpack.CurrentZone.Value = v.Name
UpdateZone:FireClient(Player)
end
end)
end
The problem lies within the client script in ReplicatedFirst:
local ReplicatedStorage = game.ReplicatedStorage
local ZoneModule = require(ReplicatedStorage:WaitForChild("ZoneModule"))
local ZoneData = ZoneModule.ZoneStats
local UpdateZone = ReplicatedStorage:WaitForChild("UpdateZone")
local ZoneParts = workspace.ZoneParts
function GetCurrentZone()
for _, v in pairs(ZoneParts:GetChildren()) do
local CurrentZone = ZoneData[v.name]
if CurrentZone ~= nil then
return v, CurrentZone
else
warn("No stats for this zone!")
end
end
end
UpdateZone.OnClientEvent:Connect(function()
GetCurrentZone()
-- stuff happens
end)
This is the error that it keeps throwing.
I’m drawing a blank here because I have defined ZoneData, or so I thought anyhow.
As the topic suggests, to me it appears that the module script is just not being required for some reason.
I’m assuming that there’s something about module scripts that I’m not understanding.
Odd. ZoneStats module does not have ZoneStats.ZoneStats. If you understand exactly what a module script does, the table returned from the module is on the variable already after requiring. The value is, but not the variable name from it.
local ReplicatedStorage = game.ReplicatedStorage
-- This is wrong
local ZoneModule = require(ReplicatedStorage:WaitForChild("ZoneModule"))
local ZoneData = ZoneModule.ZoneStats
local UpdateZone = ReplicatedStorage:WaitForChild("UpdateZone")
local ZoneParts = workspace.ZoneParts
function GetCurrentZone()
for _, v in pairs(ZoneParts:GetChildren()) do
local CurrentZone = ZoneData[v.name]
if CurrentZone ~= nil then
return v, CurrentZone
else
warn("No stats for this zone!")
end
end
end
UpdateZone.OnClientEvent:Connect(function()
GetCurrentZone()
-- stuff happens
end)
local ReplicatedStorage = game.ReplicatedStorage
local ZoneData = require(ReplicatedStorage:WaitForChild("ZoneModule"))
local UpdateZone = ReplicatedStorage:WaitForChild("UpdateZone")
local ZoneParts = workspace.ZoneParts
function GetCurrentZone()
for _, v in pairs(ZoneParts:GetChildren()) do
local CurrentZone = ZoneData[v.name]
if CurrentZone ~= nil then
return v, CurrentZone
else
warn("No stats for this zone!")
end
end
end
UpdateZone.OnClientEvent:Connect(function()
GetCurrentZone()
-- stuff happens
end)
Compare between, a variable in a script that required a module “inherits” all of its contents.
local StarterPack = game.StarterPack
local Zone = {}
Zone.__index = Zone
function Zone.new(name)
return setmetatable({
Name = name,
FogEnd = 1000,
FogColor = Color3.fromRGB(255,0,0),
Ambient = Color3.fromRGB(0,0,255),
Brightness = 0,
Music = StarterPack.ZoneMusic.TEST,
LocationText = tostring("Test Area"),
LocationDescription = tostring("Test Description"),
}, Zone)
end
return Zone
--Script
local ReplicatedStorage = game.ReplicatedStorage
local ZoneModule = require(ReplicatedStorage:WaitForChild("ZoneModule"))
local UpdateZone = ReplicatedStorage:WaitForChild("UpdateZone")
local ZoneParts = workspace.ZoneParts
function GetCurrentZone()
for _, v in pairs(ZoneParts:GetChildren()) do
local CurrentZone = ZoneModule.new(v.Name)
if CurrentZone ~= nil then
return v, CurrentZone
else
warn("No stats for this zone!")
end
end
end
UpdateZone.OnClientEvent:Connect(function()
GetCurrentZone()
-- stuff happens
end) ```
Keep in mind that OOP is known as the worst paradigm in terms of performance, but for how you've set things up, I believe you could use this!
This is not universal across all zones. I’ll be honest though. I don’t really understand metatables all that much. They’re basically magic in my eyes.
If you expect properties to change, you can add them as an argument.
When I wrote function Zone.new(name). You can continously add new things such as lighting.
Ex:
--Module
local Zone = {}
Zone.__index = Zone
function Zone.new(name, brightness)
return setmetatable({
Name = name,
Brightness = brightness,
}, Zone)
end
function Zone:GetName()
return self.Name --> Looks inside the metatable for an attribute named "Name" and returns the value
end
function Zone:GetBrightness()
return self.Brightness
end
--Script
local ZoneModule = require(ReplicatedStorage:WaitForChild("ZoneModule"))
local zone = ZoneModule.new("DEF", 100)
print(zone:GetName()) --> "DEF"
print(zone:GetBrightness()) --> "DEF", "100"
local zone2 = ZoneModule.new("CAB", 200)
print(zone:GetName()) --> "CAB"
print(zone:GetBrightness()) --> "ABC", "200"
OUTPUT:
And then when you return the metatable, you just set an attribute after the argument!
There are many tutorials on OOP, go check them out . If you’d prefer me explaining it further, I could do it in DMS as I don’t want to spam this thread with information that derails from the topic.
Note: That OOP is not always the solution and actually very rarely is the solution as there are many more performant approaches, but I believe that OOP allows me to structure and think of code easier. So use it wisely!