Opinions on how to better structure my combat framework?

Hello! I just got stuck on this topic and I have no idea on how to proceed or what to do better now.
I have 1 module which handles the players stun and other states. And i require this module in every server script associated with combat. In that module there are already a couple functions checking if the player can proceed and in every script If it returns false i simply return. But the problem is if i were to add another state in the future I would have to go back to every single server script and add that check. I though of adding it into all 1 big function but im not sure at this point. Any suggestion?

2 Likes

Could you show the ModuleScript? (Or, at least the parts of the module that are necessary to understand this fully.)

2 Likes

here:

–script that creates the controller:

function CombatIS.CreateProfile(Player:Player)
	local self = setmetatable({}, CombatIS)

	self.Player = Player
	self.Character = Player.Character or Player.CharacterAdded:Wait()
	self.Root = self.Character.PrimaryPart
	self.Hum = self.Character:FindFirstChildOfClass("Humanoid")

	self.RagdollParts = {}

	self.LastState = "None"
	self.LastStateTick = os.time()

	self.CombatStates = "Idle"
	self.ActionState = "Landed"
	self.AerialState = "Landed"

	self.Stun = false
	self.Invincible = false

	self.Character:SetAttribute("ActionState", self.ActionState)
	self.Character:SetAttribute("AerialState", self.AerialState)

	self.Character:SetAttribute("Stun", false)
	self.Character:SetAttribute("Invincible", false)

	CombatIS.Controllers[Player.Name] = self

	return self
end

scripts that handle states:

function CombatIS:CheckStun()
	if self.Stun == true then
		return true
	else
		return false
	end
end

function CombatIS:CheckIframe()
	if self.Invincible == true then
		return true
	else
		return false
	end
end

There are more unrelated things but here are the ones i mentioned

1 Like

Is it possible you could convert it all into one single function? Such as:

function CombatIS:CheckState(StateName)
	return self[StateName] == true
end
1 Like

I could but that wont really solve my problem, If i add a new state i would still have to go to every script i required it in

1 Like

May I see an example of a script that calls the module and uses one of the specific states?

1 Like

Just calls the functions then returns if it returns false.

local Profile = CIS:GetProfile

local Stun = Profile:CheckStun()
local Iframe = Profile:CheckStun()

if Stun then return end

--continues with move down here
1 Like

If it only checks that the stun is true, then you could:

local stun = Profile:CheckState("Stun")

if stun then return end

However, if the code only runs if any of the states are false, you could do this:

self.States = {
	Stun = false,
	Iframe = false,
}
function CombatIS:CheckState(StateName)
	return self.States[StateName] == true
end

and, in the script:

local States = {}
for StateName,_ in pairs(Profile.States)
	table.Insert(States, Profile:CheckState(StateName))
end

if table.find(States, true) then return end
2 Likes

Scripts check different states at different times how is this better than before? Why would i need to implement a loop into it, i just want to know how is this better in anyway?

2 Likes

My apologies, I didn’t know that. I incorrectly assumed that because the variables were created at the same times, they would both use return at the same time.

This part of the script
image
could be used to make it so you would not have to create new functions each time you would want to add new states.
Although, it would be understandable if you didn’t implement this due to the hassle of going through the other scripts that require the module and editing them individually to be compatible with the changes.

1 Like

Thanks for the advice but i dont think i explained it too well. For example i have a new state called “flying” and if the player is hit while in this state it would play an animation and no damage would be deslt. So in the cis service i would add a extra state and the function where the animation would play. Now how would i go to every script associated with combat that deals damage and implement it, i would have have to run the function for the players profile that got hit and if it returns that the player has the flying state it would run the function. This would have to be for every single script.

2 Likes

Ah, I think I understand better now. Just a random question: How much scripts damage? Do they damage individually? Or is there a general damaging function that is created in the module and used in other scripts?

Individually, also the function :ApplyStun is introduced here