Attempt to index nil with ____ (From a ModuleScript)

I’m making an O.O.P module for my game that essentially handles all the guns. (Since the guns act VERY similar to each-other with slight differences.) I have a “data” variable that holds data from that gun’s specific module. When I try to access a specific value from that module, it says “attempt to index nil with ___”

function GunController.new(tool: Tool)
	local weaponData = require(ReplicatedStorage.Gun.Data[tool.Name])
	local self = {
		tool = tool,
		data = weaponData,
		equipped = false,
		activated = false,
		shooting = false,
		reloading = false,
		
		ammo = tool:GetAttribute("Ammo"),
		reloadingState = tool:GetAttribute("Reloading"),
		
		lastTick = tick(),
		
		connections = {}
	}
	setmetatable(self, GunController)
	
	self:initialize()
	
	return self
end

Below is the line of code that is having problems.

function GunController:startShooting()
	if self.equipped then
		if self.ammo == 0 then
			-- reload
		end
		
		local fireMode = self.data["FIRE_MODE"] -- ERROR
		local rateOfFire = self.data["FIRERATE"]

If I try printing self.data in the constructor thread, it outputs all the values as a table like normal. If I try printing the self.data in the :startShooting() function, it prints nil?

can you show the code instantiating the object and the rest of the module script?

1 Like

Yes.

local GunController = {}
GunController.__index = GunController

function GunController.new(tool: Tool)
	local weaponData = require(ReplicatedStorage.Gun.Data[tool.Name])
	local self = {
		tool = tool,
		data = weaponData,
		equipped = false,
		activated = false,
		shooting = false,
		reloadingState = false,
		
		ammo = tool:GetAttribute("Ammo"),
		reloading = tool:GetAttribute("Reloading"),
		
		lastTick = tick(),
		
		connections = {}
	}
	setmetatable(self, GunController)
	
	self:initialize()
	
	return self
end

function GunController:initialize()
	table.insert(self.connections, self.tool.Equipped:Connect(function() GunController:equip() end))
	table.insert(self.connections, self.tool.Unequipped:Connect(function() GunController:unequip() end))
	table.insert(self.connections, self.tool.Activated:Connect(function() GunController:activate() end))
	table.insert(self.connections, self.tool.Deactivated:Connect(function() GunController:deactivate() end))
end

function GunController:equip()
	if self.equipped then
		return
	end
	self.equipped = true
end

function GunController:unequip()
	if not self.equipped then
		return
	end
	self.equipped = false
end

function GunController:activate()
	if self.activated then
		return
	end
	self.activated = true
	
	self:startShooting()
end

function GunController:deactivate()
	if not self.activated then
		return
	end
	self.activated = false
end

function GunController:startShooting()
	if self.equipped then
		if self.ammo == 0 then
			-- reload
		end
		
		local fireMode = self.data["FIRE_MODE"]
		local rateOfFire = self.data["FIRERATE"]
		
		if fireMode == "Semi" then
			self.shooting = true
			print("shot")
			
			task.delay(rateOfFire, function()
				self.shooting = false
				
				if self.ammo == 0 then
					-- reload
				end
			end)
		elseif fireMode == "Auto" then
			task.spawn(function()
				self.shooting = true
				
				while self.activated do
					if (tick() - self.lastTick) > rateOfFire then
						print("shot")
						
						self.lastTick = tick()
					else
						task.wait()
					end
				end
				self.shooting = false
				
				if self.ammo == 0 then
					-- reload
				end
			end)
		end
	end
end

return GunController

is data nil in the GunController.new() function? It may be something wrong with requiring the weaponData

1 Like

I did this

	print(weaponData)
	print(self.data)

Printed everything fine

Maybe it’s just the way I ordered my functions or something? haha

Can you show the code calling the startShooting() function? I honestly am not sure why it doesn’t work.

1 Like
function GunController:activate()
	if self.activated then
		return
	end
	self.activated = true
	
	self:startShooting()
end

I’ll do some more debugging for it, hopefully I can find out why

Also, if I try referencing self.data in any other function, it prints nil? It is not only the shooting function, strange

I’m kinda grasping at straws but, when I started learning OOP, I kept accidently calling the module script to call the function. Did you create the object then call the function on the object and not the modulescript?

1 Like
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local GunController = require(ReplicatedStorage.Gun.Classes.GunController)

local Controller = GunController.new(script.Parent) -- script.Parent is the tool

In your initialize, I think you meant to use self, not GunController when calling your methods.

1 Like

Ah, It works now, small little mistake that went unnoticed haha, thanks for all your help @KingDonutOfAllDonuts @OniiSamaUwU

This is the fixed line of code

function GunController:initialize()
	table.insert(self.connections, self.tool.Equipped:Connect(function() self:equip() end))
	table.insert(self.connections, self.tool.Unequipped:Connect(function() self:unequip() end))
	table.insert(self.connections, self.tool.Activated:Connect(function() self:activate() end))
	table.insert(self.connections, self.tool.Deactivated:Connect(function() self:deactivate() end))
end
1 Like

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