### Basic Knit Setup Source: https://sleitnick.github.io/Knit/docs/executionmodel This is the standard setup for a Knit script on both the server and client. It requires the Knit module and starts the Knit application, catching any potential errors during startup. ```lua local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit) -- Load services or controllers here Knit.Start():catch(warn) ``` -------------------------------- ### Start Knit Server with Options Source: https://sleitnick.github.io/Knit/api Initiate the Knit server with custom configurations by passing a KnitOptions object to Knit.Start(). This example demonstrates setting up inbound middleware for processing player arguments. ```lua Knit.Start({ Middleware = { Inbound = { function(player, args) print("Player is giving following args to server:", args) return true end }, }, }):andThen(function() print("Knit started!") end):catch(warn) ``` -------------------------------- ### Create and Use a Simple Service Source: https://sleitnick.github.io/Knit/docs/gettingstarted Demonstrates creating a 'MoneyService' with methods to get and give money. It also shows how to expose a server-side method to the client by defining it within the 'Client' table of the service. This example assumes 'someDataStore' is defined elsewhere. ```lua local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit) -- Create the service: local MoneyService = Knit.CreateService { Name = "MoneyService", } -- Add some methods to the service: function MoneyService:GetMoney(player) -- Do some sort of data fetch local money = someDataStore:GetAsync("money") return money end function MoneyService:GiveMoney(player, amount) -- Do some sort of data fetch local money = self:GetMoney(player) money += amount someDataStore:SetAsync("money", money) end Knit.Start():catch(warn) ``` ```lua -- Money service on the server ... function MoneyService.Client:GetMoney(player) -- We already wrote this method, so we can just call the other one. -- 'self.Server' will reference back to the root MoneyService. return self.Server:GetMoney(player) end ... ``` -------------------------------- ### Complete Client Startup Script with RbxUtil Source: https://sleitnick.github.io/Knit/docs/intellisense A client-side startup script mirroring the server-side example, using RbxUtil's Loader to load controllers from ReplicatedStorage and start them. ```lua -- StarterPlayer.StarterPlayerScripts.ClientStartup local controllers = Loader.LoadDescendants(ReplicatedStorage, Loader.MatchesName("Controller$")) Loader.SpawnAll(controllers, "OnStart") ``` -------------------------------- ### Start Knit with Custom Options Source: https://sleitnick.github.io/Knit/api/KnitClient Initiates the Knit framework with custom options. This example demonstrates disabling the default promise behavior for service methods by setting `ServicePromises` to `false`. It returns a promise that resolves when Knit has successfully started. ```lua Knit.Start({ServicePromises = false}):andThen(function() print("Knit started!") end):catch(warn) ``` -------------------------------- ### Create a Knit Controller Source: https://sleitnick.github.io/Knit/api/KnitClient Controllers must be created before calling `Knit.Start()`. This example shows how to define a controller with initialization and start methods. ```lua -- Create a controller local MyController = Knit.CreateController { Name = "MyController", } function MyController:KnitStart() print("MyController started") end function MyController:KnitInit() print("MyController initialized") end ``` -------------------------------- ### Start Source: https://sleitnick.github.io/Knit/api Starts the Knit framework. This should only be called once. Optionally, `KnitOptions` can be passed to configure Knit's custom settings. Ensure all services are created before calling `Start`, as services cannot be added later. ```APIDOC ## Start ### Description Starts Knit. Should only be called once. Optionally, `KnitOptions` can be passed in order to set Knit's custom configurations. Be sure that all services have been created _before_ calling `Start`. Services cannot be added later. ### Parameters #### Path Parameters - **options** (KnitOptions?) - Optional - Custom configurations for Knit. ### Returns - **Promise**: A promise that resolves when Knit has started. ### Example ```lua Knit.Start():andThen(function() print("Knit started!") end):catch(warn) ``` Example of Knit started with options: ```lua Knit.Start({ Middleware = { Inbound = { function(player, args) print("Player is giving following args to server:", args) return true end }, }, }):andThen(function() print("Knit started!") end):catch(warn) ``` ``` -------------------------------- ### Start Source: https://sleitnick.github.io/Knit/api Starts Knit. Should only be called once. Optionally, `KnitOptions` can be passed in order to set Knit's custom configurations. ```APIDOC ## `Start` ### Description Starts Knit. Should only be called once. Optionally, `KnitOptions` can be passed in order to set Knit's custom configurations. ### Signature `KnitServer.Start(options: KnitOptions?) → Promise` ### Caution Be sure that all services have been created _before_ calling `Start`. Services cannot be added later. ### Example ```lua Knit.Start():andThen(function() print("Knit started!") end):catch(warn) ``` ### Example with Options ```lua Knit.Start({ Middleware = { Inbound = { function(player, args) print("Player is giving following args to server:", args) return true end }, } }):andThen(function() print("Knit started!") end):catch(warn) ``` ``` -------------------------------- ### Start Knit Server Source: https://sleitnick.github.io/Knit/api Call Knit.Start() once to initialize the Knit server. It returns a Promise that resolves when Knit has started. Errors during startup are caught and warned. ```lua Knit.Start():andThen(function() print("Knit started!") end):catch(warn) ``` -------------------------------- ### Wait for Knit to Start and Get Controller Source: https://sleitnick.github.io/Knit/api/KnitClient Provides a promise that resolves once Knit has started, useful for code that depends on Knit controllers but is not the script that initiated `Start`. This example shows how to wait for Knit to start, retrieve a specific controller, and then call a method on it. ```lua Knit.OnStart():andThen(function() local MyController = Knit.GetController("MyController") MyController:DoSomething() end):catch(warn) ``` -------------------------------- ### Get All Services Source: https://sleitnick.github.io/Knit/api Gets a table of all services. ```lua local allServices = Knit.GetServices() ``` -------------------------------- ### Execute Code After Knit Starts Source: https://sleitnick.github.io/Knit/api Use `Knit.OnStart()` to get a Promise that resolves when Knit has started. This is useful for code that depends on Knit services but is not the script that called `Start`. ```lua Knit.OnStart():andThen(function() local MyService = Knit.Services.MyService MyService:DoSomething() end):catch(warn) ``` -------------------------------- ### Start All Services with a Loop Source: https://sleitnick.github.io/Knit/docs/examples Load all service modules from a specified folder using a loop. Ensure all service modules are placed in the 'Services' folder. ```lua local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit) -- Load all services: for _, v in script.Parent.Services:GetDescendants() do if v:IsA("ModuleScript") then require(v) end end Knit.Start():catch(warn) ``` -------------------------------- ### Initialize Knit Server Source: https://sleitnick.github.io/Knit/api Load service modules and start the Knit server. Use this to initialize the server-side framework. ```lua local Knit = require(somewhere.Knit) -- Load service modules within some folder: Knit.AddServices(somewhere.Services) -- Start Knit: Knit.Start():andThen(function() print("Knit started") end):catch(warn) ``` -------------------------------- ### Start Source: https://sleitnick.github.io/Knit/api/KnitServer Starts the Knit service. This should only be called once. Optionally, KnitOptions can be passed to configure Knit's custom settings. Ensure all services are created before calling Start. ```APIDOC ## Start ### Description Starts Knit. Should only be called once. Optionally, `KnitOptions` can be passed in order to set Knit's custom configurations. Be sure that all services have been created _before_ calling `Start`. Services cannot be added later. ### Signature `KnitServer.Start(options: KnitOptions?) -> Promise` ### Example ```lua Knit.Start():andThen(function() print("Knit started!") end):catch(warn) ``` ### Example with Options ```lua Knit.Start({ Middleware = { Inbound = { function(player, args) print("Player is giving following args to server:", args) return true end }, } }):andThen(function() print("Knit started!") end):catch(warn) ``` ``` -------------------------------- ### Start Knit with default options Source: https://sleitnick.github.io/Knit/api/KnitClient Call Knit.Start() to initialize Knit with default settings. Use .andThen() to execute code upon successful startup and .catch() to handle errors. ```lua Knit.Start():andThen(function() print("Knit started!") end):catch(warn) ``` -------------------------------- ### Start Knit with Default Options Source: https://sleitnick.github.io/Knit/api/KnitClient Initiates the Knit framework. This function should be called once per client. It returns a promise that resolves when Knit has successfully started. By default, service methods exposed to the client return promises. ```lua Knit.Start():andThen(function() print("Knit started!") end):catch(warn) ``` -------------------------------- ### OnStart Source: https://sleitnick.github.io/Knit/api/KnitClient Returns a promise that is resolved once Knit has started. This is useful for any code that needs to tie into Knit controllers but is not the script that called `Start`. ```APIDOC ## OnStart ### Description Returns a promise that is resolved once Knit has started. This is useful for any code that needs to tie into Knit controllers but is not the script that called `Start`. ```lua Knit.OnStart():andThen(function() local MyController = Knit.GetController("MyController") MyController:DoSomething() end):catch(warn) ``` ### Method static ### Returns - **Promise** - Description ``` -------------------------------- ### OnStart Source: https://sleitnick.github.io/Knit/api/KnitClient Returns a promise that is resolved once Knit has started. This is useful for any code that needs to tie into Knit controllers but is not the script that called `Start`. ```APIDOC ## OnStart ### Description Returns a promise that is resolved once Knit has started. This is useful for any code that needs to tie into Knit controllers but is not the script that called `Start`. ### Method `KnitClient.OnStart()` ### Returns - `Promise` - A promise that resolves when Knit has started. ### Example ```lua Knit.OnStart():andThen(function() local MyController = Knit.GetController("MyController") MyController:DoSomething() end):catch(warn) ``` ``` -------------------------------- ### Manually Start Services with OnStart Method Source: https://sleitnick.github.io/Knit/docs/intellisense Iterate through loaded services and manually call their 'OnStart' method if it exists. Use task.spawn to run OnStart asynchronously. ```lua for _, service in services do if typeof(service.OnStart) == "function" then task.spawn(function() service:OnStart() end) end end ``` -------------------------------- ### OnStart Source: https://sleitnick.github.io/Knit/api Returns a promise that is resolved once Knit has started. This is useful for any code that needs to tie into Knit services but is not the script that called `Start`. ```APIDOC ## `OnStart` ### Description Returns a promise that is resolved once Knit has started. This is useful for any code that needs to tie into Knit services but is not the script that called `Start`. ### Method `KnitServer.OnStart()` ### Returns - `Promise` - A promise that resolves when Knit has started. ``` -------------------------------- ### Start Source: https://sleitnick.github.io/Knit/api/KnitServer Starts the Knit framework. This function should only be called once. Optionally, KnitOptions can be provided to configure Knit's behavior, such as setting up middleware for inbound requests. It returns a Promise that resolves when Knit has successfully started. ```APIDOC ## Start ### Description Starts Knit. Should only be called once. Optionally, `KnitOptions` can be passed in order to set Knit's custom configurations. :::caution Be sure that all services have been created _before_ calling `Start`. Services cannot be added later. ::: ### Parameters #### Path Parameters - **options** (KnitOptions?) - Optional - Custom configurations for Knit. ### Method `static` ### Returns - `Promise` - A promise that resolves when Knit has started. ### Request Example ```lua Knit.Start():andThen(function() print("Knit started!") end):catch(warn) ``` Example of Knit started with options: ```lua Knit.Start({ Middleware = { Inbound = { function(player, args) print("Player is giving following args to server:", args) return true end }, }, }):andThen(function() print("Knit started!") end):catch(warn) ``` ``` -------------------------------- ### Wait for Knit to Start Source: https://sleitnick.github.io/Knit/api/KnitClient Use `OnStart` to execute code after Knit has started. This is useful for initializing controllers or other systems that depend on Knit. ```lua Knit.OnStart():andThen(function() local MyController = Knit.GetController("MyController") MyController:DoSomething() end):catch(warn) ``` -------------------------------- ### Client-Side Consumer of PointsService Source: https://sleitnick.github.io/Knit/docs/services An example of a client-side LocalScript that consumes the PointsService. It initializes Knit, gets the service, listens for point changes, and fires a signal to request points. ```lua -- From a LocalScript local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit) Knit.Start():catch(warn):await() local PointsService = Knit.GetService("PointsService") local function PointsChanged(points) print("My points:", points) end -- Get points and listen for changes: PointsService:GetPoints():andThen(PointsChanged) PointsService.PointsChanged:Connect(PointsChanged) -- Ask server to give points randomly: PointsService.GiveMePoints:Fire() ``` -------------------------------- ### Lua Class Example Source: https://sleitnick.github.io/Knit/docs/vscodesnippets An example of a generated Lua class named MyClass, demonstrating its structure and methods. ```Lua local MyClass = {} MyClass.__index = MyClass function MyClass.new() local self = setmetatable({}, MyClass) return self end function MyClass:Destroy() end return MyClass ``` -------------------------------- ### Start Knit with Custom Options Source: https://sleitnick.github.io/Knit/api Initiate the Knit framework with custom `KnitOptions`, such as defining inbound middleware. This function should only be called once. ```lua Knit.Start({ Middleware = { Inbound = { function(player, args) print("Player is giving following args to server:", args) return true end }, }, }):andThen(function() print("Knit started!") end):catch(warn) ``` -------------------------------- ### Start Services with RbxUtil Loader.SpawnAll Source: https://sleitnick.github.io/Knit/docs/intellisense Utilize Loader.SpawnAll to automatically call a specified method (e.g., 'OnStart') on all loaded services. This function also sets memory categories for profiling. ```lua Loader.SpawnAll(services, "OnStart") ``` -------------------------------- ### KnitClient.Start Source: https://sleitnick.github.io/Knit/api/KnitClient Starts Knit. This method should only be called once per client. It returns a Promise that resolves when Knit has started. ```APIDOC ## KnitClient.Start ### Description Starts Knit. Should only be called once per client. ### Method `KnitClient.Start(options: KnitOptions?): Promise` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```lua Knit.Start():andThen(function() print("Knit started!") end):catch(warn) ``` ### Response #### Success Response (Promise) Resolves when Knit has started. #### Response Example None explicitly defined, but the promise can be chained with `.andThen()` and `.catch()`. ``` ```APIDOC ## KnitClient.Start with Options ### Description Starts Knit with custom options. This example shows how to disable service method promises. ### Method `KnitClient.Start(options: KnitOptions?): Promise` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```lua Knit.Start({ServicePromises = false}):andThen(function() print("Knit started!") end):catch(warn) ``` ### Response #### Success Response (Promise) Resolves when Knit has started. #### Response Example None explicitly defined, but the promise can be chained with `.andThen()` and `.catch()`. ``` -------------------------------- ### Get a Service by Name Source: https://sleitnick.github.io/Knit/api Gets the service by name. Throws an error if the service is not found. ```lua local MyService = Knit.GetService("MyService") ``` -------------------------------- ### Basic Knit Initialization Source: https://sleitnick.github.io/Knit/docs/gettingstarted This is the most basic usage of Knit, requiring the module and starting the framework. It's intended for both server and client scripts. Errors during startup are caught and logged using the 'warn' function. Chaining ':await()' can be used to yield until startup is complete. ```lua local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit) Knit.Start():catch(warn) -- Knit.Start() returns a Promise, so we are catching any errors and feeding it to the built-in 'warn' function -- You could also chain 'await()' to the end to yield until the whole sequence is completed: -- Knit.Start():catch(warn):await() ``` -------------------------------- ### Client-Side Service Consumption (Promises) Source: https://sleitnick.github.io/Knit/docs/gettingstarted This client-side code fetches the player's money using the 'MoneyService'. It utilizes promises with ':andThen()' to handle the asynchronous response. Ensure Knit is started before attempting to get the service. ```lua -- Client-side code local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit) Knit.Start():catch(warn):await() local MoneyService = Knit.GetService("MoneyService") MoneyService:GetMoney():andThen(function(money) print(money) end) ``` -------------------------------- ### Start Source: https://sleitnick.github.io/Knit/api/KnitClient Starts Knit. Should only be called once per client. By default, service methods exposed to the client will return promises. To change this behavior, set the `ServicePromises` option to `false`. ```APIDOC ## Start options ### Description Starts Knit. Should only be called once per client. By default, service methods exposed to the client will return promises. To change this behavior, set the `ServicePromises` option to `false`: ```lua Knit.Start({ServicePromises = false}):andThen(function() print("Knit started!") end):catch(warn) ``` ### Method static ### Parameters #### Path Parameters - **options** (KnitOptions?) - Required - Description ### Returns - **Promise** - Description ``` -------------------------------- ### Start All Services with Knit.AddServices Source: https://sleitnick.github.io/Knit/docs/examples Use Knit.AddServices or Knit.AddServicesDeep to automatically load all ModuleScripts from a given instance. This simplifies service loading compared to manual looping. ```lua local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit) -- Load all services within 'Services': Knit.AddServices(script.Parent.Services) -- Load all services (the Deep version scans all descendants of the passed instance): Knit.AddServicesDeep(script.Parent.OtherServices) Knit.Start():catch(warn) ``` -------------------------------- ### Client-Side Service Consumption (No Promises) Source: https://sleitnick.github.io/Knit/docs/gettingstarted This client-side code fetches the player's money using the 'MoneyService' without using promises. The `ServicePromises` option is set to `false` during Knit startup, allowing direct retrieval of service method results. Ensure Knit is started before attempting to get the service. ```lua Knit.Start({ServicePromises = false}):catch(warn):await() local MoneyService = Knit.GetService("MoneyService") local money = MoneyService:GetMoney() ``` -------------------------------- ### Handle Knit Startup Promise Source: https://sleitnick.github.io/Knit/api Resolves a promise once Knit has started. Useful for code that needs to tie into Knit services after initialization but is not the script that called Start. ```lua Knit.OnStart():andThen(function() local MyService = Knit.Services.MyService MyService:DoSomething() end):catch(warn) ``` -------------------------------- ### KnitServer.GetServices Source: https://sleitnick.github.io/Knit/api Gets a table of all services. ```APIDOC ## KnitServer.GetServices ### Description Gets a table of all services. ### Method `KnitServer.GetServices() -> {[string]: Service}` ### Parameters None ### Request Example ```lua local allServices = Knit.GetServices() ``` ### Response #### Success Response ({[string]: Service}) - **{[string]: Service}** (table) - A table where keys are service names and values are Service objects. #### Response Example ```lua -- Returns a table like: {["MyService"] = ServiceObject, ...} ``` ``` -------------------------------- ### GetServices Source: https://sleitnick.github.io/Knit/api Gets a table of all services. ```APIDOC ## `GetServices` ### Description Gets a table of all services. ### Method `Knit.GetServices()` ### Returns - **{ [string]: Service }** - A table containing all registered services, keyed by their names. ``` -------------------------------- ### Full PointsService Implementation Source: https://sleitnick.github.io/Knit/docs/services A comprehensive example of a Knit service including RemoteProperties, Signals, and server-side logic for managing player points. It initializes signals and handles player connections. ```lua local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit) local Signal = require(Knit.Util.Signal) local PointsService = Knit.CreateService { Name = "PointsService", -- Define some properties: PointsPerPlayer = {}, PointsChanged = Signal.new(), Client = { -- Expose signals to the client: PointsChanged = Knit.CreateSignal(), GiveMePoints = Knit.CreateSignal(), Points = Knit.CreateProperty(0), }, } -- Client exposed GetPoints method: function PointsService.Client:GetPoints(player) return self:GetPoints(player) end -- Add Points: function PointsService:AddPoints(player, amount) local points = self:GetPoints(player) points += amount self.PointsPerPlayer[player] = points if amount ~= 0 then self.PointsChanged:Fire(player, points) self.Client.PointsChanged:Fire(player, points) end self.Client.Points:SetFor(player, points) end -- Get Points: function PointsService:GetPoints(player) local points = self.PointsPerPlayer[player] return points or 0 end -- Initialize function PointsService:KnitInit() local rng = Random.new() -- Give player random amount of points: self.Client.GiveMePoints:Connect(function(player) local points = rng:NextInteger(0, 10) self:AddPoints(player, points) print("Gave " .. player.Name .. " " .. points .. " points") end) -- Clean up data when player leaves: game:GetService("Players").PlayerRemoving:Connect(function(player) self.PointsPerPlayer[player] = nil end) end return PointsService ``` -------------------------------- ### Create Knit Controller Source: https://sleitnick.github.io/Knit/docs/vscodesnippets Template for creating a Knit controller, including initialization and start functions. Use this for managing client-server interactions or game state. ```lua "Knit Controller": { "prefix": ["knitcontroller"], "body": [ "local Knit = require(ReplicatedStorage.Packages.Knit)", "", "local ${0:$TM_FILENAME_BASE} = Knit.CreateController { Name = \"${0:$TM_FILENAME_BASE}\" }", "", "", "function ${0:$TM_FILENAME_BASE}:KnitStart()", "\t", "end", "", "", "function ${0:$TM_FILENAME_BASE}:KnitInit()", "\t", "end", "", "", "return ${0:$TM_FILENAME_BASE}", "" ], "description": "Knit Controller template" } ``` -------------------------------- ### Create Knit Service Source: https://sleitnick.github.io/Knit/docs/vscodesnippets Template for creating a Knit service, including initialization and start functions. Use this for defining modular server-side logic. ```lua "Knit Service": { "prefix": ["knitservice"], "body": [ "local Knit = require(ReplicatedStorage.Packages.Knit)", "", "local ${0:$TM_FILENAME_BASE} = Knit.CreateService {", "\tName = \"${0:$TM_FILENAME_BASE}\",", "\tClient = {},", "}", "", "", "function ${0:$TM_FILENAME_BASE}:KnitStart()", "\t", "end", "", "", "function ${0:$TM_FILENAME_BASE}:KnitInit()", "\t", "end", "", "", "return ${0:$TM_FILENAME_BASE}", "" ], "description": "Knit Service template" } ``` -------------------------------- ### GetControllers Source: https://sleitnick.github.io/Knit/api/KnitClient Gets a table of all controllers. ```APIDOC ## GetControllers ### Description Gets a table of all controllers. ### Method static ### Returns - **{ [string]: Controller }** - Description ``` -------------------------------- ### KnitServer.GetService Source: https://sleitnick.github.io/Knit/api Gets the service by name. Throws an error if the service is not found. ```APIDOC ## KnitServer.GetService ### Description Gets the service by name. Throws an error if the service is not found. ### Method `KnitServer.GetService(serviceName: string) -> Service` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **serviceName** (string) - Required - The name of the service to retrieve. ### Request Example ```lua local MyService = Knit.GetService("MyService") ``` ### Response #### Success Response (Service) - **Service** (Service) - The requested service object. #### Response Example ```lua -- Returns a Service object ``` ``` -------------------------------- ### Get Controller by Name Source: https://sleitnick.github.io/Knit/api/KnitClient Retrieves a specific controller instance using its registered name. Throws an error if the controller is not found. ```lua KnitClient.GetController("MyController") ``` -------------------------------- ### Get All Controllers Source: https://sleitnick.github.io/Knit/api/KnitClient Retrieves a table containing all currently loaded controllers, indexed by their names. ```lua KnitClient.GetControllers() ``` -------------------------------- ### Create a RemoteProperty Marker Source: https://sleitnick.github.io/Knit/api Use `CreateProperty` to define a marker that will become a `RemoteProperty` when Knit starts. An initial value can be provided. This is useful for replicating data to clients. ```lua local MyService = Knit.CreateService { Name = "MyService", Client = { -- Create the property marker, which will turn into a -- RemoteProperty when Knit.Start() is called: MyProperty = Knit.CreateProperty("HelloWorld"), }, } function MyService:KnitInit() -- Change the value of the property: self.Client.MyProperty:Set("HelloWorldAgain") end ``` -------------------------------- ### CreateProperty Source: https://sleitnick.github.io/Knit/api/KnitServer Returns a marker that transforms a key into a RemoteProperty. This should only be called within the Client table of a service. An initial value can be provided to set the starting state of the property, which is useful for replicating data to clients. ```APIDOC ## CreateProperty ### Description Returns a marker that will transform the current key into a RemoteProperty once the service is created. Should only be called within the Client table of a service. An initial value can be passed along as well. RemoteProperties are great for replicating data to all of the clients. Different data can also be set per client. See [RemoteProperty](https://sleitnick.github.io/RbxUtil/api/RemoteProperty) documentation for more info. ### Parameters #### Path Parameters - **initialValue** (any) - Optional - The initial value for the RemoteProperty. ### Method `static` ### Returns - `PROPERTY_MARKER` - A marker that signifies a RemoteProperty. ### Request Example ```lua local MyService = Knit.CreateService { Name = "MyService", Client = { -- Create the property marker, which will turn into a -- RemoteProperty when Knit.Start() is called: MyProperty = Knit.CreateProperty("HelloWorld"), }, } function MyService:KnitInit() -- Change the value of the property: self.Client.MyProperty:Set("HelloWorldAgain") end ``` ``` -------------------------------- ### Use Events in a Knit Service Source: https://sleitnick.github.io/Knit/docs/services This example demonstrates how to use Knit's Signal module to create and fire events from a service. The `AddPoints` method now fires a `PointsChanged` event. ```lua -- Load the Signal module and create PointsChanged signal: local Signal = require(Knit.Util.Signal) PointsService.PointsChanged = Signal.new() -- Modify AddPoints: function PointsService:AddPoints(player, amount) local points = self:GetPoints(player) points += amount self.PointsPerPlayer[player] = points -- Fire event signal, as long as we actually changed the points: if amount ~= 0 then self.PointsChanged:Fire(player, points) end end ``` -------------------------------- ### Complete Server Startup Script with RbxUtil Source: https://sleitnick.github.io/Knit/docs/intellisense A consolidated server-side startup script using RbxUtil's Loader module to load services and initiate their startup methods. ```lua -- ServerScriptService.ServerStartup local services = Loader.LoadDescendants(ServerScriptService, Loader.MatchesName("Service$")) Loader.SpawnAll(services, "OnStart") ``` -------------------------------- ### Create and Reflect Services on Client Source: https://sleitnick.github.io/Knit/api/KnitClient Demonstrates server-side service creation with client-side reflection. Services are only exposed to the client if they have remote-based content in their Client table. ```lua -- Server-side service creation: local MyService = Knit.CreateService { Name = "MyService", Client = { MySignal = Knit.CreateSignal(), MyProperty = Knit.CreateProperty("Hello"), }, } function MyService:AddOne(player, number) return number + 1 end ------------------------------------------------- -- Client-side service reflection: local MyService = Knit.GetService("MyService") -- Call a method: local num = MyService:AddOne(5) --> 6 -- Fire a signal to the server: MyService.MySignal:Fire("Hello") -- Listen for signals from the server: MyService.MySignal:Connect(function(message) print(message) end) -- Observe the initial value and changes to properties: MyService.MyProperty:Observe(function(value) print(value) end) ``` -------------------------------- ### Implementing Knit Controller Lifecycle Methods Source: https://sleitnick.github.io/Knit/docs/controllers Shows how to implement optional KnitInit and KnitStart lifecycle methods within a controller. These methods are called during the controller's initialization and startup phases. ```lua function CameraController:KnitStart() print("CameraController KnitStart called") end function CameraController:KnitInit() print("CameraController KnitInit called") end ``` -------------------------------- ### OnStart Source: https://sleitnick.github.io/Knit/api/KnitServer References the Util folder. Should only be accessed when using Knit as a standalone module. If using Knit from Wally, modules should just be pulled in via Wally instead of relying on Knit's Util folder, as this folder only contains what is necessary for Knit to run in Wally mode. ```APIDOC ## `OnStart` ### Description References the Util folder. Should only be accessed when using Knit as a standalone module. If using Knit from Wally, modules should just be pulled in via Wally instead of relying on Knit's Util folder, as this folder only contains what is necessary for Knit to run in Wally mode. ### Lua Type Folder ### Readonly true ``` -------------------------------- ### Create and Set RemoteProperty in Server Source: https://sleitnick.github.io/Knit/docs/services Demonstrates how to create a RemoteProperty on the server and set its value for a specific player. This property can then be observed by clients. ```lua -- Create the RemoteProperty: PointsService.Client.Points = Knit.CreateProperty(0) function PointsService:AddPoints(player, amount) local points = self:GetPoints(player) points += amount self.PointsPerPlayer[player] = points self.Client.Points:SetFor(player, points) end ``` -------------------------------- ### Create a Knit Service Source: https://sleitnick.github.io/Knit/api Define and create a new service. Services must be created before Knit.Start() is called. Expose client-side functions and define Knit lifecycle methods like KnitStart and KnitInit. ```lua -- Create a service local MyService = Knit.CreateService { Name = "MyService", Client = {}, } -- Expose a ToAllCaps remote function to the clients function MyService.Client:ToAllCaps(player, msg) return msg:upper() end -- Knit will call KnitStart after all services have been initialized function MyService:KnitStart() print("MyService started") end -- Knit will call KnitInit when Knit is first started function MyService:KnitInit() print("MyService initialize") end ``` -------------------------------- ### Create a Basic Knit Service Source: https://sleitnick.github.io/Knit/docs/services This is the simplest form of creating a service. The `Name` field is required and must be unique. The `Client` table is optional but recommended for clarity. ```lua local PointsService = Knit.CreateService { Name = "PointsService", Client = {} } return PointsService ``` -------------------------------- ### GetService Source: https://sleitnick.github.io/Knit/api Gets the service by name. Throws an error if the service is not found. ```APIDOC ## `GetService` ### Description Gets the service by name. Throws an error if the service is not found. ### Method `Knit.GetService(serviceName)` ### Parameters #### Path Parameters - **serviceName** (string) - Required - The name of the service to retrieve. ### Returns - **Service** - The requested service. ``` -------------------------------- ### Add Services from a Folder Source: https://sleitnick.github.io/Knit/api Require all modules that are children of a given parent instance. This is a convenient way to load multiple services from a directory. ```lua Knit.AddServices(somewhere.Services) ``` -------------------------------- ### GetController Source: https://sleitnick.github.io/Knit/api/KnitClient Gets the controller by name. Throws an error if the controller is not found. ```APIDOC ## GetController controllerName ### Description Gets the controller by name. Throws an error if the controller is not found. ### Method static ### Parameters #### Path Parameters - **controllerName** (string) - Required - Description ### Returns - **Controller** - Description ``` -------------------------------- ### Listen for Client-to-Server Signal in Knit Service Source: https://sleitnick.github.io/Knit/docs/services Initializes a Knit service by connecting to a client-to-server signal ('GiveMePoints'). When the client fires this signal, the server responds by adding random points to the player. ```lua function PointsService:KnitInit() local rng = Random.new() -- Listen for the client to fire this signal, then give random points: self.Client.GiveMePoints:Connect(function(player) local points = rng:NextInteger(0, 10) self:AddPoints(player, points) print("Gave " .. player.Name .. " " .. points .. " points") end) -- ...other code for cleaning up player data here end ``` -------------------------------- ### Add Services from a Parent Instance Source: https://sleitnick.github.io/Knit/api Requires all modules that are children of the given parent. This is an easy way to quickly load all services that might be in a folder. ```lua Knit.AddServices(somewhere.Services) ``` -------------------------------- ### Reference Roblox Service Source: https://sleitnick.github.io/Knit/docs/vscodesnippets Snippet to quickly get a Roblox service. Useful for accessing built-in Roblox functionalities. ```lua "Service": { "prefix": ["service"], "body": ["local ${0:Name}Service = game:GetService(\" ${0:Name}Service\")"], "description": "Roblox Service" } ``` -------------------------------- ### Using Knit's Signal Class in a Service Source: https://sleitnick.github.io/Knit/docs/util Demonstrates how to import and instantiate the Signal class within a Knit service. Ensure Knit is required before accessing its utility modules. ```lua local Signal = require(Knit.Util.Signal) local MyService = Knit.CreateService { Name = "MyService", SomeSignal = Signal.new(), } ``` -------------------------------- ### Implement Service Methods Using Properties Source: https://sleitnick.github.io/Knit/docs/services This snippet shows how to implement service methods using the previously defined properties. It updates and retrieves player points from the `PointsPerPlayer` table. ```lua PointsService.PointsPerPlayer = {} function PointsService:AddPoints(player, amount) local points = self:GetPoints(player) -- Current amount of points points += amount -- Add points self.PointsPerPlayer[player] = points -- Store points end function PointsService:GetPoints(player) local points = self.PointsPerPlayer[player] return if points ~= nil then points else 0 -- Return 0 if no points found for player end ``` -------------------------------- ### Accessing Server Services in Knit Controllers Source: https://sleitnick.github.io/Knit/docs/controllers Demonstrates how to access server-side services and their events/methods from a client controller. Ensure the service is exposed on the server. ```lua function CameraController:KnitStart() local SomeService = Knit.GetService("SomeService") SomeService:DoSomething() SomeService.SomeEvent:Connect(function(...) end) SomeService.AnotherEvent:Fire("Some data") end ``` -------------------------------- ### Create a Knit Controller Source: https://sleitnick.github.io/Knit/api/KnitClient Defines and initializes a new controller. Controllers must be created before calling Knit.Start(). ```lua local MyController = Knit.CreateController { Name = "MyController", } function MyController:KnitStart() print("MyController started") end function MyController:KnitInit() print("MyController initialized") end ``` -------------------------------- ### Invoke Client-Exposed Method from Client Source: https://sleitnick.github.io/Knit/docs/services On the client-side, require Knit, get the desired service, and invoke its client-exposed methods. Use .andThen for asynchronous callbacks. ```lua -- From a LocalScript local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit) local PointsService = Knit.GetService("PointsService") PointsService:GetPoints():andThen(function(points) print("Points for myself:", points) end) ``` -------------------------------- ### Add Properties to a Knit Service Source: https://sleitnick.github.io/Knit/docs/services Properties can be added to services like any other Lua table. This example adds a `PointsPerPlayer` table to store player points. ```lua PointsService.PointsPerPlayer = {} ``` -------------------------------- ### Load Filtered Descendants with RbxUtil Loader Source: https://sleitnick.github.io/Knit/docs/intellisense Filter ModuleScripts by name using Loader.MatchesName when calling Loader.LoadDescendants. This example loads modules ending with 'Service'. ```lua local services = Loader.LoadDescendants(ServerScriptService, Loader.MatchesName("Service$")) ``` -------------------------------- ### Start Knit with ServicePromises disabled Source: https://sleitnick.github.io/Knit/api/KnitClient Configure Knit to not use promises for service methods by passing {ServicePromises = false} to Knit.Start(). This affects how service calls behave. ```lua Knit.Start({ServicePromises = false}):andThen(function() print("Knit started!") end):catch(warn) ``` -------------------------------- ### CreateService Source: https://sleitnick.github.io/Knit/api Constructs a new service. Services must be created before calling `Knit.Start()`. ```APIDOC ## `CreateService` ### Description Constructs a new service. Services must be created _before_ calling `Knit.Start()`. ### Method `Knit.CreateService(serviceDef)` ### Parameters #### Path Parameters - **serviceDef** (ServiceDef) - Required - The definition of the service to create. ### Returns - **Service** - The created service object. ``` -------------------------------- ### CreateProperty Marker with Initial Value Source: https://sleitnick.github.io/Knit/api/KnitServer Returns a marker to create a RemoteProperty. Use within a service's Client table. An initial value can be provided to replicate data to all clients. ```Lua MyProperty = Knit.CreateProperty("HelloWorld") ``` -------------------------------- ### Create and Define a Service Source: https://sleitnick.github.io/Knit/api/KnitServer Defines a new service with client-accessible functions and Knit lifecycle methods. Services must be created before Knit.Start(). ```lua -- Create a service local MyService = Knit.CreateService { Name = "MyService", Client = {}, } -- Expose a ToAllCaps remote function to the clients function MyService.Client:ToAllCaps(player, msg) return msg:upper() end -- Knit will call KnitStart after all services have been initialized function MyService:KnitStart() print("MyService started") end -- Knit will call KnitInit when Knit is first started function MyService:KnitInit() print("MyService initialize") end ``` -------------------------------- ### Add Services Recursively from a Parent Instance Source: https://sleitnick.github.io/Knit/api Requires all modules that are descendants of the given parent. ```lua Knit.AddServicesDeep(somewhere.Services) ``` -------------------------------- ### KnitServer.AddServices Source: https://sleitnick.github.io/Knit/api Requires all the modules that are children of the given parent. This is an easy way to quickly load all services that might be in a folder. ```APIDOC ## KnitServer.AddServices ### Description Requires all the modules that are children of the given parent. This is an easy way to quickly load all services that might be in a folder. ### Method `KnitServer.AddServices(parent: Instance) -> {Service}` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **parent** (Instance) - Required - The parent instance containing the service modules. ### Request Example ```lua Knit.AddServices(somewhere.Services) ``` ### Response #### Success Response ({Service}) - **{Service}** (table) - A table of loaded services. #### Response Example ```lua -- Returns a table of Service objects ``` ``` -------------------------------- ### KnitServer.CreateService Source: https://sleitnick.github.io/Knit/api Constructs a new service. Services must be created before calling Knit.Start(). ```APIDOC ## KnitServer.CreateService ### Description Constructs a new service. Services must be created before calling `Knit.Start()`. ### Method `KnitServer.CreateService(serviceDef: ServiceDef) -> Service` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **serviceDef** (ServiceDef) - Required - Definition of the service to be created. ### Request Example ```lua local MyService = Knit.CreateService { Name = "MyService", Client = {}, } function MyService.Client:ToAllCaps(player, msg) return msg:upper() end function MyService:KnitStart() print("MyService started") end function MyService:KnitInit() print("MyService initialize") end ``` ### Response #### Success Response (Service) - **Service** (Service) - The newly created service object. #### Response Example ```lua -- Returns a Service object ``` ``` -------------------------------- ### Add Controllers from Parent Instance Source: https://sleitnick.github.io/Knit/api/KnitClient Requires all child modules of a given parent instance to be loaded as controllers. ```lua Knit.AddControllers(somewhere.Controllers) ``` -------------------------------- ### Loader Module Usage Source: https://sleitnick.github.io/Knit/docs/intellisense Utilize the Loader module to load and register services. This approach simplifies the custom module loading process by providing utility functions for matching and loading modules before starting Knit. ```lua local services = Loader.LoadChildren(parent, Loader.MatchesName("Service$")) for _, service in services do Knit.CreateService(service) end Knit.Start() ``` -------------------------------- ### Observe RemoteProperty on Client Source: https://sleitnick.github.io/Knit/docs/services Shows how to observe a RemoteProperty from the client to receive its current value and any subsequent updates. Ensure Knit is required and the service is obtained. ```lua -- LocalScript local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit) local PointsService = Knit.GetService("PointsService") -- The 'Observe' method will fire for the current value and any time the value changes: PointsService.Points:Observe(function(points) print("Current number of points:", points) end) ``` -------------------------------- ### KnitOptions Source: https://sleitnick.github.io/Knit/api Defines options for KnitServer initialization. Middleware defined here will apply to all services unless they specify their own middleware. ```APIDOC ## KnitOptions ### Description Options for KnitServer initialization. Middleware defined here will apply to all services unless they specify their own middleware. ### Fields - **Middleware** (Middleware?) - Optional - Server-level middleware to be applied to all services. ``` -------------------------------- ### AddServices Source: https://sleitnick.github.io/Knit/api Requires all the modules that are children of the given parent. This is an easy way to quickly load all services that might be in a folder. ```APIDOC ## `AddServices` ### Description Requires all the modules that are children of the given parent. This is an easy way to quickly load all services that might be in a folder. ### Method `Knit.AddServices(parent)` ### Parameters #### Path Parameters - **parent** (Instance) - Required - The parent instance containing the services to add. ### Returns - **{ Service }** - A table of the added services. ``` -------------------------------- ### Implement Basic Camera Locking Behavior Source: https://sleitnick.github.io/Knit/docs/controllers This snippet shows how to implement basic camera locking and unlocking logic, updating the camera's type and CFrame. ```lua function CameraController:LockTo(part) local cam = workspace.CurrentCamera self.Locked = true cam.CameraType = Enum.CameraType.Scriptable cam.CFrame = part.CFrame * CFrame.new(0, 0, self.Distance) end function CameraController:Unlock() local cam = workspace.CurrentCamera self.Locked = false cam.CameraType = Enum.CameraType.Custom end ``` -------------------------------- ### Create a RemoteProperty Marker Source: https://sleitnick.github.io/Knit/api Use CreateProperty within a service's Client table to define a marker that will become a RemoteProperty. This is useful for replicating data across clients. An initial value can be provided. ```lua local MyService = Knit.CreateService { Name = "MyService", Client = { -- Create the property marker, which will turn into a -- RemoteProperty when Knit.Start() is called: MyProperty = Knit.CreateProperty("HelloWorld"), }, } function MyService:KnitInit() -- Change the value of the property: self.Client.MyProperty:Set("HelloWorldAgain") end ``` -------------------------------- ### ServerMiddleware Source: https://sleitnick.github.io/Knit/api An array of server middleware functions. ```APIDOC ## ServerMiddleware ### Description An array of server middleware functions. ### Type `{ServerMiddlewareFn}` ``` -------------------------------- ### Use a Service from another ModuleScript Source: https://sleitnick.github.io/Knit/docs/intellisense This ModuleScript demonstrates how to require and use another service (MathService) to perform calculations. Ensure the required service is accessible. ```lua -- ServerScriptService.CalcService -- Simply require another service to use it: local MathService = require(somewhere.MathService) local CalcService = {} function CalcService:OnStart() local n1 = 10 local n2 = 20 local sum = MathService:Add(n1, n2) print(`Sum of {n1} and {n2} is {sum}`) end return CalcService ``` -------------------------------- ### Catching KnitInit Errors with Catch Source: https://sleitnick.github.io/Knit/docs/executionmodel Alternatively, errors from `KnitInit` can be handled using the `Catch()` method on the promise returned by `Knit.Start()`, providing a callback for error scenarios. ```lua Knit.Start():catch(function(err) -- Handle error warn(tostring(err)) end) ```