{"id":"riptide/core","name":"core","scope":"riptide","platform":"roblox","description":"A strict Luau framework for Roblox with side-specific APIs, typed networking/state, module lifecycle orchestration, and sandboxed plugins.","version":"0.9.0-maelstrom.3","latest":"0.9.0-maelstrom.3","versions":["0.9.0-maelstrom.1","0.9.0-maelstrom.2","0.9.0-maelstrom.3"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"bb1b5429e479a403f9bfc0f4d775c724c615538f10dae8ad37dfd8205446ca1f","likes":0,"downloads":0,"install":"forest install riptide/core","url":"https://forest.dev/p/roblox/riptide/core","files":"https://api.forest.dev/ai/package/roblox/riptide/core/files","readme":"<div align=\"center\">\n\n<img src=\"https://github.com/riptide-project/framework/raw/maelstrom/assets/riptide_banner_v4.png\" alt=\"Riptide Banner\" width=\"100%\">\n\n<br/>\n\n<a href=\"https://github.com/riptide-project/framework\"><img src=\"https://raw.githubusercontent.com/maneetoo/Roblox-OSS-Badges/refs/heads/main/Badges/Community/GitHub/link-github-repository.svg\" alt=\"GitHub Repository\" height=\"28\"></a>\n<a href=\"https://riptide-project.github.io/framework\"><img src=\"https://raw.githubusercontent.com/maneetoo/Roblox-OSS-Badges/refs/heads/main/Badges/Roblox-Styled/Original/link-documentation.svg\" alt=\"Documentation\" height=\"28\"></a>\n<a href=\"https://github.com/riptide-project/framework/releases\"><img src=\"https://raw.githubusercontent.com/maneetoo/Roblox-OSS-Badges/refs/heads/main/Badges/Community/GitHub/link-github-releases.svg\" alt=\"GitHub Releases\" height=\"28\"></a>\n<a href=\"CHANGELOG.md\"><img src=\"https://raw.githubusercontent.com/maneetoo/Roblox-OSS-Badges/refs/heads/main/Badges/Roblox-Styled/Original/link-changelog.svg\" alt=\"Changelog\" height=\"28\"></a>\n<a href=\"https://pesde.dev/packages/riptide/core\"><img src=\"https://raw.githubusercontent.com/maneetoo/Roblox-OSS-Badges/refs/heads/main/Badges/Community/Package/link-pesde.svg\" alt=\"Pesde Package\" height=\"28\"></a>\n<a href=\"https://wally.run/package/riptide/core\"><img src=\"https://raw.githubusercontent.com/maneetoo/Roblox-OSS-Badges/refs/heads/main/Badges/Community/Package/link-wally.svg\" alt=\"Wally Package\" height=\"28\"></a>\n<a href=\"https://github.com/riptide-project/framework/actions\"><img src=\"https://raw.githubusercontent.com/maneetoo/Roblox-OSS-Badges/refs/heads/main/Badges/Roblox-Styled/Original/link-tests.svg\" alt=\"Tests\" height=\"28\"></a>\n\n<br/>\n<br/>\n\nRiptide was built from the ground up for production Roblox games. It solves the most common architecture problems while remaining invisible, staying out of your way, and scaling elegantly.\n\n</div>\n\n## 🌊 Maelstrom-3 preview\n\nVersion `0.9.0-maelstrom.3` is the latest preview release. `0.8.2` remains the latest stable release. Follow the [Maelstrom-3 guide](https://riptide-project.github.io/framework/versions/0.9.0-maelstrom.3/guides/getting-started/) to get started.\n\n---\n\n## ✨ Key Features\n\n- 📅 **Deterministic Lifecycle:** Phased initialization (`Load` → `Init` → `Start`) ensures modules and plugins load in a predictable, race-free order.\n- 🔌 **Framework-Layer Plugins:** Sandboxed plugins load before game modules, reach bounded `Start` readiness before gameplay starts, support dependency ordering, and stay isolated so third-party failures cannot bring down the framework.\n- ⚡ **Independent Signals:** Typed events with constant-time disconnect; callbacks run in reusable threads so a yielding or failing listener does not block the others.\n- 📡 **Unified Networking:** Multiplexed `RemoteEvent` and `UnreliableRemoteEvent` networking with flat, closure-free middleware chains.\n- 🛡️ **Typed Remote Validation:** Enforce client payload types at the network boundary via `Riptide.Network.RegisterTyped()` in server modules and composable `Guard` validators.\n- 📦 **100% Strict Luau:** Written entirely with `--!strict`, exporting clean API interfaces for full autocomplete and type-checking.\n- 🛠️ **Built-in Power:** Ships with Sleitnick's `Trove` resource tracker, `EventBus` pub/sub, `Guard` schema validators, `StateMachine`, `Async` utilities, and server-authoritative `State` replication.\n\n---\n\n## 📦 Installation\n\nInstall the Maelstrom-3 preview with either package manager. For the stable release, use [0.8.2](https://riptide-project.github.io/framework/versions/0.8.2/guides/quickstart/).\n\n### Via Pesde (Recommended)\n\nIn your game folder, run `pesde init` and choose `roblox` and `pesde/scripts_rojo`. Then run:\n\n```bash\npesde add riptide/core@0.9.0-maelstrom.3 --alias Riptide\npesde install\n```\n\nResult: `pesde.toml` lists Riptide and the package is in `roblox_packages/Riptide`.\n\n### Via Wally\n\nRun `wally init` in your game folder. Add this line under `[dependencies]` in `wally.toml`:\n\n```toml\nRiptide = \"riptide/core@0.9.0-maelstrom.3\"\n```\n\nRun `wally install`. Result: Riptide is in `Packages/Riptide`.\n\n### Manual (.rbxm)\n\nDownload `Riptide.rbxm` from the [Maelstrom-3 release](https://github.com/riptide-project/framework/releases/tag/v0.9.0-maelstrom.3) and insert it as `ReplicatedStorage/Packages/Riptide`.\n\n---\n\n## 🏁 Quick Look\n\nRiptide organizes your game logic into **Services** (server) and **Controllers** (client). Each module follows a clean lifecycle: modules are loaded first, `Init` runs synchronously, and `Start` runs asynchronously afterward.\n\n```lua\n-- ServerScriptService/Services/CoinsService.lua\n--!strict\nlocal CoinsService = {}\n\nfunction CoinsService:Init(Riptide)\n    -- Init runs synchronously. Register network handlers and grab\n    -- references to other services here — everything is loaded but\n    -- not yet started.\n    Riptide.Network.RegisterTyped(\"BuyItem\", {\n        Riptide.Guard.String(50),       -- itemId:  string, max 50 chars\n        Riptide.Guard.Number(0, 1000),  -- price:   number, 0–1000\n    }, function(player, itemId, price)\n        print(player.Name .. \" bought \" .. itemId .. \" for \" .. price .. \" coins\")\n    end)\nend\n\nfunction CoinsService:Start(Riptide)\n    -- Start runs in its own coroutine — safe to yield here.\n    self.Trove = Riptide.Trove.new()\n    print(\"CoinsService is running!\")\nend\n\nfunction CoinsService:OnPlayerAdded(Riptide, player)\n    Riptide.State:SetForPlayer(player, \"coins\", 0)\nend\n\nreturn CoinsService\n```\n\n**Launch the server** from a server script:\n\n```lua\n-- ServerScriptService/main.server.lua\nlocal ReplicatedStorage  = game:GetService(\"ReplicatedStorage\")\nlocal ServerScriptService = game:GetService(\"ServerScriptService\")\nlocal Riptide = require(ReplicatedStorage.Packages.Riptide).Server\n\nRiptide.Launch({\n    ModulesFolder = ServerScriptService.Services,\n})\n```\n\n**Launch the client** from a LocalScript:\n\n```lua\n-- StarterPlayerScripts/main.client.lua\nlocal ReplicatedStorage = game:GetService(\"ReplicatedStorage\")\nlocal Players = game:GetService(\"Players\")\nlocal Riptide = require(ReplicatedStorage.Packages.Riptide).Client\n\nRiptide.Launch({\n    ModulesFolder = Players.LocalPlayer.PlayerScripts.Controllers,\n})\n```\n\n---\n\n## 📚 Documentation\n\nComplete setup guides, API reference, and examples:\n\n**[👉 Riptide Documentation](https://riptide-project.github.io/framework)**\n\n---\n\n## 📄 License\n\nMIT — see [LICENSE](LICENSE).\n","readmeTruncated":false}