{"id":"verifiedhawaii/raddish","name":"raddish","scope":"verifiedhawaii","platform":"roblox","description":"Redis-like in-memory cache and networking system for Roblox","version":"1.0.1","latest":"1.0.1","versions":["1.0.0","1.0.1"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"55fc693fc458248f811c5e6189aa32bbc06b2af5e2b0a355a715b5ec735a7d82","likes":0,"downloads":0,"install":"forest install verifiedhawaii/raddish","url":"https://forest.dev/p/roblox/verifiedhawaii/raddish","files":"https://api.forest.dev/ai/package/roblox/verifiedhawaii/raddish/files","readme":"<div align=\"center\">\r\n\r\n```\r\n╔═══════════════════════════════════════════════════════════════════════════╗\r\n║                                                                           ║\r\n║    ██████╗   █████╗ ██████╗ ██████╗ ██╗███████╗██╗  ██╗                   ║\r\n║    ██╔══██╗██╔══██╗██╔══██╗██╔══██╗██║██╔════╝██║  ██║                    ║\r\n║    ██████╔╝███████║██║  ██║██║  ██║██║███████╗███████║                    ║\r\n║    ██╔══██╗██╔══██║██║  ██║██║  ██║██║╚════██║██╔══██║                    ║\r\n║    ██║  ██║██║  ██║██████╔╝██████╔╝██║███████║██║  ██║                    ║\r\n║    ╚═╝  ╚═╝╚═╝  ╚═╝╚═════╝ ╚═════╝ ╚═╝╚══════╝╚═╝  ╚═╝                    ║\r\n║                                                                           ║\r\n║         Redis-like In-Memory Cache & Networking for Roblox                ║\r\n║                                                                           ║\r\n╚═══════════════════════════════════════════════════════════════════════════╝\r\n```\r\n\r\n**⚡ Lightning-fast in-memory caching** • **🔄 Cross-server events** • **🌐 External APIs**\r\n\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\r\n[![Roblox](https://img.shields.io/badge/Roblox-Ready-00A2FF?logo=roblox)](https://www.roblox.com/)\r\n[![Version](https://img.shields.io/badge/version-1.0.0-blue.svg)](https://github.com/VerifiedHawaii/Raddish/releases)\r\n[![Documentation](https://img.shields.io/badge/docs-hawaiian.gg-green.svg)](https://docs.hawaiian.gg/raddish/getting-started)\r\n\r\n[Features](#-features) • [Installation](#-installation) • [Quick Start](#-quick-start) • [Documentation](#-documentation) • [Contributing](#-contributing)\r\n\r\n</div>\r\n\r\n---\r\n\r\n## 🎯 What is Raddish?\r\n\r\nRaddish is a **Redis-like caching and networking system** built specifically for Roblox. It solves the biggest pain points of game development:\r\n\r\n- **DataStore is slow** (100-300ms per call) → Raddish caches everything in memory (<1ms)\r\n- **No cross-server communication** → Raddish provides Pub/Sub events\r\n- **External APIs are hard** → Raddish handles caching, retries, and rate limiting\r\n- **Complex data structures** → Raddish provides Hashes, Lists, Sets, and Sorted Sets\r\n\r\n### Why Raddish?\r\n\r\n| Traditional Approach | With Raddish | Improvement |\r\n|---------------------|--------------|-------------|\r\n| 100-300ms per DataStore call | <1ms from cache | **100-300x faster** |\r\n| No cross-server events | Real-time Pub/Sub | **New capability!** |\r\n| Manual API handling | Auto-caching & retry | **50-500x faster** |\r\n| Basic key-value only | Redis data structures | **More powerful** |\r\n\r\n## ✨ Features\r\n\r\n<table>\r\n<tr>\r\n<td width=\"50%\">\r\n\r\n### 🚀 Core Features\r\n- ⚡ **In-Memory Cache** - 100-1000x faster than DataStore\r\n- 🔄 **Pub/Sub Events** - Cross-server communication\r\n- 💾 **DataStore Bridge** - Auto-sync with persistence\r\n- 🛡️ **Rate Limiting** - Automatic protection\r\n- ⏰ **TTL Expiration** - Auto-cleanup of old data\r\n- 🧹 **LRU Eviction** - Smart memory management\r\n\r\n</td>\r\n<td width=\"50%\">\r\n\r\n### 📊 Data Structures\r\n- 🗃️ **Hashes** - Player data, configs\r\n- 📋 **Lists** - Queues, chat history\r\n- 🏷️ **Sets** - Tags, online players\r\n- 🏆 **Sorted Sets** - Leaderboards, rankings\r\n- 🔑 **Key-Value** - Simple caching\r\n- 🔍 **Pattern Matching** - Find keys with wildcards\r\n\r\n</td>\r\n</tr>\r\n<tr>\r\n<td width=\"50%\">\r\n\r\n### 🌐 Networking\r\n- 📡 **HTTP Methods** - GET, POST, PUT, DELETE, PATCH\r\n- 💬 **Discord Webhooks** - Easy integration\r\n- 🔁 **Retry Logic** - Exponential backoff\r\n- 📦 **Request Batching** - Efficient API calls\r\n- 🎯 **Response Caching** - Reduce API costs\r\n- 🔐 **Auth Support** - Bearer tokens, API keys\r\n\r\n</td>\r\n<td width=\"50%\">\r\n\r\n### 🎮 Game-Ready\r\n- 👥 **Player Management** - Session tracking\r\n- 🏅 **Leaderboards** - Real-time rankings\r\n- 💬 **Global Chat** - Cross-server messaging\r\n- 🎪 **Live Events** - Synchronized gameplay\r\n- 📊 **Analytics** - Track player behavior\r\n- 🔒 **Distributed Locks** - Prevent exploits\r\n\r\n</td>\r\n</tr>\r\n</table>\r\n\r\n## 📦 Installation\r\n\r\n\r\n### Manual Installation\r\n\r\n1. Download the latest release from [Releases](https://github.com/VerifiedHawaii/Raddish/releases)\r\n2. Extract the `Raddish` folder\r\n3. Place it in `ReplicatedStorage` or `ServerScriptService` in Roblox Studio\r\n\r\n### Verify Installation\r\n\r\n```lua\r\nlocal Raddish = require(game.ReplicatedStorage.Raddish)\r\nprint(\"Raddish loaded successfully!\")\r\n```\r\n\r\n## 🚀 Quick Start\r\n\r\n### Basic Usage\r\n\r\n```lua\r\nlocal Raddish = require(game.ReplicatedStorage.Raddish)\r\n\r\n-- Store data with auto-expiration\r\nRaddish.Set(\"player:123:health\", 100, 60) -- Expires in 60 seconds\r\n\r\n-- Get data (instant!)\r\nlocal health = Raddish.Get(\"player:123:health\")\r\nprint(health) -- 100\r\n\r\n-- Increment counter\r\nRaddish.Incr(\"visits\") -- 1\r\nRaddish.Incr(\"visits\") -- 2\r\n\r\n-- Check if key exists\r\nif Raddish.Exists(\"player:123:health\") then\r\n    print(\"Player is alive!\")\r\nend\r\n```\r\n\r\n### Player Data Management\r\n\r\n```lua\r\nlocal Raddish = require(game.ReplicatedStorage.Raddish)\r\n\r\ngame.Players.PlayerAdded:Connect(function(player)\r\n    -- Load player data (cached after first load)\r\n    local coins = Raddish.GetWithCache(player, \"Coins\", 0, 300)\r\n    local level = Raddish.GetWithCache(player, \"Level\", 1, 300)\r\n    \r\n    player:SetAttribute(\"Coins\", coins)\r\n    player:SetAttribute(\"Level\", level)\r\n    \r\n    print(player.Name, \"has\", coins, \"coins and is level\", level)\r\nend)\r\n\r\nfunction giveCoins(player, amount)\r\n    local newCoins = Raddish.IncrementWithCache(player, \"Coins\", amount, 0, 300)\r\n    player:SetAttribute(\"Coins\", newCoins)\r\n    return newCoins\r\nend\r\n\r\ngame.Players.PlayerRemoving:Connect(function(player)\r\n    -- Auto-save player data\r\n    Raddish.FlushPlayer(player)\r\nend)\r\n```\r\n\r\n### Global Leaderboard\r\n\r\n```lua\r\nlocal Raddish = require(game.ReplicatedStorage.Raddish)\r\n\r\n-- Add players to leaderboard\r\nRaddish.ZAdd(\"leaderboard:global\", 9999, \"VerifiedHawaii\")\r\nRaddish.ZAdd(\"leaderboard:global\", 5000, \"Player2\")\r\nRaddish.ZAdd(\"leaderboard:global\", 7500, \"Player3\")\r\n\r\n-- Get top 10 players\r\nlocal top10 = Raddish.ZRange(\"leaderboard:global\", 1, 10, true)\r\n\r\nfor i, entry in ipairs(top10) do\r\n    print(i, entry.member, entry.score)\r\nend\r\n\r\n-- Get player's rank\r\nlocal rank = Raddish.ZRank(\"leaderboard:global\", \"VerifiedHawaii\")\r\nprint(\"Rank:\", rank + 1)\r\n\r\n-- Update score\r\nRaddish.ZIncrBy(\"leaderboard:global\", 1000, \"Player2\")\r\n```\r\n\r\n### Cross-Server Events\r\n\r\n```lua\r\nlocal Raddish = require(game.ReplicatedStorage.Raddish)\r\n\r\n-- Subscribe to events (all servers)\r\nRaddish.Subscribe(\"global:announcement\", function(data)\r\n    print(\"Announcement:\", data.message)\r\n    \r\n    -- Show to all players on this server\r\n    for _, player in ipairs(game.Players:GetPlayers()) do\r\n        game.ReplicatedStorage.ShowAnnouncement:FireClient(player, data.message)\r\n    end\r\nend)\r\n\r\n-- Publish event (from any server, reaches all servers)\r\nRaddish.Publish(\"global:announcement\", {\r\n    message = \"Server maintenance in 10 minutes!\",\r\n    timestamp = os.time()\r\n})\r\n```\r\n\r\n### External API Integration\r\n\r\n```lua\r\nlocal Raddish = require(game.ReplicatedStorage.Raddish)\r\n\r\n-- Fetch data from your backend with caching\r\nlocal response = Raddish.HttpGet(\"https://api.yourgame.com/player/123\", {\r\n    cache = true,\r\n    cacheTTL = 300, -- Cache for 5 minutes\r\n    headers = {\r\n        [\"Authorization\"] = \"Bearer your-api-key\"\r\n    }\r\n})\r\n\r\nif response.Success then\r\n    print(\"Player level:\", response.Body.level)\r\nelse\r\n    warn(\"API error:\", response.StatusMessage)\r\nend\r\n```\r\n\r\n### Discord Webhooks\r\n\r\n```lua\r\nlocal Raddish = require(game.ReplicatedStorage.Raddish)\r\n\r\nlocal WEBHOOK_URL = \"https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN\"\r\n\r\n-- Rich embed\r\nRaddish.SendDiscordWebhook(WEBHOOK_URL, {\r\n    title = \"Player Achievement\",\r\n    description = \"VerifiedHawaii reached level 100!\",\r\n    color = 0x00FF00, -- Green\r\n    fields = {\r\n        {name = \"Player\", value = \"VerifiedHawaii\", inline = true},\r\n        {name = \"Level\", value = \"100\", inline = true},\r\n        {name = \"Time Played\", value = \"50 hours\", inline = true}\r\n    },\r\n    footer = {text = \"Achievement System\"},\r\n    username = \"Achievement Bot\"\r\n})\r\n```\r\n\r\n### Player Profile with Hashes\r\n\r\n```lua\r\nlocal Raddish = require(game.ReplicatedStorage.Raddish)\r\n\r\n-- Store player profile data\r\nRaddish.HSet(\"player:123\", \"name\", \"VerifiedHawaii\")\r\nRaddish.HSet(\"player:123\", \"level\", 50)\r\nRaddish.HSet(\"player:123\", \"gold\", 1000)\r\nRaddish.HSet(\"player:123\", \"vip\", true)\r\n\r\n-- Get specific field\r\nlocal name = Raddish.HGet(\"player:123\", \"name\")\r\nprint(name) -- \"VerifiedHawaii\"\r\n\r\n-- Get all fields\r\nlocal profile = Raddish.HGetAll(\"player:123\")\r\nprint(profile)\r\n-- {name = \"VerifiedHawaii\", level = 50, gold = 1000, vip = true}\r\n\r\n-- Check if field exists\r\nif Raddish.HExists(\"player:123\", \"vip\") then\r\n    print(\"Player is VIP!\")\r\nend\r\n```\r\n\r\n## 📚 Documentation\r\n\r\n### Full Documentation\r\n👉 **[docs.hawaiian.gg/raddish/getting-started](https://hawaiian.gg/raddish/getting-started)**\r\n\r\n### Quick Links\r\n- [Getting Started](https://docs.hawaiian.gg/raddish/getting-started)\r\n- [Data Structures](https://docs.hawaiian.gg/raddish/data-structures)\r\n- [Pub/Sub Events](https://docs.hawaiian.gg/raddish/pubsub)\r\n- [Networking Guide](https://docs.hawaiian.gg/raddish/networking)\r\n- [DataStore Bridge](https://docs.hawaiian.gg/raddish/datastore)\r\n\r\n### API Overview\r\n\r\n<details>\r\n<summary><b>Cache Operations</b></summary>\r\n\r\n```lua\r\nRaddish.Set(key, value, ttl)          -- Store with optional TTL\r\nRaddish.Get(key)                      -- Retrieve value\r\nRaddish.Delete(key)                   -- Delete key\r\nRaddish.Exists(key)                   -- Check if exists\r\nRaddish.Expire(key, ttl)              -- Set expiration\r\nRaddish.TTL(key)                      -- Get remaining TTL\r\nRaddish.Keys(pattern)                 -- Find keys (wildcards)\r\nRaddish.Incr(key)                     -- Increment by 1\r\nRaddish.Decr(key)                     -- Decrement by 1\r\nRaddish.FlushAll()                    -- Clear all cache\r\nRaddish.GetStats()                    -- Get cache statistics\r\n```\r\n\r\n</details>\r\n\r\n<details>\r\n<summary><b>Hashes</b></summary>\r\n\r\n```lua\r\nRaddish.HSet(hash, field, value)      -- Set field\r\nRaddish.HGet(hash, field)             -- Get field\r\nRaddish.HGetAll(hash)                 -- Get all fields\r\nRaddish.HDel(hash, field)             -- Delete field\r\nRaddish.HExists(hash, field)          -- Check if exists\r\nRaddish.HKeys(hash)                   -- Get all field names\r\nRaddish.HVals(hash)                   -- Get all values\r\nRaddish.HLen(hash)                    -- Get field count\r\n```\r\n\r\n</details>\r\n\r\n<details>\r\n<summary><b>Lists</b></summary>\r\n\r\n```lua\r\nRaddish.LPush(key, value)             -- Push to left (start)\r\nRaddish.RPush(key, value)             -- Push to right (end)\r\nRaddish.LPop(key)                     -- Pop from left\r\nRaddish.RPop(key)                     -- Pop from right\r\nRaddish.LRange(key, start, stop)      -- Get range\r\nRaddish.LLen(key)                     -- Get length\r\nRaddish.LIndex(key, index)            -- Get by index\r\n```\r\n\r\n</details>\r\n\r\n<details>\r\n<summary><b>Sets</b></summary>\r\n\r\n```lua\r\nRaddish.SAdd(key, member)             -- Add member\r\nRaddish.SRem(key, member)             -- Remove member\r\nRaddish.SIsMember(key, member)        -- Check membership (O(1))\r\nRaddish.SMembers(key)                 -- Get all members\r\nRaddish.SCard(key)                    -- Get size\r\n```\r\n\r\n</details>\r\n\r\n<details>\r\n<summary><b>Sorted Sets</b></summary>\r\n\r\n```lua\r\nRaddish.ZAdd(key, score, member)      -- Add with score\r\nRaddish.ZRem(key, member)             -- Remove member\r\nRaddish.ZRange(key, start, stop)      -- Get range (sorted)\r\nRaddish.ZRangeByScore(key, min, max)  -- Get by score range\r\nRaddish.ZScore(key, member)           -- Get score\r\nRaddish.ZRank(key, member)            -- Get rank (0-indexed)\r\nRaddish.ZIncrBy(key, delta, member)   -- Increment score\r\nRaddish.ZCard(key)                    -- Get size\r\n```\r\n\r\n</details>\r\n\r\n<details>\r\n<summary><b>Pub/Sub</b></summary>\r\n\r\n```lua\r\nRaddish.Publish(channel, data)        -- Broadcast to all servers\r\nRaddish.Subscribe(channel, callback)  -- Listen for events\r\nRaddish.GetHistory(channel, limit)    -- Get event history\r\nRaddish.GetSubscriberCount(channel)   -- Get subscriber count\r\nRaddish.UnsubscribeAll(channel)       -- Remove all subscribers\r\n```\r\n\r\n</details>\r\n\r\n<details>\r\n<summary><b>Networking</b></summary>\r\n\r\n```lua\r\nRaddish.HttpGet(url, options)         -- GET request\r\nRaddish.HttpPost(url, data, options)  -- POST request\r\nRaddish.HttpPut(url, data, options)   -- PUT request\r\nRaddish.HttpDelete(url, options)      -- DELETE request\r\nRaddish.HttpPatch(url, data, options) -- PATCH request\r\nRaddish.HttpBatch(requests)           -- Batch multiple requests\r\n\r\nRaddish.SendWebhook(url, data)        -- Generic webhook\r\nRaddish.SendDiscordWebhook(url, opts) -- Discord webhook\r\nRaddish.APIRequest(base, endpoint)    -- REST API helper\r\n\r\nRaddish.InvalidateHttpCache(url)      -- Clear cached response\r\nRaddish.ClearHttpCache()              -- Clear all HTTP cache\r\nRaddish.GetNetworkStats()             -- Get request stats\r\n```\r\n\r\n</details>\r\n\r\n<details>\r\n<summary><b>DataStore Bridge</b></summary>\r\n\r\n```lua\r\nRaddish.GetWithCache(player, key, default, ttl)\r\nRaddish.SetWithCache(player, key, value, ttl)\r\nRaddish.IncrementWithCache(player, key, delta, default, ttl)\r\nRaddish.InvalidateCache(player, key)\r\nRaddish.Flush()                       -- Save all pending writes\r\nRaddish.FlushPlayer(player)           -- Save player data\r\n```\r\n\r\n</details>\r\n\r\n## ⚙️ Configuration\r\n\r\nYou can configure Raddish by editing these values in the module files:\r\n\r\n### CacheManager.lua\r\n```lua\r\nlocal MAX_CACHE_SIZE = 10000    -- Maximum cached items\r\nlocal DEFAULT_TTL = 300         -- Default expiration (5 minutes)\r\n```\r\n\r\n### NetworkingModule.lua\r\n```lua\r\nlocal MAX_RETRIES = 3                -- HTTP retry attempts\r\nlocal RETRY_DELAY = 2                -- Retry delay (seconds)\r\nlocal RATE_LIMIT_WINDOW = 60         -- Rate limit window (seconds)\r\nlocal MAX_REQUESTS_PER_WINDOW = 100  -- Max requests per window\r\n```\r\n\r\n### DataStoreBridge.lua\r\n```lua\r\nlocal USE_WRITE_THROUGH = true      -- Write to DataStore immediately\r\nlocal WRITE_BACK_INTERVAL = 30      -- Batch write interval (seconds)\r\n```\r\n\r\n## 📊 Performance\r\n\r\n| Operation | Traditional | With Raddish | Improvement |\r\n|-----------|------------|--------------|-------------|\r\n| Get player data | 100-300ms | <1ms | **100-300x faster** |\r\n| Update leaderboard | 100-300ms | <1ms | **100-300x faster** |\r\n| Check if online | Loop through players | <1ms | **1000x+ faster** |\r\n| Cross-server event | Not possible | 100-500ms | **∞ (NEW!)** |\r\n| External API (cached) | 50-500ms | <1ms | **50-500x faster** |\r\n\r\n## 🤝 Contributing\r\n\r\nContributions are welcome! Here's how you can help:\r\n\r\n1. **Fork the repository**\r\n2. **Create a feature branch** (`git checkout -b feature/amazing-feature`)\r\n3. **Commit your changes** (`git commit -m 'Add amazing feature'`)\r\n4. **Push to the branch** (`git push origin feature/amazing-feature`)\r\n5. **Open a Pull Request**\r\n\r\n### Development Setup\r\n\r\n```bash\r\n# Clone the repository\r\ngit clone https://github.com/VerifiedHawaii/Raddish.git\r\n\r\n# Create a branch for your feature\r\ncd Raddish\r\ngit checkout -b feature/my-feature\r\n\r\n# Make your changes and test in Roblox Studio\r\n\r\n# Commit and push\r\ngit add .\r\ngit commit -m \"Add my feature\"\r\ngit push origin feature/my-feature\r\n```\r\n\r\n### Guidelines\r\n- Follow the existing code style\r\n- Add comments for complex logic\r\n- Update documentation for new features\r\n- Test thoroughly in Roblox Studio\r\n- Keep commits focused and descriptive\r\n\r\n## 🐛 Bug Reports\r\n\r\nFound a bug? Please [open an issue](https://github.com/VerifiedHawaii/Raddish/issues) with:\r\n- Clear title and description\r\n- Steps to reproduce\r\n- Expected vs actual behavior\r\n- Roblox Studio version\r\n- Any error messages\r\n\r\n## 💡 ","readmeTruncated":true,"readmeFull":"https://api.forest.dev/v1/package/verifiedhawaii/roblox/raddish/1.0.1/readme"}