Weird bug with OOP modules

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    – Fix OOP module.

  1. What is the issue? Include screenshots / videos if possible!
    – OOP is created without attributes like: InputConnections, VECTOR_Shake and others.

My module:

-------------------------
-- SERVICES --
-------------------------

local ReplicatedStorage = game:FindService('ReplicatedStorage')
local UserInputService = game:FindService('UserInputService')
local TweenService = game:FindService('TweenService')
local RunService = game:FindService('RunService')
local Players = game:FindService('Players')

-------------------------
-- TYPES --
-------------------------

type State = 'Idle' | 'IdleCrouch' | 'Walk' | 'Sprint' | 'Crouch' | 'Fall'

-------------------------
-- VARIABLES --
-------------------------

local LocalPlayer = Players.LocalPlayer
local CurrentCamera = workspace.CurrentCamera

local Modules = ReplicatedStorage:WaitForChild('Modules')
local Utilities = Modules:WaitForChild('Utilities')

local CAMERA_HANDLER = {}
CAMERA_HANDLER.__index = CAMERA_HANDLER

-------------------------
-- DEPENDENCIES --
-------------------------

local SPRING = require(Utilities:WaitForChild('Spring'))

-------------------------
-- PRIVATE FUNCTIONS --
-------------------------

-------------------------
-- PUBLIC FUNCTIONS --
-------------------------

function CAMERA_HANDLER.new()
	local self = setmetatable({}, CAMERA_HANDLER)
	
	self.VECTOR_Shake = Instance.new('Vector3Value')
	
	self.CameraTilt = Instance.new('NumberValue')
	self.CameraTilt.Name = 'CameraTilt'

	self.FallTilt = Instance.new('NumberValue')
	self.FallTilt.Name = 'FallTilt'

	self.CrouchTilt = Instance.new('NumberValue')
	self.CrouchTilt.Name = 'CrouchTilt'
	
	self.FALL_Updated = 0
	self.PREVIOUS_DeltaTime = 0.333
	self.MISSING_Updated = os.clock()
	
	self.MainSpring = SPRING.new(Vector3.zero)
	self.MainSpring:__newindex('Damper', 0.5)
	self.MainSpring:__newindex('Speed', 8)

	self.BobbingSpring = SPRING.new(Vector3.zero)
	self.BobbingSpring:__newindex('Damper', 0.9)
	self.BobbingSpring:__newindex('Speed', 10)
	
	self.AX, self.AY, self.AZ = 0, 0, 0
	self.AX_T, self.AY_T, self.AZ_T = 0, 0, 0

	self.CameraLocked, self.CameraLockedOffset = false, {0, 0}
	self.CameraSmoothness, self.CameraSensitivity = 40, 0.3
	self.MouseLocked = false
	
	self.InputConnections = {}
	
	return self
end

function CAMERA_HANDLER:Enable()
	self.InputConnections[#self.InputConnections + 1] = UserInputService.InputBegan:Connect(function(InputObject : InputObject, ProcessedEvent : boolean) : () -- Here error: self.InputConnections is nil.
		if ProcessedEvent then return end

		if InputObject.UserInputType == Enum.UserInputType.Keyboard and InputObject.KeyCode == Enum.KeyCode.L then
			self.MouseLocked = not self.MouseLocked
		end
	end)

	-- || Other code.
end

function CAMERA_HANDLER:Disable()
    for Index, Connection : RBXScriptConnection in self.InputConnections do
        Connection:Disconnect()
        self.InputConnections[Index] = nil
    end

    self.InputConnections = {}
end

-------------------------
-- END OF CODE --
-------------------------

return CAMERA_HANDLER
1 Like

That’s keeping it a little too simple. You’ll have to elaborate more on what exactly the problem is, What exactly are you trying to achieve (i.e what is the code supposed to do)? What is happening instead? etc

So, i have local script that called “Start”. It gets all handlers (Camera, Player and etc.) and stores it like: MODULES[Handler.Name] = LoadedHandler.new() after this loop i have another loop that will get all loaded handlers .new() and if handler have :Enable method it calls it.

For example: Camera:Enable() was called, and it stops with error at line “self.InputConnections[self.InputConnections + 1] = …” 'cause self.InputConnections is nil.
When i printing self table it returns all methods without attributes that i assign in .new method.

Sorry if you something doesn’t understand, don’t know english well.

Show me this part in your code

and the area around it

“Start” part of code that loads all handlers:

_G.ClientLoaded = false
local REQUIRED, LOADED = 0, 0

repeat
	task.wait(0.1)
until game:GetService('ContentProvider').RequestQueueSize == 0

for _, Handler in Handlers:GetDescendants() do
	if not LOADED_HANDLERS[Handler.Name] and Handler:IsA('ModuleScript') then
		print(`[Client]: Loading handler {Handler.Name}`)
		
		REQUIRED += 1

		local Success, ErrorCode = pcall(function()
			task.spawn(function()
				local Loaded_Handler = require(Handler)
				
				LOADED_HANDLERS[Handler.Name] = Loaded_Handler.new()
				SHARED_HANDLERS:AddHandler(Handler.Name, Loaded_Handler)
				
				LOADED += 1
			end)
		end)

		if Success then
			print(`[Client]: Successfully loaded handler {Handler.Name}`)
		else
			print(`[Client]: Failed to load handler {Handler.Name}. Error description: {ErrorCode}`)
		end
	end
end

repeat
	task.wait()
until REQUIRED == LOADED
_G.ClientLoaded = true

for _, Handler in SHARED_HANDLERS:GetHandlers() do
	if Handler.Enable then Handler:Enable() end
end

SharedHandlers module:

local SHARED_HANDLERS = {}
local MODULE = {}

function MODULE:AddHandler(Name, Handler)
	SHARED_HANDLERS[Name] = Handler
end

function MODULE:GetHandlers()
	return SHARED_HANDLERS
end

return MODULE
1 Like

I believe the error originates from those lines.
You add Loaded_Handler.new() to LOADED_HANDLERS[Handler.Name]
However, right after you do SHARED_HANDLERS:AddHandler(Handler.Name, Loaded_Handler), where you add the CAMERA_HANDLER module itself to SHARED_HANDLERS, instead of the new object you created with Loaded_Handler.new().
So essentially, all you have to do is switch the line

SHARED_HANDLERS:AddHandler(Handler.Name, Loaded_Handler)

With this

SHARED_HANDLERS:AddHandler(Handler.Name, LOADED_HANDLERS[Handler.Name])

And that should fix the error with your CAMERA_HANDLER and any other HANDLERs.

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