Custom Tool class using Components

Hey everyone, I have recently been using @sleitnick’s RbxUtil library to improve my code, and would like to know if I am utilizing all the packages correctly and efficiently.

Here is my TWToolComponent module:

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

local Packages = ReplicatedStorage.Packages
local Component = require(Packages.Component)
local Signal = require(Packages.Signal)
local Trove = require(Packages.Trove)
type Signal = Signal.Signal
type Trove = Trove.TroveC

local LocalPlayer = Players.LocalPlayer

local Remotes = ReplicatedStorage.Remotes.TWTool

local OnlyLocalTWTool = {}
function OnlyLocalTWTool.ShouldConstruct(component)
	return component.Instance:IsA("Model") and component.Instance:IsDescendantOf(LocalPlayer.Character)
end
function OnlyLocalTWTool.Constructing(component)
	local animations = component.Instance:FindFirstChild("Animations")
	assert(animations and animations:IsA("Folder"), "Animations folder not found!")
	for _, child in ipairs(animations:GetChildren()) do
		if not child:IsA("Animation") then
			error("Animations folder must only contain Animations!")
		end
	end
end

type self = {
	_trove: Trove,

	Equipping: Signal,
	Unequipping: Signal,
	Equipped: boolean,

	_humanoid: Humanoid,

	_animTracks: { [string]: AnimationTrack },
}

local TWToolComponent = Component.new({
	Tag = "TWTool",
	Extensions = { OnlyLocalTWTool },
})

export type TWToolComponentInstance = typeof(setmetatable({} :: self, TWToolComponent))

function TWToolComponent.Construct(self: self): ()
	self._trove = Trove.new()
end

function TWToolComponent.Start(self: self): ()
	self.Equipping = self._trove:Construct(Signal)
	self.Unequipping = self._trove:Construct(Signal)
	self.Equipped = false

	self._humanoid = self.Instance.Parent:FindFirstChildOfClass("Humanoid")

	self._animTracks = {}
	for _, animation: Animation in ipairs(self.Instance.Animations:GetChildren()) do
		self._animTracks[animation.Name] = self._trove:Add(self._humanoid.Animator:LoadAnimation(animation))
	end
end
function TWToolComponent.Stop(self: self): ()
	self._trove:Clean()
end

function TWToolComponent.Equip(self: self): ()
	if self.Equipped or self._humanoid.Health <= 0 then
		return
	end
	self.Equipping:Fire()
	self.Equipped = true

	Remotes.Equipping:FireServer(self.Instance)

	self.Instance.Parent.Torso.Grip.Part1 = self.Instance.PrimaryPart

	self._animTracks.Idle:Play(0)
	self._animTracks.Equip:Play(0)
end
function TWToolComponent.Unequip(self: self): ()
	if not self.Equipped then
		return
	end
	self.Unequipping:Fire()
	self.Equipped = false

	Remotes.Unequipping:FireServer(self.Instance)

	for _, animTrack in pairs(self._animTracks) do
		animTrack:Stop(0)
	end
end

return TWToolComponent

I also uploaded it to GitHub if you would prefer to view it there: TWToolComponent

Unfortunately, I am not one for comments so I will briefly describe the point of the module to you here. I am creating a custom tool and inventory system utilizing RbxUtil’s Component module (also Signal and Trove). The goal is use the idea of Components to attach multiple behaviors to a single Instance, in this case a Model instead of a Tool as I want to essentially create a custom class TWTool (TWToolComponentInstance)

I am still working on the inventory and tool system, so I want to know if this is the right way to go about using RbxUtil