[2.0] WCS - A combat system framework

Does this framework support using non player characters? For the most part it has been working fine for me in my tests except for when it comes to using :SetHumanoidData(). It gives me the error

  ReplicatedStorage.Modules.wcs.source.character:756: attempt to index number with number - character:756
  Stack Begin
  Script 'ReplicatedStorage.Modules.wcs.source.character', Line 756 - character:756
  Script 'ReplicatedStorage.Modules.wcs.source.character', Line 765 - function _internal_calculateAppliedProps - character:765
  Script 'ReplicatedStorage.Modules.wcs.source.character', Line 721 - function _internal_updateHumanoidProps - character:721
  Script 'ReplicatedStorage.Modules.wcs.source.character', Line 235 - character:235
  Script 'ReplicatedStorage.Modules.wcs.include.node_modules.@rbxts.sleitnick-signal', Line 47 - function acquireRunnerThreadAndCallEventHandler - sleitnick-signal:47
  Script 'ReplicatedStorage.Modules.wcs.include.node_modules.@rbxts.sleitnick-signal', Line 58 - function runEventHandlerInFreeThread - sleitnick-signal:58
  Stack End

This is my code for my status effect. If I comment out the :SetHumanoidData() it runs without errors. The status effect works perfectly fine for players I will add.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local WCS = require(ReplicatedStorage.Modules.wcs)

local StatusEffect = WCS.RegisterStatusEffect("Stun")

function StatusEffect:OnStartServer()
	self:SetHumanoidData(
		-- Disable walkspeed
		{WalkSpeed = {-100, "Set"}, 5}
	)
end

function StatusEffect:OnStartClient()
	if self.Character.Humanoid then
		-- Disable jumping
		self.Character.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
	end
end

function StatusEffect:OnEndClient()
	if self.Character.Humanoid then
		-- Enable jumping
		self.Character.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, true)
	end
end

return StatusEffect

Thank you for any feedback.

Edit: Also including the code I use to create the npc characters below.

local function registerNPC(npcCharacter: Model)
	print("Creating NPC character")
	
	local humanoid = npcCharacter:WaitForChild("Humanoid")

	-- Create character
	local WCS_Character = Character.new(npcCharacter)
	
	print(WCS_Character)
	
	WCS_Character.DamageTaken:Connect(function(container)
		if humanoid then
			humanoid:TakeDamage(container.Damage)
		end
	end)
	
	-- destroy it when humanoid dies
	humanoid.Died:Once(function()
		WCS_Character:Destroy()
	end)
end

-- Create characters for npcs under NPCs folder in workspace
for _, npcCharacter in game.Workspace.Alive.NPCs:GetChildren() do
	task.delay(3, registerNPC, npcCharacter)
end
game.Workspace.Alive.NPCs.ChildAdded:Connect(registerNPC)

image
priority value should come as a second argument to SetHumanoidData, not a table member !!

Wow, thank you for the quick response! That fixed it straight away! I found that part of the documentation a little difficult to understand.

I will say, itā€™s interesting that it worked on players without issue until now.

Is it possible for there to be a function to extend the time of a status effect in a future update or is that not possible?
Unless Iā€™m mistaken the only way I can extend a status effect if a character already has it is to apply a new one which causes weird behaviors with it constantly stopping and starting repeatedly.

you probably want to add another status of the same kind instead.

Thatā€™s what I am doing and it creates some unintended, buggy behavior for what I am attempting to achieve.
While I am just applying another status effect of the same kind to try and extend it, they all individually start and end. It does not extend the already existing one.
It would be nice to be able to extend the duration or set the currently active status effectā€™s duration to a new value so instead of spammy starts and ends to the status.

Here is a video of a status I made that makes characters models go invisible and place a stone copy in the place to visualize what I am saying about spammy.

You will notice that for the first second they stay as a statue. Then that first second runs out and it starts blinking at the rate it is being applied as the first one ends, then the second one ends, then the third one, etc
output

you could just run the if checks, e.g: if one status ended, but thereā€™s more of the same kind on the statue, donā€™t make it blink

Iā€™ll try that to fix it

If it does work out, I still think if you do make update in the future that would be a nice function to add

Edit: I tried to have it not reverse the stone effect until all of them ended but Iā€™m stuck.
I thought of placing this within the :OnEndServer() of the status effect

repeat
		task.wait(.05)
	until #self.Character:GetAllStatusEffectsOfType(StatusEffect) <= 1

That produced the result of the effects never ending. How would you suggest implementing this without causing an endless wait for all the status effects to end?

I did end up making a solution, though in a very much so less than ideal way.
I added a new function to the statusEffect module script

function StatusEffect:ExtendLength(Time)
	if self._internal_isReplicated then
		return logWarning("Cannot perform this action on a replicated status")
	end
	self._internal_timer:extendLength(Time)
end

And also had to add a new function to the Timer module script

function Timer:extendLength(lengthInSeconds)
	assertValidLength(lengthInSeconds)
	self.timeLeftInSeconds = self.timeLeftInSeconds + lengthInSeconds
end

I imagine there must have been an easier way but it works.
I just have to call :ExtendLength() on my status effect and it will extend it by however many seconds I put in

in OnStartServer, line 1:

if self.Character:GetAllStatusEffectsOfType(StatusEffect) > 1 then
    return
end

in OnEndServer, line 1:

if self.Character:GetAllStatusEffectsOfType(StatusEffect) > 0 then
    return
end

Is there a recommended way to extend the Character class in luau to add additional fields/methods? For example, adding stats fields to the Character and methods for them. Alternatively, is there a way to just attach additional replicated data to the Character like with :SetMetatable()

I usually wrap wcs character class using a component & pass it in to all skills using inheritance (extending from a base class, that has these fields defined) !!

Not sure if intended, but when workspace ModelStreamingBehavior property is set to improved, this warn occurs
image

None of the skills seem to work as well when fired from client

Suspected problem
image

Module is placed in ReplicatedStorage, client starts in StarterPlayerScripts, and server starts in ServerScriptService. Is there a way to solve this problem? Or is it not compatible with Improved streaming at all?