OOP Implementation for NPC Classes

hey what’s up devs! for a little while i have been working on a stealth game and i have just began to start seriously doing the disguises and clothing classes and crap like that, but i’ve been having some issues that i really have no idea how to fix. also i should note that i’m pretty new to OOP so my code might not be too great.

anyways here’s basically what the classes of npcs and stuff look like, as well as their attributes (so far):

-- Define NPC classes and their attributes
local classAttributes = {
	Civilian = {
		suspicionIncreaseRate = 0.002,      -- Rate at which suspicion increases when detected
		suspicionDecreaseRate = 0.001,      -- Rate at which suspicion decreases when not detected
		discoveryCooldown = 1,              -- Cooldown period after being discovered before suspicion starts to decrease
		detectionRange = 30,                -- Range at which the NPC can detect players
		fieldOfViewThreshold = 0.5,         -- Threshold for considering a player within the NPC's field of view
		-- Add other class-specific attributes...
	},
	Guard = {
		Uniform = {
			suspicionIncreaseRate = 0.003,      -- Faster rate of suspicion increase when detected
			suspicionDecreaseRate = 0.002,      -- Moderate rate of suspicion decrease when not detected
			discoveryCooldown = 3,              -- Shorter cooldown period after being discovered
			detectionRange = 40,                -- Longer detection range for guards
			fieldOfViewThreshold = 0.7,         -- Wider field of view threshold for guards
			-- Add other class-specific attributes...
		},
	},
	-- Define attributes for other NPC classes...
}

function NPCModule.new(npcInstance, npcClassPath)
	local self = setmetatable({}, NPCModule)
	
	-- Get attributes for the specified NPC class
	local attributes = ["somehow get the path to the classAttributes's specific npc class that you want"]
	
	-- Initialize NPC parameters using class-specific attributes
	self.npcInstance = npcInstance
	self.humanoid = npcInstance:WaitForChild("Humanoid")
	self.head = npcInstance:WaitForChild("Head")
	self.rootPart = npcInstance:WaitForChild("HumanoidRootPart")
	self.detectionRange = attributes.detectionRange
	self.fieldOfViewThreshold = attributes.fieldOfViewThreshold
	self.suspicionAmount = 0
	self.suspicionIncreaseRate = attributes.suspicionIncreaseRate or 0.0025
	self.suspicionDecreaseRate = attributes.suspicionDecreaseRate or 0.005
	self.discoveryCooldown = attributes.discoveryCooldown
	self.lastSeenPositions = {}
	self.playerDatas = {}
	self.maxSuspicion = 1
	self.minSuspicion = 0

etc, etc, a bunch more crap that isn't necessarily relevant

and then the script for when you want to make a new aware npc or whatever you would like to call it:

-- NPCScript.lua

local NPCModule = require(game.ReplicatedStorage.ModuleScripts.NPCModule)
for _,npc in ipairs(workspace.NPCs:GetChildren()) do
	local npcInstance = npc  -- Assuming the script is directly under the NPC

	local detectionRange = 50 -- Adjust the detection range as needed
	local fieldOfViewThreshold = 0.5 -- Adjust the field of view threshold as needed
	
	local random = math.random(1,2)
	local npc
	if random == 1 then
	npc = NPCModule.new(npcInstance, {"Civilian"})
	else
		npc = NPCModule.new(npcInstance,{"Guard","Uniform"})
	end
end

now here’s the problem: how do i get the “Uniform” subcatagory from the “Guard” catagory in the classAttributes table? cause i pass in {“Guard”,“Uniform”} but then how do i like tell the script that’s what i’m looking for? does that make sense? honestly i’m very confused about how my script even works. do you have any suggetions or better ways to do this sorta thing? please let me know i’m very open to new ideas! thanks so much for reading this topic and if you have an idea or a solution to this problem i would love to know it! thank you!

function NPCModule.new(npcInstance, npcClassPath)
    local self = setmetatable({}, NPCModule)
    local attributes = classAttributes
    for _, part in ipairs(npcClassPath) do
        attributes = attributes[part]
    end
    self.npcInstance = npcInstance
    self.humanoid = npcInstance:WaitForChild("Humanoid")
    self.head = npcInstance:WaitForChild("Head")
    self.rootPart = npcInstance:WaitForChild("HumanoidRootPart")
    self.detectionRange = attributes.detectionRange
    self.fieldOfViewThreshold = attributes.fieldOfViewThreshold
    self.suspicionAmount = 0
    self.suspicionIncreaseRate = attributes.suspicionIncreaseRate or 0.0025
    self.suspicionDecreaseRate = attributes.suspicionDecreaseRate or 0.005
    self.discoveryCooldown = attributes.discoveryCooldown
    self.lastSeenPositions = {}
    self.playerDatas = {}
    self.maxSuspicion = 1
    self.minSuspicion = 0
end
1 Like

yo dude fr thank you so much! idk why the frick i couldn’t figure it out but that finally worked! thank you!!!

1 Like

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