Getting Started
Welcome to Riptide! This guide walks you through every step β from installation to your first working Service and Controller β with no prior framework experience required.
1. Installation
Section titled β1. InstallationβVia Pesde (Recommended)
Section titled βVia Pesde (Recommended)βPesde is the recommended Luau package manager. Install it by following the Pesde docs, then run:
pesde add riptide/corePesde places Riptide inside luau_packages/. You reference it from your Rojo project as a Packages folder in ReplicatedStorage.
Via Wally
Section titled βVia Wallyβ[dependencies]Riptide = "riptide/core@0.9.0-maelstrom.2"Manual Installation (.rbxm)
Section titled βManual Installation (.rbxm)βDownload Riptide.rbxm from the latest release and drop it into ReplicatedStorage/Packages/.
2. Rojo Project Setup
Section titled β2. Rojo Project SetupβRojo syncs your local code files into Roblox Studio. Create a default.project.json at the root of your project:
{ "name": "my-riptide-game", "tree": { "$className": "DataModel", "ReplicatedStorage": { "$className": "ReplicatedStorage", "Packages": { "$path": "luau_packages" }, "SharedModules": { "$path": "src/shared" } }, "ServerScriptService": { "$className": "ServerScriptService", "main": { "$path": "src/server/main.server.lua" }, "Services": { "$path": "src/server/Services" } }, "StarterPlayer": { "$className": "StarterPlayer", "StarterPlayerScripts": { "$className": "StarterPlayerScripts", "main": { "$path": "src/client/main.client.lua" }, "Controllers": { "$path": "src/client/Controllers" } } } }}This produces the following hierarchy inside Roblox Studio:
ReplicatedStorage/βββ Packages/ β Riptide and other dependenciesβββ SharedModules/ β code used by both server and client
ServerScriptService/βββ main β server entry point (Script)βββ Services/ β server-only modules (Folder)
StarterPlayer/StarterPlayerScripts/βββ main β client entry point (LocalScript)βββ Controllers/ β client-only modules (Folder)Create the matching local folders:
src/βββ shared/ β SharedModulesβββ server/β βββ main.server.luaβ βββ Services/βββ client/ βββ main.client.lua βββ Controllers/3. Your First Service (Server)
Section titled β3. Your First Service (Server)βIn Riptide, server-side game logic lives in Services β plain Lua tables with special lifecycle methods.
Create src/server/Services/HelloService.lua:
-- src/server/Services/HelloService.lua--!strict
local HelloService = {}
--[[ Init(Riptide) β runs SYNCHRONOUSLY before any module starts. Use this phase to: β’ store references to other services β’ register network event handlers β’ set up initial state Do NOT yield here (no task.wait, no async calls).]]function HelloService:Init(Riptide) print("HelloService:Init β framework is setting up!")end
--[[ Start(Riptide) β runs ASYNCHRONOUSLY (via task.spawn) after ALL modules have finished Init. Use this phase to: β’ start game loops β’ connect to events β’ yield freely]]function HelloService:Start(Riptide) print("HelloService:Start β everything is ready!")end
--[[ OnPlayerAdded(Riptide, player) β called when a player joins. Also replays for players already in the server after module initialization and plugin readiness.]]function HelloService:OnPlayerAdded(Riptide, player) print("Welcome, " .. player.Name .. "!")end
--[[ OnPlayerRemoving(Riptide, player) β called when a player leaves. Use this to clean up player-specific data.]]function HelloService:OnPlayerRemoving(Riptide, player) print("Goodbye, " .. player.Name .. "!")end
return HelloService4. Your First Controller (Client)
Section titled β4. Your First Controller (Client)βClient-side logic lives in Controllers β same idea, different folder.
Create src/client/Controllers/HelloController.lua:
-- src/client/Controllers/HelloController.lua--!strict
local HelloController = {}
function HelloController:Init(Riptide) -- Listen for a network event fired by the server Riptide.Network.Register("ServerGreeting", function(message) print("Server says:", message) end)end
function HelloController:Start(Riptide) -- Tell the server we are ready Riptide.Network.FireServer("ClientReady") print("HelloController started on the client!")end
return HelloController5. Launch Entry Scripts
Section titled β5. Launch Entry ScriptsβRiptide does not start automatically. You must call Launch from both your server and client entry scripts.
Server Entry Point
Section titled βServer Entry PointβCreate src/server/main.server.lua:
-- src/server/main.server.lua--!strictlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local ServerScriptService = game:GetService("ServerScriptService")
-- Require Riptide from the Packages folderlocal Riptide = require(ReplicatedStorage.Packages.Riptide).Server
Riptide.Launch({ -- Required: the Folder containing your server Services ModulesFolder = ServerScriptService.Services,
-- Optional: shared modules loaded BEFORE Services SharedModulesFolder = ReplicatedStorage.SharedModules,})Client Entry Point
Section titled βClient Entry PointβCreate src/client/main.client.lua:
-- src/client/main.client.lua--!strictlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local Players = game:GetService("Players")
local Riptide = require(ReplicatedStorage.Packages.Riptide).Client
Riptide.Launch({ -- Required: the Folder containing your client Controllers ModulesFolder = Players.LocalPlayer.PlayerScripts.Controllers,
-- Optional: shared modules loaded BEFORE Controllers SharedModulesFolder = ReplicatedStorage.SharedModules,})6. Start Rojo & Play
Section titled β6. Start Rojo & Playβ- Run
rojo servein your terminal. - Connect via the Rojo Studio plugin.
- Press Play in Roblox Studio.
You should see this in the Output window:
π [Riptide] Server Initialization Started...HelloService:Init β framework is setting up!HelloService:Start β everything is ready!π [Riptide] β
Server Start Phase Dispatched.Welcome, Player1!And on the client:
π [Riptide] Client Initialization Started...HelloController started on the client!π [Riptide] β
Client Start Phase Dispatched.Congratulations β you have a working Riptide project! π
Next Steps
Section titled βNext Stepsβ- Project Structure β recommended folder layout for larger games.
- Module Lifecycle β understand the Load / Init / Start phases in depth.
- Network β fire events between server and client.
- State Replication β server-authoritative state synced to clients.
- Plugins β extend the framework with modular, sandboxed plugins.