{"id":"toriumslurs/jolt","name":"jolt","scope":"toriumslurs","platform":"roblox","description":"High-performance binary networking library for Roblox.","version":"4.0.0","latest":"4.0.0","versions":["4.0.0"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"fa66156ffe28ba7d3e11c50b841e369db30778dbb4a377d430802a8f985b1543","likes":0,"downloads":0,"install":"forest install toriumslurs/jolt","url":"https://forest.dev/p/roblox/toriumslurs/jolt","files":"https://api.forest.dev/ai/package/roblox/toriumslurs/jolt/files","readme":"# Jolt\n\nHigh-performance binary networking library for Roblox.\n\n---\n\n## Overview\n\nJolt is a strictly typed, buffer-serialized networking framework designed as a high-throughput replacement for standard `RemoteEvent`, `UnreliableRemoteEvent`, and `RemoteFunction` instances.\n\nIt utilizes 16-bit FNV-1a channel hashing, packed binary buffers, doubly-linked signal dispatching with object pooling, and per-frame batched transmission to minimize network bandwidth, serialization overhead, and garbage collection pressure.\n\n---\n\n## Key Capabilities\n\n* **Hash-Based Wire Addressing**: Channel identifiers are hashed to 16-bit unsigned integers, replacing repetitive string names in packet headers and cutting wire framing overhead by up to 90%.\n* **High-Throughput Binary Serialization**: Custom buffer encoding supporting 63+ data formats, including half-precision floats (`Float16`), 24-bit floats, 24-bit integers, 8-booleans-per-byte bitpacking, homogeneous typed arrays, and columnar struct array compression.\n* **Zero-GC Object Pooling**: Reusable connection node and buffer pools eliminate memory allocations on frequent event disconnections and buffer writes.\n* **Frame-Synchronized Batching**: Network packets are batched in memory and dispatched once per engine frame directly on `RunService.Heartbeat`.\n* **Zero-Trust Security Layer**: Built-in validation enforcing buffer size ceilings (256 KB), parameter count limits (64), pending request caps (128), and recursion depth limits (16).\n* **Strict Type Safety**: Fully typed in Luau (`--!strict`, `--!native`, `--!optimize 2`) with support for generic argument and return parameter annotations.\n\n---\n\n## Installation\n\nPlace the `Jolt` module folder inside `ReplicatedStorage` (or your shared dependency directory).\n\n```lua\nlocal Jolt = require(game:GetService(\"ReplicatedStorage\").Jolt)\n```\n\n---\n\n## API Reference\n\n### Server API (`Jolt.Server`)\n\nCreates or retrieves a server-side network channel.\n\n```lua\nlocal channel = Jolt.Server(channelName: string): Server<Args..., Out...>\n```\n\n#### Methods\n\n* **`channel:Fire(player: Player, ...args: any)`**\n  Sends a reliable event to a specific player.\n* **`channel:FireUnreliable(player: Player, ...args: any)`**\n  Sends an unreliable event to a specific player.\n* **`channel:FireAll(...args: any)`**\n  Broadcasts a reliable event to all connected players.\n* **`channel:FireAllUnreliable(...args: any)`**\n  Broadcasts an unreliable event to all connected players.\n* **`channel:FireExcept(exceptPlayer: Player, ...args: any)`**\n  Broadcasts a reliable event to all connected players except the specified player.\n* **`channel:FireList(players: { Player }, ...args: any)`**\n  Broadcasts a reliable event to an array of target players using optimized buffer cloning.\n* **`channel:Invoke(player: Player, ...args: any): Out...`**\n  Invokes a client and yields until the client returns a response or the 30-second timeout expires.\n* **`channel:Connect(callback: (player: Player, Args...) -> ()): Connection`**\n  Listens for reliable and unreliable client-to-server events. Returns a `Connection` object.\n* **`channel:Once(callback: (player: Player, Args...) -> ()): Connection`**\n  Listens for the next event only, then automatically disconnects.\n* **`channel:Wait(): (Player, Args...)`**\n  Yields the calling thread until the next event is received.\n* **`channel:Destroy()`**\n  Tears down the channel, unregisters it from the active channel table, destroys all signal connections, and cancels pending request timers.\n\n#### Callbacks\n\n* **`channel.OnInvoke = function(player: Player, ...args: any): Out...`**\n  Defines the handler for incoming client-to-server invocations.\n\n---\n\n### Client API (`Jolt.Client`)\n\nCreates or retrieves a client-side network channel.\n\n```lua\nlocal channel = Jolt.Client(channelName: string): Client<Args..., Out...>\n```\n\n#### Methods\n\n* **`channel:Fire(...args: any)`**\n  Sends a reliable event to the server.\n* **`channel:FireUnreliable(...args: any)`**\n  Sends an unreliable event to the server.\n* **`channel:Invoke(...args: any): Out...`**\n  Invokes the server and yields until a response is returned or the 30-second timeout expires.\n* **`channel:Connect(callback: (Args...) -> ()): Connection`**\n  Listens for server-to-client events. Returns a `Connection` object.\n* **`channel:Once(callback: (Args...) -> ()): Connection`**\n  Listens for the next event only, then automatically disconnects.\n* **`channel:Wait(): Args...`**\n  Yields the calling thread until the next event is received.\n* **`channel:Destroy()`**\n  Tears down the channel, unregisters it, destroys its signal listeners, and cancels pending request timers.\n\n#### Callbacks\n\n* **`channel.OnInvoke = function(...args: any): Out...`**\n  Defines the handler for incoming server-to-client invocations.\n\n---\n\n### Connection Object\n\nReturned by `:Connect()` and `:Once()`.\n\n* **`connection:Disconnect()`**\n  Disconnects the listener and returns the internal node to the object pool.\n* **`connection.Connected: boolean`**\n  Indicates whether the connection is currently active.\n\n---\n\n## Code Examples\n\n### 1. Basic Events\n\n#### Server\n```lua\nlocal ReplicatedStorage = game:GetService(\"ReplicatedStorage\")\nlocal Jolt = require(ReplicatedStorage.Jolt)\n\nlocal CombatEvent = Jolt.Server(\"CombatEvent\")\n\n-- Listen for client attacks\nCombatEvent:Connect(function(player, targetId, attackType)\n    print(`{player.Name} attacked {targetId} with {attackType}`)\n    \n    -- Notify all other players\n    CombatEvent:FireExcept(player, targetId, attackType)\nend)\n```\n\n#### Client\n```lua\nlocal ReplicatedStorage = game:GetService(\"ReplicatedStorage\")\nlocal Jolt = require(ReplicatedStorage.Jolt)\n\nlocal CombatEvent = Jolt.Client(\"CombatEvent\")\n\n-- Listen for other players' attacks\nCombatEvent:Connect(function(targetId, attackType)\n    print(`Received attack animation trigger: {targetId} ({attackType})`)\nend)\n\n-- Send attack to server\nCombatEvent:Fire(\"Enemy_123\", \"Slash\")\n```\n\n---\n\n### 2. Two-Way Invocations\n\n#### Server\n```lua\nlocal ReplicatedStorage = game:GetService(\"ReplicatedStorage\")\nlocal Jolt = require(ReplicatedStorage.Jolt)\n\nlocal InventoryService = Jolt.Server(\"InventoryService\")\n\nInventoryService.OnInvoke = function(player, itemId, amount)\n    if typeof(itemId) ~= \"string\" or typeof(amount) ~= \"number\" then\n        error(\"Invalid arguments\")\n    end\n    \n    local success = true\n    local remainingBalance = 150\n    return success, remainingBalance\nend\n```\n\n#### Client\n```lua\nlocal ReplicatedStorage = game:GetService(\"ReplicatedStorage\")\nlocal Jolt = require(ReplicatedStorage.Jolt)\n\nlocal InventoryService = Jolt.Client(\"InventoryService\")\n\nlocal success, balance = InventoryService:Invoke(\"Potion_Health\", 2)\nprint(\"Purchase result:\", success, \"New balance:\", balance)\n```\n\n---\n\n### 3. Strictly Typed Generic Channels\n\nYou can supply generic type parameters for compile-time type validation in Luau:\n\n```lua\n-- Define parameter types\ntype PositionPayload = {\n    entityId: number,\n    position: Vector3,\n    velocity: Vector3,\n}\n\n-- Server\nlocal PositionChannel = Jolt.Server(\"EntityPositions\") :: Jolt.Server<PositionPayload>\nPositionChannel:FireAll({\n    entityId = 1,\n    position = Vector3.new(0, 5, 0),\n    velocity = Vector3.zero,\n})\n\n-- Client\nlocal PositionChannel = Jolt.Client(\"EntityPositions\") :: Jolt.Client<PositionPayload>\nPositionChannel:Connect(function(payload)\n    print(payload.entityId, payload.position)\nend)\n```\n\n---\n\n## Supported Serialization Types\n\nJolt serializes the following data types natively through its buffer pipeline:\n\n| Category | Supported Types |\n|---|---|\n| **Primitives** | `nil`, `boolean` (individual & bitpacked), `number` (Float16, Float24, Float32, Float64, Int8, Int16, Int24, Int32, Uint8, Uint16, Uint24, Uint32), `string` (8-bit, 16-bit, and variable LEB128 lengths), `buffer` |\n| **Vectors & Spatial** | `Vector2`, `Vector2` (Float16), `Vector2int16`, `Vector3`, `Vector3` (Float16), `Vector3int16`, `CFrame` (full), `CFrame` (position-only), `CFrame` (position + 1-byte yaw angle), `Ray`, `Rect`, `Region3`, `Region3int16` |\n| **Roblox Objects** | `Instance`, `EnumItem` (cached reverse lookups), `BrickColor`, `Color3`, `ColorSequence`, `ColorSequenceKeypoint`, `NumberRange`, `NumberSequence`, `NumberSequenceKeypoint`, `DateTime`, `TweenInfo`, `UDim`, `UDim2` |\n| **Collections** | `Array` (generic), `Map` (generic), `StructArray` (columnar schema compression), and typed homogeneous arrays (`i8`, `i16`, `i32`, `u8`, `u16`, `u32`, `f32`, `f64`, `bool`, `string`, `Vector2`, `Vector3`, `Color3`, `CFrame`) |\n\n---\n\n## System Boundaries and Security Limits\n\n| Boundary | Value | Behavior on Violation |\n|---|---|---|\n| **Maximum Raw Buffer Size** | 256 KB (`262,144` bytes) | Payload dropped immediately |\n| **Maximum Packet Arguments** | 64 parameters | Reading breaks; surplus arguments ignored |\n| **Maximum Concurrent Requests** | 128 pending invokes per target | Invocations immediately throw error |\n| **Maximum Serialization Depth** | 16 nested levels | Traversal aborts to prevent stack overflow |\n| **Request Timeout** | 30 seconds | Yielding thread resumed with `\"Request timed out\"` |\n| **Instance Packet Limit** | 256 instances per payload | Array capped and non-Instance elements stripped |\n\n---\n\n## Performance Guidelines\n\n1. **Unreliable Streams for High-Frequency State**: Use `:FireUnreliable()` and `:FireAllUnreliable()` for positions, physics snapshots, and transient visual effects.\n2. **Channel Naming**: Channel names are hashed at startup and cached. Choose clear, descriptive names without worrying about wire overhead.\n3. **Structured Entity Arrays**: When transmitting lists of uniform tables (e.g. `{ { id = 1, x = 0, y = 0 }, ... }`), Jolt automatically utilizes columnar compression (`TAG_ARR_STRUCT`) to serialize keys only once.\n4. **Lifecycle Cleanup**: Call `:Destroy()` when dynamically allocated channels are no longer needed to release signal nodes and cancel active timers.\n\n---\n\n## License\n\nThis project is licensed under the MIT License. See [LICENSE](LICENSE) for details.\n","readmeTruncated":false}