Historical 0.6.0 guide
Riptide is a lightweight, strictly-typed, and modular Roblox framework. It features phased initialization, safe dependency injection, a robust unified networking layer, and a shared ComponentService for managing tagged instances.
📦 Installation
Section titled “📦 Installation”Via Pesde (recommended)
Section titled “Via Pesde (recommended)”Add Riptide to your pesde.toml dependencies:
[dependencies]Riptide = { name = "riptide/core", version = "^0.6.0", target = "roblox" }Then install dependencies:
pesde installManual
Section titled “Manual”Download Riptide.rbxm from the v0.6.0 release and insert it as ReplicatedStorage/Packages/Riptide.
🏁 How to Start
Section titled “🏁 How to Start”Riptide does not start automatically. You must launch the framework from your own Server and Client entry points.
Server Initialization (main.server.lua)
Section titled “Server Initialization (main.server.lua)”local Riptide = require(ReplicatedStorage.Packages.Riptide)local MyServerModules = ServerScriptService:WaitForChild("MyServerModules")local MySharedModules = ReplicatedStorage:WaitForChild("SharedModules")local MyComponents = ReplicatedStorage:WaitForChild("Components") -- optional
Riptide.Server.Launch({ ModulesFolder = MyServerModules, -- Folder or { Folder, ... } SharedModulesFolder = MySharedModules, -- optional: Folder or { Folder, ... } ComponentsFolder = MyComponents, -- optional})Client Initialization (main.client.lua)
Section titled “Client Initialization (main.client.lua)”local Riptide = require(ReplicatedStorage.Packages.Riptide)local MyClientModules = ReplicatedStorage:WaitForChild("MyClientModules")local MySharedModules = ReplicatedStorage:WaitForChild("SharedModules")local MyComponents = ReplicatedStorage:WaitForChild("Components") -- optional
Riptide.Client.Launch({ ModulesFolder = { MyClientModules }, -- Folder or { Folder, ... } SharedModulesFolder = { MySharedModules }, -- optional: Folder or { Folder, ... } ComponentsFolder = MyComponents, -- optional})🚀 Module Lifecycle & Dependency Injection (DI)
Section titled “🚀 Module Lifecycle & Dependency Injection (DI)”Riptide completely eliminates the need for require() circles. Any ModuleScript inside your designated ModulesFolder will be automatically loaded into the Riptide Registry.
[!NOTE] Services and Controllers are registered by canonical module ID (relative path from
ModulesFolder, e.g.Economy/PlayerData). Short names are still supported as aliases when unique.
If two modules share the same short name, Riptide marks that alias as ambiguous and requires full canonical path lookups.
Examples:
Riptide.GetService("Economy/PlayerData")✅ always deterministicRiptide.GetService("PlayerData")✅ only if alias is uniqueRiptide.GetService("Data")⚠️ returnsnilwhen alias is ambiguous
Methods are executed in strict phases:
Init(Riptide): Called synchronously. Use this toGetServiceorGetControllerand set up your variables.Start(Riptide): Called asynchronously viatask.spawn. All modules are fully initialized at this point, so it is safe to interact with them and run game logic.
Example DI Module
Section titled “Example DI Module”--!strictlocal RiptidePkg = require(ReplicatedStorage.Packages.Riptide)type Riptide = RiptidePkg.Riptide
local PlayerState = {}
function PlayerState:Init(Riptide: Riptide) -- Easily inject other modules self.DataService = Riptide.GetService("DataService")
-- Listen to the unified Network layer Riptide.Network.Register("PlayerJumped", function(player, height) print(player.Name .. " jumped " .. height .. " studs!") end)end
function PlayerState:Start(Riptide: Riptide) self.DataService:GiveMoney(100)end
return PlayerState📡 Networking (Riptide.Network)
Section titled “📡 Networking (Riptide.Network)”Riptide automatically creates a single RemoteEvent and RemoteFunction inside its own package under the hood. No ReplicatedStorage clutter!
Network event dispatch uses a reusable trampoline handler in the hot-path to reduce closure allocations during heavy event traffic.
Client-Side API
Network.Register(name, callback): Listen for server events.Network.Unregister(name, callback): Remove a previously registered handler.Network.FireServer(name, ...): Send event data to the server.Network.InvokeServer(name, ...): Request data from the server.
Server-Side API
Network.Register(name, callback): Listen for client events. Callback automatically receivesplayeras the first argument.Network.Unregister(name, callback): Remove a previously registered handler.Network.FireClient(player, name, ...): Send event data to a specific player.Network.FireAllClients(name, ...): Broadcast event data to everyone.Network.InvokeClient(player, name, ...): Request data from a client.
🧩 ComponentService (Riptide.ComponentService)
Section titled “🧩 ComponentService (Riptide.ComponentService)”A shared (server & client) system for managing component objects linked to tagged Instances via CollectionService.
ComponentService startup is idempotent: repeated _start(...) calls are ignored to prevent duplicated CollectionService listeners.
Each Component is a ModuleScript whose name matches the tag. It must expose a new(instance) constructor and optionally a Destroy(self) cleanup method.
Example Component (Lava.lua)
Section titled “Example Component (Lava.lua)”local Lava = {}Lava.__index = Lava
function Lava.new(instance: BasePart) local self = setmetatable({ _instance = instance, _connection = nil :: RBXScriptConnection?, }, Lava)
self._connection = instance.Touched:Connect(function(hit) local humanoid = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if humanoid then (humanoid :: Humanoid):TakeDamage(10) end end)
return selfend
function Lava:Destroy() if self._connection then self._connection:Disconnect() self._connection = nil endend
return LavaAPI
ComponentService:Get(instance): Get the first component attached to an instance.ComponentService:Get(instance, tagName): Get a specific component by tag name.
📄 License
Section titled “📄 License”This project is licensed under the MIT License - see the LICENSE file for details.