How to use classes with Knit?

Hello, recently I’ve been using the Knit framework and I wanted to know I can work with classes. I’m currently on mobile so I can’t provide any code, but am I essentially just making a class like normal inside a module script and then in whatever controller or service I just make the new object? Or should I write the class code in a controller/service?

Whether a controller, service or module you can still create a class. You just have to require it unlike AGF where you can just use self.Module.Something to get the class on Knit you have to add it manually.

Here’s what I did on Knit runtime:

Runtime
-- Only local script and and server script require this to start Knit
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Knit = require(script.Parent.Knit)

local function CreateMetatable(Folder: Instance): table
	local Item = setmetatable({}, {
		__index = function(self, index)
			local Object = Folder:FindFirstChild(index)
			assert(Object, ("%s is not a valid member of %s"):format(index, Folder:GetFullName()))

			if Object:IsA("ModuleScript") then
				self[index] = require(Object)

				pcall(function()
					if not (typeof(self[index].KnitStart) == "function") then
						return
					end

					table.insert(Knit.ModuleToStart, self[index])
				end)

				return self[index]
			elseif Object:IsA("Folder") or Object:IsA("Model") then
				self[index] = CreateMetatable(Object)

				return self[index]
			end

			error(("%s is not an object that can be returned"):format(index))
		end,
	})

	return Item
end

Knit.Util = CreateMetatable(Knit.Util)
Knit.Shared = CreateMetatable(ReplicatedStorage.Source)

function Knit:SetModule(Folder: Instance) -- Basically adds the Modules/Components Folder
	 self.ModuleToStart = {}
	self.Module = CreateMetatable(Folder)

	self
		.OnStart()
		:andThen(function()
			for _, module in ipairs(self.ModuleToStart) do
				module:KnitStart()
			end
		end)
		:catch(warn)
end

return Knit
On server script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Runtime = require(ReplicatedStorage.Packages.Runtime)

local Source = ServerStorage.Source

-- Set Module adds a table on Knit which is Knit.Module
Runtime:SetModule(Source.Modules) 
Runtime.AddServices(Source.Services)

Runtime.Start():catch(warn)
On client script
repeat
	task.wait()
until game:IsLoaded()

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Runtime = require(ReplicatedStorage.Packages.Runtime)

Runtime.LocalPlayer = Runtime.Util.LocalPlayer

local PlayerScripts = Runtime.LocalPlayer.PlayerScripts
local Source = PlayerScripts:WaitForChild("Source")

-- Set Module adds a table on Knit which is Knit.Module
Runtime:SetModule(Source:WaitForChild("Modules"))
Runtime.AddControllers(Source:WaitForChild("Controllers"))

Runtime.Start():catch(warn)
-- Example of what a module looks like
local Knit = require(...)
local FooService

local Foo = {}
Foo.__index = Foo

function Foo.new()
    local self = setmetatable({}, Foo)

    return self
end

-- Does not have a KnitInit only KnitStart
-- You can change this
-- You can check that on runtime on line 14
--[[
if not (typeof(self[index].KnitStart) == "function") then
	return
end
]]
function Foo:KnitStart()
    -- The purpose of this is to get a service from Knit
    -- since this is not a Service/Controller
    -- we have no way of getting the Service
    -- without waiting for the Knit.Start() to finish
    FooService = Knit:GetService("FooService")
end
-- The feature that I add on Knit runtime was just the __index which is combined with SetModule
-- with this you no longer need to require the module just simply index the module
local Knit = require(...)
local Foo = Knit.Modules.Foo

local FooService = Knit.CreateService({
    Name = "FooService"
    Client = {}
})

function FooService:KnitInt()
    -- Knit Init is not really used that much
    -- Mostly when you want to start something before 
    -- KnitStart starts, like PlayerAdded, PlayerRemoving
end

Ok so I didn’t do exactly what you said, but based on what you did say this is how I did my code. You reckon this is a decentish job? lol

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

local Knit = require(RepStorage.Packages.Knit)

local CharacterClass = require(Knit.Modules.CharacterClass)

local PlayerController = Knit.CreateController {
	Name = "PlayerController"
}

local player = Players.LocalPlayer

function PlayerController:KnitInit()
	player.CharacterAdded:Connect(function(character)
		print("Character Added")
		local character = CharacterClass.new(self:GetCharacter(),100,16,7,3)
		character:Respawn()
	end)
end

function PlayerController:GetCharacter()
	return player.Character or player.CharacterAdded:Wait()
end

return PlayerController
local RepStorage = game:GetService("ReplicatedStorage")

local Knit = require(RepStorage.Packages.Knit)
local Utils = require(Knit.Shared.Utils)

local CharacterClass = {}
CharacterClass.__index = CharacterClass

function CharacterClass.new(model,health,walkSpeed,jumpHeight,maxJumps)
	print("Creating New Character")
	local self = setmetatable({}, CharacterClass)
	return self
end

function CharacterClass:KnitStart()

end

function CharacterClass:Respawn()
	print("Respawning Character")
end

return CharacterClass
1 Like