### Start Shake and Bind to RenderStep Source: https://context7.com/sleitnick/rbxutil/llms.txt Starts a shake effect and binds it to the RenderStep for camera manipulation. Requires `Packages.Shake` and `RunService`. ```lua local Shake = require(Packages.Shake) local RunService = game:GetService("RunService") local cameraShake = Shake.new() cameraShake.Amplitude = 5 cameraShake.Frequency = 0.1 cameraShake.FadeInTime = 0.2 cameraShake.FadeOutTime = 0.5 cameraShake.SustainTime = 1 cameraShake.Sustain = false cameraShake.PositionInfluence = Vector3.new(1, 1, 0) cameraShake.RotationInfluence = Vector3.new(0.1, 0.1, 0.1) -- Start the shake cameraShake:Start() -- Bind to RenderStep for camera shake local camera = workspace.CurrentCamera cameraShake:BindToRenderStep(Shake.NextRenderName(), Enum.RenderPriority.Last.Value, function(pos, rot, isDone) camera.CFrame *= CFrame.new(pos) * CFrame.Angles(rot.X, rot.Y, rot.Z) end) ``` -------------------------------- ### Require and Use RBXUtil Modules in Lua Source: https://github.com/sleitnick/rbxutil/blob/main/docs/intro.md Demonstrates how to require the installed Signal and TableUtil modules from the Packages folder and use their functionalities. This example connects a Signal and shuffles data using TableUtil. ```lua -- Reference folder with packages: local Packages = game:GetService("ReplicatedStorage").Packages -- Require the utility modules: local Signal = require(Packages.Signal) local TableUtil = require(Packages.TableUtil) -- Use the modules: local signal = Signal.new() signal:Connect(function(data) local randomizedData = TableUtil.Shuffle(data) print(randomizedData) end) signal:Fire({"A", "B", "C"}) ``` -------------------------------- ### Install RbxUtil Package Source: https://github.com/sleitnick/rbxutil/blob/main/docs/ts.md Command to install a specific RbxUtil module using npm. ```bash $ npm install @rbxutil/quaternion ``` -------------------------------- ### Net Module: Client-Side Event Connection and Function Invocation Source: https://context7.com/sleitnick/rbxutil/llms.txt Client-side setup for Net module. Connect to server events using Net:Connect and invoke server functions with Net:Invoke. Fire events to the server using Net:RemoteEvent:FireServer. ```lua -- CLIENT SIDE -- Connect to server events Net:Connect("PointsChanged", function(points) print("Points updated:", points) end) -- Invoke server function local serverTime = Net:Invoke("GetServerTime") print("Server time:", serverTime) -- Fire event to server Net:RemoteEvent("PlayerAction"):FireServer("Jump", {Height = 10}) ``` -------------------------------- ### Define and Manage Components in Roblox Source: https://context7.com/sleitnick/rbxutil/llms.txt Use Component.new to bind classes to instances with specific tags. Lifecycle methods like Construct, Start, and Stop handle instance initialization and cleanup. ```lua local Component = require(Packages.Component) -- Create a component class local EnemyComponent = Component.new({ Tag = "Enemy", Ancestors = {workspace}, Extensions = {}, -- Optional extensions }) -- Optional: Set render priority for RenderSteppedUpdate EnemyComponent.RenderPriority = Enum.RenderPriority.Camera.Value -- Construct is called when the component is instantiated function EnemyComponent:Construct() self.Health = 100 self.MaxHealth = 100 self.Speed = 16 end -- Start is called after Construct, safe to get other components here function EnemyComponent:Start() print("Enemy started on instance:", self.Instance:GetFullName()) -- Get another component on the same instance local anotherComponent = self:GetComponent(SomeOtherComponent) end -- Stop is called when the tag is removed or instance is destroyed function EnemyComponent:Stop() print("Enemy stopped") end -- Optional: HeartbeatUpdate runs every Heartbeat function EnemyComponent:HeartbeatUpdate(dt) -- Update enemy logic end -- Optional: SteppedUpdate runs every Stepped function EnemyComponent:SteppedUpdate(dt) -- Physics update end -- Optional: RenderSteppedUpdate runs every RenderStepped (client only) function EnemyComponent:RenderSteppedUpdate(dt) -- Render update end -- Listen for component lifecycle events EnemyComponent.Started:Connect(function(component) print("An enemy component started:", component.Instance.Name) end) EnemyComponent.Stopped:Connect(function(component) print("An enemy component stopped:", component.Instance.Name) end) -- Get all existing components local allEnemies = EnemyComponent:GetAll() for _, enemy in ipairs(allEnemies) do enemy.Health = enemy.MaxHealth end -- Get component from a specific instance local enemyComponent = EnemyComponent:FromInstance(someInstance) if enemyComponent then enemyComponent.Health -= 10 end -- Wait for a component to be available on an instance EnemyComponent:WaitForInstance(someInstance):andThen(function(component) print("Component ready:", component.Health) end) ``` -------------------------------- ### Configure Rojo to Sync Packages Folder Source: https://github.com/sleitnick/rbxutil/blob/main/docs/intro.md Set up your Rojo configuration to sync the 'Packages' folder, generated by Wally, into Roblox Studio's ReplicatedStorage. This makes the installed modules accessible in your game. ```json { "name": "rbx-util-example", "tree": { "$className": "DataModel", "ReplicatedStorage": { "$className": "ReplicatedStorage", "Packages": { "$path": "Packages" } } } } ``` -------------------------------- ### Net Module: Server-Side RemoteEvent and RemoteFunction Handling Source: https://context7.com/sleitnick/rbxutil/llms.txt Server-side setup for Net module. Use RemoteEvent to create/get events and Connect to handle incoming client events. Handle RemoteFunction calls with Net:Handle. ```lua local Net = require(Packages.Net) -- SERVER SIDE -- Create/get a RemoteEvent (auto-created on server) local remoteEvent = Net:RemoteEvent("PointsChanged") -- Connect to incoming client events Net:Connect("PlayerAction", function(player, action, data) print(player.Name .. " performed " .. action) end) -- Connect to unreliable events (for frequent updates like position) Net:ConnectUnreliable("PositionUpdate", function(player, position) -- Handle position update end) -- Handle a RemoteFunction call Net:Handle("GetServerTime", function(player) return os.time() end) -- Fire events to clients Net:RemoteEvent("PointsChanged"):FireClient(somePlayer, 100) Net:RemoteEvent("PointsChanged"):FireAllClients(500) ``` -------------------------------- ### TableUtil: Getting Keys and Values from a Dictionary Source: https://context7.com/sleitnick/rbxutil/llms.txt Extract all keys from a dictionary-like table. Extract all values from a dictionary-like table. ```lua -- Get keys and values local dict = {A = 10, B = 20, C = 30} local keys = TableUtil.Keys(dict) -- {"A", "B", "C"} local values = TableUtil.Values(dict) -- {10, 20, 30} ``` -------------------------------- ### TableUtil: Shuffling and Sampling Arrays Source: https://context7.com/sleitnick/rbxutil/llms.txt Shuffle the elements of an array randomly. Get a random sample of a specified size from an array. ```lua -- Shuffle array local shuffled = TableUtil.Shuffle(numbers) -- Get random sample local sample = TableUtil.Sample(numbers, 3) ``` -------------------------------- ### Handle Touch Input Events Source: https://context7.com/sleitnick/rbxutil/llms.txt Listens for touch gestures, including when touches start, end, or move. Use :Destroy() to clean up the touch input handler. ```lua local Input = require(Packages.Input) local Touch = Input.Touch -- Touch input local touch = Touch.new() touch.TouchStarted:Connect(function(touchPositions) print("Touch started with", #touchPositions, "fingers") end) touch.TouchEnded:Connect(function(touchPositions) print("Touch ended") end) touch.TouchMoved:Connect(function(touchPositions) -- Handle touch movement end) ``` -------------------------------- ### Spawn and Manage Concurrent Tasks with Concur Source: https://context7.com/sleitnick/rbxutil/llms.txt Use Concur.spawn to start a new concurrent task. Tasks can be deferred, delayed, or created from immediate values. Handle task completion using OnCompleted or await results with Await. ```lua local Concur = require(Packages.Concur) -- Spawn a concurrent task local task1 = Concur.spawn(function() task.wait(2) return "Task 1 complete" end) -- Deferred execution local task2 = Concur.defer(function() return "Task 2 complete" end) -- Delayed execution local task3 = Concur.delay(1, function() return "Task 3 complete after 1 second" end) -- Create from immediate value local immediate = Concur.value(42) -- Wait from an event local playerJoined = Concur.event(game.Players.PlayerAdded, function(player) return player.Name == "SpecificPlayer" end) -- Handle completion with callback task1:OnCompleted(function(err, result) if err then warn("Error:", err) return end print(result) end) -- Await (yields current thread) local err, result = task1:Await() if not err then print("Result:", result) end -- Await with timeout local err, result = task1:Await(5) -- 5 second timeout if err == Concur.Errors.Timeout then warn("Task timed out") end -- Wait for all tasks to complete local allTasks = Concur.all({task1, task2, task3}) allTasks:OnCompleted(function(err, results) for i, res in ipairs(results) do print("Task", i, ":", res[1] and "Error" or res[2]) end end) -- Race: complete when first task finishes (without error) local firstComplete = Concur.first({task1, task2, task3}) firstComplete:OnCompleted(function(err, result) print("First to complete:", result) end) -- Check completion status if task1:IsCompleted() then print("Task 1 is done") end -- Stop a running task local longTask = Concur.spawn(function() for i = 1, 100 do print(i) task.wait(1) end end) task.wait(5) longTask:Stop() -- Handle stopped error longTask:OnCompleted(function(err) if err == Concur.Errors.Stopped then print("Task was stopped") end end) -- Save all player data concurrently game:BindToClose(function() local saves = {} for _, player in game.Players:GetPlayers() do table.insert(saves, Concur.spawn(function() savePlayerData(player) end)) end Concur.all(saves):Await() end) ``` -------------------------------- ### Create and Configure Shake Instance Source: https://context7.com/sleitnick/rbxutil/llms.txt Initializes a Shake instance and configures its properties for amplitude, frequency, and fade. Requires `Packages.Shake`. ```lua local Shake = require(Packages.Shake) -- Create a shake instance local cameraShake = Shake.new() -- Configure the shake cameraShake.Amplitude = 5 -- Magnitude of shake cameraShake.Frequency = 0.1 -- Speed (smaller = faster) cameraShake.FadeInTime = 0.2 -- Fade-in duration cameraShake.FadeOutTime = 0.5 -- Fade-out duration cameraShake.SustainTime = 1 -- Duration at full amplitude cameraShake.Sustain = false -- Set true for indefinite shake cameraShake.PositionInfluence = Vector3.new(1, 1, 0) cameraShake.RotationInfluence = Vector3.new(0.1, 0.1, 0.1) ``` -------------------------------- ### Configure Rojo Project Source: https://github.com/sleitnick/rbxutil/blob/main/docs/ts.md Add the @rbxutil directory to the node_modules section of your default.project.json file. ```json "node_modules": { "$className": "Folder", "@rbxts": { "$path": "node_modules/@rbxts" }, "@rbxutil": { "$path": "node_modules/@rbxutil" } } ``` -------------------------------- ### TableUtil: Copying Tables (Shallow and Deep) Source: https://context7.com/sleitnick/rbxutil/llms.txt Demonstrates shallow and deep copying of tables using TableUtil.Copy. The second argument, when true, enables deep copying. ```lua local TableUtil = require(Packages.TableUtil) -- Copy tables (shallow or deep) local original = {a = 1, b = {c = 2}} local shallow = TableUtil.Copy(original) local deep = TableUtil.Copy(original, true) ``` -------------------------------- ### Create and Update CFrame Spring for Camera Source: https://context7.com/sleitnick/rbxutil/llms.txt Initializes a CFrame spring for camera smoothing and updates it each frame. Requires `Packages.Spring`. ```lua local Spring = require(Packages.Spring) local RunService = game:GetService("RunService") -- Create a spring for CFrame (camera smoothing) local cameraSpring = Spring.new(CFrame.identity, 0.2) -- Update spring every frame RunService.Heartbeat:Connect(function(dt) local currentCFrame = cameraSpring:Update(dt) camera.CFrame = currentCFrame end) ``` -------------------------------- ### Create and Use Custom Enums with EnumList Source: https://context7.com/sleitnick/rbxutil/llms.txt Demonstrates how to create custom enumeration types and access their properties. Use this for defining sets of named constants. ```lua local EnumList = require(Packages.EnumList) -- Create an enum local Directions = EnumList.new("Directions", { "Up", "Down", "Left", "Right", }) -- Access enum items local dir = Directions.Up print(dir.Name) --> "Up" print(dir.Value) --> 1 print(dir.EnumType == Directions) --> true -- Check if value belongs to enum print(Directions:BelongsTo(dir)) --> true print(Directions:BelongsTo("Up")) --> false -- Get all enum items local items = Directions:GetEnumItems() for _, item in ipairs(items) do print(item.Name, item.Value) end -- Get enum name print(Directions:GetName()) --> "Directions" -- Use in game logic local GameState = EnumList.new("GameState", { "Waiting", "Starting", "Playing", "Ending", }) local currentState = GameState.Waiting if currentState == GameState.Waiting then print("Waiting for players...") end ``` -------------------------------- ### Create and Update Vector3 Spring Source: https://context7.com/sleitnick/rbxutil/llms.txt Initializes a Vector3 spring with a target position and updates it each frame. Requires `Packages.Spring`. ```lua local Spring = require(Packages.Spring) local RunService = game:GetService("RunService") -- Create a spring for Vector3 local positionSpring = Spring.new(Vector3.zero, 0.3, 50) -- initial, smoothTime, maxSpeed positionSpring.Target = Vector3.new(10, 5, 0) -- Update spring every frame RunService.Heartbeat:Connect(function(dt) local currentPosition = positionSpring:Update(dt) part.Position = currentPosition end) ``` -------------------------------- ### Handle Mouse Input Events Source: https://context7.com/sleitnick/rbxutil/llms.txt Sets up listeners for various mouse events like clicks, movement, and scrolling. Ensure to call :Destroy() on the mouse object when it's no longer needed. ```lua local Input = require(Packages.Input) local Mouse = Input.Mouse -- Mouse input local mouse = Mouse.new() mouse.LeftDown:Connect(function() print("Left mouse button pressed") end) mouse.LeftUp:Connect(function() print("Left mouse button released") end) mouse.RightDown:Connect(function() print("Right click") end) mouse.Moved:Connect(function(position) print("Mouse position:", position) end) mouse.Scrolled:Connect(function(direction) print("Scrolled:", direction) end) ``` -------------------------------- ### Handle Keyboard Input Events Source: https://context7.com/sleitnick/rbxutil/llms.txt Provides methods to check key states and listen for key press/release events. Use :Destroy() to clean up the keyboard input handler. ```lua local Input = require(Packages.Input) local Keyboard = Input.Keyboard -- Keyboard input local keyboard = Keyboard.new() keyboard:IsKeyDown(Enum.KeyCode.W) -- Check if key is held keyboard.KeyDown:Connect(function(keyCode) print("Key pressed:", keyCode.Name) end) keyboard.KeyUp:Connect(function(keyCode) print("Key released:", keyCode.Name) end) ``` -------------------------------- ### Implement Client-Server Communication with Comm Source: https://context7.com/sleitnick/rbxutil/llms.txt Comm facilitates networking through ServerComm and ClientComm, supporting remote functions, signals, and replicated properties. ```lua local Comm = require(Packages.Comm) local ServerComm = Comm.ServerComm local ClientComm = Comm.ClientComm -- SERVER SIDE local serverComm = ServerComm.new(game:GetService("ReplicatedStorage"), "GameComm") -- Bind a function that clients can call serverComm:BindFunction("GetPlayerData", function(player: Player) return { Coins = 100, Level = 5, } end) -- Wrap a method from a table local DataService = { _cache = {}, GetCachedData = function(self, player: Player, key: string) return self._cache[player] and self._cache[player][key] end, } serverComm:WrapMethod(DataService, "GetCachedData") -- Create a signal for server-to-client communication local pointsChanged = serverComm:CreateSignal("PointsChanged") -- Fire to specific player pointsChanged:Fire(somePlayer, 500) -- Fire to all players pointsChanged:FireAll(1000) -- Fire to all except one player pointsChanged:FireExcept(somePlayer, 750) -- Fire with filter predicate pointsChanged:FireFilter(function(player) return player.Team == game.Teams.Red end, 250) -- Listen for client signals pointsChanged:Connect(function(player, message) print(player.Name .. " sent: " .. message) end) -- Create a replicated property local mapInfo = serverComm:CreateProperty("MapInfo", { MapName = "DefaultMap", TimeLimit = 60, }) -- Update property for all clients mapInfo:Set({MapName = "NewMap", TimeLimit = 120}) -- Update property for specific player mapInfo:SetFor(somePlayer, {MapName = "SpecialMap", TimeLimit = 180}) -- CLIENT SIDE local clientComm = ClientComm.new(game:GetService("ReplicatedStorage"), false, "GameComm") -- Build a communication object local comm = clientComm:BuildObject() -- Call server function local playerData = comm:GetPlayerData() print("Coins:", playerData.Coins) -- Get cached data using wrapped method local cachedValue = comm:GetCachedData("someKey") ``` -------------------------------- ### TableUtil: Reconciling and Syncing Table Data Source: https://context7.com/sleitnick/rbxutil/llms.txt Reconcile player data with a template, adding missing keys. Sync data with a template, performing a two-way sync and removing extra keys. ```lua -- Reconcile player data with template (adds missing keys, preserves existing) local template = {Coins = 0, Level = 1, Inventory = {}} local playerData = {Coins = 100, OldKey = "value"} local reconciledData = TableUtil.Reconcile(playerData, template) -- Result: {Coins = 100, Level = 1, Inventory = {}, OldKey = "value"} -- Sync data with template (two-way sync, removes extra keys) local syncedData = TableUtil.Sync(playerData, template) -- Result: {Coins = 100, Level = 1, Inventory = {}} ``` -------------------------------- ### Clone Shake Preset Source: https://context7.com/sleitnick/rbxutil/llms.txt Clones an existing shake instance to create a new one with modified properties, useful for presets like recoil. Requires `Packages.Shake`. ```lua local Shake = require(Packages.Shake) -- Clone a shake preset local recoilShake = cameraShake:Clone() recoilShake.Amplitude = 2 ``` -------------------------------- ### Modify Spring Target and Apply Impulse Source: https://context7.com/sleitnick/rbxutil/llms.txt Demonstrates setting a new target for a spring and applying an impulse to change its velocity. Requires `Packages.Spring`. ```lua local Spring = require(Packages.Spring) -- Set new target (spring smoothly moves toward it) positionSpring.Target = Vector3.new(0, 10, 5) -- Apply an impulse (adds velocity) positionSpring:Impulse(Vector3.new(0, 50, 0)) -- Jump impulse ``` -------------------------------- ### TableUtil: Finding Elements and Checking Conditions in Tables Source: https://context7.com/sleitnick/rbxutil/llms.txt Find the first element in a table that satisfies a given predicate function. Check if all or some elements satisfy a predicate. ```lua -- Find in table with predicate local users = {{Name = "Bob", Age = 20}, {Name = "Alice", Age = 25}} local alice, index = TableUtil.Find(users, function(user) return user.Name == "Alice" end) -- Check all/some with predicate local allAdults = TableUtil.Every(users, function(u) return u.Age >= 18 end) local hasYoung = TableUtil.Some(users, function(u) return u.Age < 21 end) ``` -------------------------------- ### Create and Update Number Spring Source: https://context7.com/sleitnick/rbxutil/llms.txt Initializes a number spring with a target value and updates it each frame. Requires `Packages.Spring`. ```lua local Spring = require(Packages.Spring) local RunService = game:GetService("RunService") -- Create a spring for a number value local numberSpring = Spring.new(0, 0.5) -- initial value, smoothTime numberSpring.Target = 100 -- Update spring every frame RunService.Heartbeat:Connect(function(dt) local currentValue = numberSpring:Update(dt) print("Number:", currentValue) end) ``` -------------------------------- ### Create Periodic Timers with Timer Source: https://context7.com/sleitnick/rbxutil/llms.txt The Timer module allows for periodic execution with configurable intervals, drift prevention, and signal-based updates. ```lua local Timer = require(Packages.Timer) -- Create a timer that ticks every 2 seconds local timer = Timer.new(2) -- Connect to the Tick event timer.Tick:Connect(function() print("Tick! Time:", os.time()) end) -- Start the timer timer:Start() -- Start the timer and fire immediately timer:StartNow() -- Check if timer is running if timer:IsRunning() then print("Timer is active") end -- Stop the timer timer:Stop() -- Configure timer properties before starting local preciseTimer = Timer.new(0.1) preciseTimer.AllowDrift = false -- Prevents drift accumulation preciseTimer.UpdateSignal = RunService.Heartbeat -- Default preciseTimer.TimeFunction = os.clock -- Use os.clock instead of time() preciseTimer.Tick:Connect(function() -- Precision-critical code end) preciseTimer:Start() -- Simple one-liner timer local connection = Timer.simple(1, function() print("Simple tick!") end) -- Simple timer with immediate start local connection = Timer.simple(1, function() print("Immediate tick!") end, true) -- startNow = true -- Destroy the timer timer:Destroy() ``` -------------------------------- ### Implement Custom Events with Signal Source: https://context7.com/sleitnick/rbxutil/llms.txt Use Signal for yield-safe custom events that support connection management, one-time handlers, and wrapping existing RBXScriptSignals. ```lua local Signal = require(Packages.Signal) -- Create a new signal local playerDied = Signal.new() -- Connect a handler function local connection = playerDied:Connect(function(playerName, cause) print(playerName .. " died from " .. cause) end) -- Fire the signal with arguments playerDied:Fire("Player1", "fall damage") -- Connect a one-time handler that auto-disconnects after firing playerDied:Once(function(playerName, cause) print("First death: " .. playerName) end) -- Wait for the signal (yields current thread) task.spawn(function() local name, cause = playerDied:Wait() print("Waited for death: " .. name) end) -- Wrap an existing RBXScriptSignal local childAdded = Signal.Wrap(workspace.ChildAdded) childAdded:Connect(function(child) print(child.Name .. " added to workspace") end) -- Check if object is a Signal print(Signal.Is(playerDied)) --> true -- Disconnect a specific connection connection:Disconnect() -- Disconnect all connections playerDied:DisconnectAll() -- Clean up the signal playerDied:Destroy() ``` -------------------------------- ### Add RBXUtil Dependencies to Wally Configuration Source: https://github.com/sleitnick/rbxutil/blob/main/docs/intro.md Specify RBXUtil modules like Signal and TableUtil as dependencies in your wally.toml file. Ensure the version specifier matches your project's requirements. ```toml [package] name = "your_name/your_project" version = "0.1.0" registry = "https://github.com/UpliftGames/wally-index" realm = "shared" [dependencies] Signal = "sleitnick/signal@^1" TableUtil = "sleitnick/table-util@^1" ``` -------------------------------- ### Create Explosion Shake with Distance Falloff Source: https://context7.com/sleitnick/rbxutil/llms.txt Creates a shake effect for an explosion that diminishes with distance using `Shake.InverseSquare`. Requires `Packages.Shake`. ```lua local Shake = require(Packages.Shake) local function ExplosionShake(explosionPosition: Vector3) local shake = Shake.new() shake.Amplitude = 10 shake.FadeInTime = 0 shake.SustainTime = 0.5 shake.FadeOutTime = 1 shake:Start() shake:BindToRenderStep(Shake.NextRenderName(), Enum.RenderPriority.Last.Value, function(pos, rot) local distance = (camera.CFrame.Position - explosionPosition).Magnitude pos = Shake.InverseSquare(pos, distance) rot = Shake.InverseSquare(rot, distance) camera.CFrame *= CFrame.new(pos) * CFrame.Angles(rot.X, rot.Y, rot.Z) end) end ``` -------------------------------- ### Reset Spring and Access Properties Source: https://context7.com/sleitnick/rbxutil/llms.txt Resets a spring to a specific value instantly and accesses its current properties. Requires `Packages.Spring`. ```lua local Spring = require(Packages.Spring) -- Reset spring to a specific value (no smooth transition) positionSpring:Reset(Vector3.new(0, 0, 0)) -- Spring properties print("Current:", positionSpring.Current) print("Target:", positionSpring.Target) print("Velocity:", positionSpring.Velocity) print("SmoothTime:", positionSpring.SmoothTime) print("MaxSpeed:", positionSpring.MaxSpeed) ``` -------------------------------- ### Clean up Input Handlers Source: https://context7.com/sleitnick/rbxutil/llms.txt Demonstrates the necessary cleanup for input objects when they are no longer needed to prevent memory leaks. ```lua -- Clean up mouse:Destroy() keyboard:Destroy() ``` -------------------------------- ### TableUtil: Mapping and Filtering Table Values Source: https://context7.com/sleitnick/rbxutil/llms.txt Map values in a table by applying a function to each element. Filter values based on a predicate function. ```lua -- Map values local numbers = {1, 2, 3, 4, 5} local doubled = TableUtil.Map(numbers, function(n) return n * 2 end) -- Result: {2, 4, 6, 8, 10} -- Filter values local evens = TableUtil.Filter(numbers, function(n) return n % 2 == 0 end) -- Result: {2, 4} ``` -------------------------------- ### Handle Optional Values with Option Source: https://context7.com/sleitnick/rbxutil/llms.txt Use the Option module to represent values that may be nil, preventing common nil-related errors. It supports pattern matching, chaining, and safe unwrapping. ```lua local Option = require(Packages.Option) -- Create an Option with a value local someValue = Option.Some(42) -- Wrap a potentially nil value local maybeNil = Option.Wrap(possiblyNilValue) -- Use Option.None for explicit absence local noValue = Option.None -- Check if Option has a value if someValue:IsSome() then local value = someValue:Unwrap() print("Value:", value) end if noValue:IsNone() then print("No value present") end -- Pattern matching someValue:Match({ Some = function(value) print("Got value:", value) end, None = function() print("No value") end, }) -- Unwrap with fallback local result = maybeNil:UnwrapOr(0) -- Unwrap with fallback function local result = maybeNil:UnwrapOrElse(function() return calculateDefaultValue() end) -- Expect with custom error message local value = someValue:Expect("Value should exist!") -- Chain operations local doubled = someValue:AndThen(function(v) return Option.Some(v * 2) end) -- Logical operations local optA = Option.Some(10) local optB = Option.Some(20) local andResult = optA:And(optB) -- Returns optB if optA is Some local orResult = optA:Or(optB) -- Returns optA if it's Some, else optB local xorResult = optA:XOr(optB) -- Returns None (both are Some) -- Filter local filtered = someValue:Filter(function(v) return v > 10 end) -- Contains check print(someValue:Contains(42)) --> true -- Type checking print(Option.Is(someValue)) --> true -- Serialization for network/storage local serialized = someValue:Serialize() local deserialized = Option.Deserialize(serialized) ``` -------------------------------- ### Configure TypeScript Types Source: https://github.com/sleitnick/rbxutil/blob/main/docs/ts.md Include the @rbxutil directory in the typeRoots array within tsconfig.json. ```json "typeRoots": ["node_modules/@rbxts", "node_modules/@rbxutil"] ``` -------------------------------- ### Serialize and Deserialize Arguments with Ser Source: https://context7.com/sleitnick/rbxutil/llms.txt Use Ser.SerializeArgs and Ser.DeserializeArgs to pass custom objects through RemoteEvents. Supports immediate values, Option types, and custom registered classes. ```lua local Ser = require(Packages.Ser) local Option = require(Packages.Option) -- Serialize arguments (useful before RemoteEvent:FireServer) local opt = Option.Some(42) local serializedArgs = Ser.SerializeArgs(opt, "hello", 123) -- Deserialize arguments (useful when receiving from RemoteEvent) local deserializedArgs = Ser.DeserializeArgs(table.unpack(serializedArgs)) -- Serialize and unpack in one call local a, b, c = Ser.SerializeArgsAndUnpack(opt, "hello", 123) -- Deserialize and unpack in one call local opt2, str, num = Ser.DeserializeArgsAndUnpack(serializedData, stringData, numData) ``` ```lua -- Serialize single value local serialized = Ser.Serialize(opt) -- Deserialize single value local deserialized = Ser.Deserialize(serialized) ``` ```lua -- Add custom class serialization local MyClass = {ClassName = "MyClass"} function MyClass.new(value) return setmetatable({Value = value, ClassName = "MyClass"}, {__index = MyClass}) end function MyClass:Serialize() return {ClassName = "MyClass", Value = self.Value} end function MyClass.Deserialize(data) return MyClass.new(data.Value) end -- Register custom class with Ser Ser.Classes.MyClass = { Serialize = function(obj) return obj:Serialize() end, Deserialize = MyClass.Deserialize, } -- Now MyClass instances auto-serialize through RemoteEvents local myObj = MyClass.new(100) local serialized = Ser.Serialize(myObj) local restored = Ser.Deserialize(serialized) ``` -------------------------------- ### Manage Application State with Silo Source: https://context7.com/sleitnick/rbxutil/llms.txt Silo provides a Redux-inspired state container with support for immutable updates, subscriptions, and state composition. ```lua local Silo = require(Packages.Silo) -- Create a silo with initial state and modifiers local playerSilo = Silo.new({ -- Initial state Coins = 0, Level = 1, Experience = 0, }, { -- Modifiers (state mutation functions) AddCoins = function(state, amount) state.Coins += amount end, SetLevel = function(state, level) state.Level = level end, AddExperience = function(state, xp) state.Experience += xp if state.Experience >= state.Level * 100 then state.Level += 1 state.Experience = 0 end end, }) -- Dispatch actions to modify state playerSilo:Dispatch(playerSilo.Actions.AddCoins(50)) playerSilo:Dispatch(playerSilo.Actions.AddExperience(150)) -- Get current state local state = playerSilo:GetState() print("Coins:", state.Coins, "Level:", state.Level) -- Subscribe to all state changes local unsubscribe = playerSilo:Subscribe(function(newState, oldState) print("State changed!") print("Coins:", oldState.Coins, "->", newState.Coins) end) -- Watch specific values with selector local function selectCoins(state) return state.Coins end local unwatchCoins = playerSilo:Watch(selectCoins, function(coins) print("Coins changed to:", coins) end) -- Reset to default state playerSilo:ResetToDefaultState() -- Combine multiple silos local inventorySilo = Silo.new({Items = {}}, { AddItem = function(state, item) table.insert(state.Items, item) end, }) local gameSilo = Silo.combine({ Player = playerSilo, Inventory = inventorySilo, }) -- Access combined state local fullState = gameSilo:GetState() print("Player coins:", fullState.Player.Coins) print("Items:", #fullState.Inventory.Items) -- Dispatch with combined silo (uses original action names) gameSilo:Dispatch(gameSilo.Actions.AddCoins(100)) gameSilo:Dispatch(gameSilo.Actions.AddItem("Sword")) -- Unsubscribe when done unsubscribe() unwatchCoins() ``` -------------------------------- ### Handle Gamepad Input Events Source: https://context7.com/sleitnick/rbxutil/llms.txt Connects to gamepad button and thumbstick events, and allows checking if a button is currently held. Remember to call :Destroy() when finished. ```lua local Input = require(Packages.Input) local Gamepad = Input.Gamepad -- Gamepad input local gamepad = Gamepad.new() gamepad.ButtonDown:Connect(function(button) print("Button pressed:", button.Name) end) gamepad.ButtonUp:Connect(function(button) print("Button released:", button.Name) end) gamepad:IsButtonDown(Enum.KeyCode.ButtonA) gamepad:GetThumbstick(Enum.KeyCode.Thumbstick1) -- Returns Vector2 ``` -------------------------------- ### Destroy Shake Instance Source: https://context7.com/sleitnick/rbxutil/llms.txt Cleans up and destroys a shake instance to prevent memory leaks. Requires `Packages.Shake`. ```lua local Shake = require(Packages.Shake) -- Clean up cameraShake:Destroy() ``` -------------------------------- ### Load ModuleScripts with Loader Source: https://context7.com/sleitnick/rbxutil/llms.txt Use Loader.LoadChildren and Loader.LoadDescendants to load ModuleScripts from a given parent. Supports filtering with predicates and name matching. ```lua local Loader = require(Packages.Loader) -- Load all child ModuleScripts local modules = Loader.LoadChildren(ReplicatedStorage.Modules) for name, module in pairs(modules) do print("Loaded:", name) end -- Load all descendant ModuleScripts local allModules = Loader.LoadDescendants(ReplicatedStorage.Modules) -- Load with predicate filter local services = Loader.LoadDescendants(ServerScriptService.Services, function(moduleScript) return moduleScript.Name:match("Service$") ~= nil end) -- Use built-in name matcher local controllers = Loader.LoadChildren( ReplicatedStorage.Controllers, Loader.MatchesName("Controller$") ) ``` ```lua -- Spawn a method on all loaded modules Loader.SpawnAll(services, "OnStart") -- Complete initialization pattern local Services = Loader.LoadDescendants( ServerScriptService.Services, Loader.MatchesName("Service$") ) Loader.SpawnAll(Services, "OnInit") -- Initialize all services Loader.SpawnAll(Services, "OnStart") -- Start all services ``` -------------------------------- ### Detect Preferred Input Type Source: https://context7.com/sleitnick/rbxutil/llms.txt Automatically detects the user's preferred input method (Keyboard/Mouse, Gamepad, or Touch) and fires an event when it changes. This is useful for adapting UI or controls. ```lua local Input = require(Packages.Input) local PreferredInput = Input.PreferredInput -- Preferred input detection (auto-switches based on last used) local preferred = PreferredInput.new() preferred.Changed:Connect(function(inputType) if inputType == PreferredInput.InputType.Keyboard then print("Using keyboard/mouse") elseif inputType == PreferredInput.InputType.Gamepad then print("Using gamepad") elseif inputType == PreferredInput.InputType.Touch then print("Using touch") end end) ``` -------------------------------- ### TableUtil: JSON Encoding and Decoding Source: https://context7.com/sleitnick/rbxutil/llms.txt Encode a Lua table into a JSON string. Decode a JSON string back into a Lua table. ```lua -- JSON encoding/decoding local json = TableUtil.EncodeJSON({key = "value"}) local decoded = TableUtil.DecodeJSON(json) ``` -------------------------------- ### Manage Object Lifecycles with Trove Source: https://context7.com/sleitnick/rbxutil/llms.txt Trove tracks and cleans up instances, connections, threads, and promises. It supports sub-troves and automatic cleanup via instance destruction. ```lua local Trove = require(Packages.Trove) -- Create a new trove local trove = Trove.new() -- Add an instance to the trove (will be destroyed when trove is cleaned) local part = trove:Add(Instance.new("Part")) part.Parent = workspace -- Clone an instance and add to trove local clonedPart = trove:Clone(somePart) clonedPart.Parent = workspace -- Construct an object and add to trove local signal = trove:Construct(Signal) -- Connect to a signal and auto-track the connection trove:Connect(workspace.ChildAdded, function(child) print(child.Name .. " added") end) -- Add a cleanup function trove:Add(function() print("Cleanup function called!") end) -- Add a thread to the trove (will be cancelled on cleanup) local thread = trove:Add(task.spawn(function() while true do task.wait(1) print("Running...") end end)) -- Bind to RenderStep (auto-unbinds on cleanup) trove:BindToRenderStep("MyRender", Enum.RenderPriority.Last.Value, function(dt) -- Update something end) -- Add a promise to the trove (will be cancelled on cleanup) trove:AddPromise(somePromise):andThen(function() print("Promise resolved") end) -- Create a sub-trove (cleaned up when parent trove is cleaned) local subTrove = trove:Extend() -- Attach trove to an instance (auto-cleans when instance is destroyed) trove:AttachToInstance(somePart) -- Remove an object from the trove and clean it up trove:Remove(part) -- Remove without cleaning up trove:Pop(signal) -- Clean up all tracked objects trove:Clean() -- Destroy is an alias for Clean trove:Destroy() ``` -------------------------------- ### TableUtil: Reducing Table to a Single Value Source: https://context7.com/sleitnick/rbxutil/llms.txt Reduce a table to a single accumulated value by applying a function iteratively. An initial accumulator value can be provided. ```lua -- Reduce to single value local sum = TableUtil.Reduce(numbers, function(acc, n) return acc + n end, 0) -- Result: 15 ``` -------------------------------- ### Sustained Shake and Stop Source: https://context7.com/sleitnick/rbxutil/llms.txt Creates a shake effect that sustains indefinitely until explicitly stopped, triggering a fade-out. Requires `Packages.Shake`. ```lua local Shake = require(Packages.Shake) -- Sustained shake (for continuous effects) local sustainedShake = Shake.new() sustainedShake.Sustain = true sustainedShake:Start() -- Later, stop the sustained shake sustainedShake:StopSustain() -- Triggers fade-out ``` -------------------------------- ### Create Unique Identifiers with Symbol Source: https://context7.com/sleitnick/rbxutil/llms.txt Generates unique identifiers that can be used as table keys to prevent collisions. Symbols are guaranteed to be unique, even if created with the same string. ```lua local Symbol = require(Packages.Symbol) -- Create a symbol local MY_KEY = Symbol("MyKey") local PRIVATE_DATA = Symbol("PrivateData") -- Symbols are always unique print(Symbol("Test") == Symbol("Test")) --> false print(MY_KEY == MY_KEY) --> true -- Use as table keys local object = { Name = "Public Name", [PRIVATE_DATA] = { secret = "hidden value", }, } -- Only accessible with the symbol print(object.Name) --> "Public Name" print(object[PRIVATE_DATA].secret) --> "hidden value" -- Symbols can be nameless local UNNAMED = Symbol() print(tostring(UNNAMED)) --> "Symbol()" print(tostring(MY_KEY)) --> "Symbol(MyKey)" -- Common pattern: module-private keys local INTERNAL_STATE = Symbol("InternalState") local MyClass = {} MyClass.__index = MyClass function MyClass.new() return setmetatable({ [INTERNAL_STATE] = { initialized = true, data = {}, }, }, MyClass) end ``` -------------------------------- ### Bind Shake to a Signal Source: https://context7.com/sleitnick/rbxutil/llms.txt Binds a shake effect to a signal, such as `RunService.Heartbeat`, to apply shake updates. Requires `Packages.Shake`. ```lua local Shake = require(Packages.Shake) local RunService = game:GetService("RunService") local cameraShake = Shake.new() -- ... configuration ... -- Or bind to a signal cameraShake:OnSignal(RunService.Heartbeat, function(pos, rot, isDone) -- Apply shake end) ``` -------------------------------- ### Update Shake Manually Source: https://context7.com/sleitnick/rbxutil/llms.txt Manually updates the shake effect within a loop, such as `RunService.Heartbeat`, and applies the resulting position and rotation. Requires `Packages.Shake`. ```lua local Shake = require(Packages.Shake) local RunService = game:GetService("RunService") local cameraShake = Shake.new() -- ... configuration ... -- Or update manually RunService.Heartbeat:Connect(function() local pos, rot, isDone = cameraShake:Update() if not isDone then -- Apply pos and rot end end) ``` -------------------------------- ### TableUtil: Flattening Nested Arrays Source: https://context7.com/sleitnick/rbxutil/llms.txt Flatten a nested array into a single-level array. Handles arbitrarily deep nesting. ```lua -- Flatten nested arrays local nested = {{1, 2}, {3, 4}, {5, 6}} local flat = TableUtil.Flat(nested) -- Result: {1, 2, 3, 4, 5, 6} ``` -------------------------------- ### TableUtil: Deep Table Locking (Read-Only) Source: https://context7.com/sleitnick/rbxutil/llms.txt Deeply freezes a table, making it read-only. Any attempt to modify nested tables or their properties will result in an error. ```lua -- Lock table (deep freeze) local config = TableUtil.Lock({setting = {value = 1}}) -- config.setting.value = 2 -- Error: cannot modify readonly table ``` -------------------------------- ### TableUtil: O(1) Array Element Removal Source: https://context7.com/sleitnick/rbxutil/llms.txt Remove an element from an array in constant time by swapping it with the last element and then removing the last element. Note: This changes the order of the array. ```lua -- O(1) removal (swaps with last element) local arr = {"A", "B", "C", "D"} TableUtil.SwapRemove(arr, 2) -- {"A", "D", "C"} ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.