Skip to content

Data Structures

Raddish provides Redis-like data structures that make complex operations simple and fast.

Hashes

Hashes are like dictionaries or tables - perfect for storing object data.

Basic Operations

lua
-- Set hash fields
Raddish.HSet("player:123", "name", "VerifiedHawaii")
Raddish.HSet("player:123", "level", 50)
Raddish.HSet("player:123", "gold", 1000)

-- Get a specific field
local name = Raddish.HGet("player:123", "name")
print(name) -- "VerifiedHawaii"

-- Get all fields
local playerData = Raddish.HGetAll("player:123")
print(playerData.name) -- "VerifiedHawaii"
print(playerData.level) -- 50
print(playerData.gold) -- 1000

-- Delete a field
Raddish.HDel("player:123", "gold")

-- Check if field exists
if Raddish.HExists("player:123", "level") then
    print("Player has a level!")
end

Advanced Operations

lua
-- Get all field names
local fields = Raddish.HKeys("player:123")
-- {"name", "level", "gold"}

-- Get all values
local values = Raddish.HVals("player:123")
-- {"VerifiedHawaii", 50, 1000}

-- Get number of fields
local count = Raddish.HLen("player:123")
print(count) -- 3

Use Cases

lua
-- Player inventory
Raddish.HSet("inventory:" .. player.UserId, "sword", 1)
Raddish.HSet("inventory:" .. player.UserId, "shield", 2)
Raddish.HSet("inventory:" .. player.UserId, "potion", 5)

-- Game configuration
Raddish.HSet("config:game", "max_players", 50)
Raddish.HSet("config:game", "difficulty", "hard")
Raddish.HSet("config:game", "pvp_enabled", true)

-- Session data
Raddish.HSet("session:" .. sessionId, "userId", player.UserId)
Raddish.HSet("session:" .. sessionId, "createdAt", os.time())
Raddish.HSet("session:" .. sessionId, "ipAddress", "xxx.xxx.xxx.xxx")

Lists

Lists are ordered collections - perfect for queues, chat history, and recent items.

Basic Operations

lua
-- Push to the right (end)
Raddish.RPush("chat:global", "Hello!")
Raddish.RPush("chat:global", "How are you?")
Raddish.RPush("chat:global", "Good!")

-- Push to the left (beginning)
Raddish.LPush("notifications", "New achievement!")

-- Pop from the right (end)
local lastMessage = Raddish.RPop("chat:global")
print(lastMessage) -- "Good!"

-- Pop from the left (beginning)
local firstNotification = Raddish.LPop("notifications")
print(firstNotification) -- "New achievement!"

-- Get range of elements
local messages = Raddish.LRange("chat:global", 1, -1) -- All messages
local last10 = Raddish.LRange("chat:global", -10, -1) -- Last 10

-- Get list length
local count = Raddish.LLen("chat:global")

-- Get element at index
local message = Raddish.LIndex("chat:global", 1)

Use Cases

lua
-- Chat history (FIFO - First In, First Out)
function addChatMessage(message)
    Raddish.RPush("chat:history", message)
    
    -- Keep only last 100 messages
    if Raddish.LLen("chat:history") > 100 then
        Raddish.LPop("chat:history")
    end
end

-- Task queue
function queueTask(taskData)
    Raddish.RPush("tasks:pending", taskData)
end

function processNextTask()
    local task = Raddish.LPop("tasks:pending")
    if task then
        -- Process task
        print("Processing:", task)
    end
end

-- Recent activity log
Raddish.RPush("activity:" .. player.UserId, {
    action = "purchased_item",
    item = "sword",
    timestamp = os.time()
})

-- Get last 10 activities
local recentActivity = Raddish.LRange("activity:" .. player.UserId, -10, -1)

Sets

Sets are unordered collections of unique values - perfect for tags, permissions, and online players.

Basic Operations

lua
-- Add members to set
Raddish.SAdd("online:players", "Player1")
Raddish.SAdd("online:players", "Player2")
Raddish.SAdd("online:players", "Player3")

-- Check if member exists (very fast - O(1))
if Raddish.SIsMember("online:players", "Player1") then
    print("Player1 is online!")
end

-- Remove member
Raddish.SRem("online:players", "Player1")

-- Get all members
local players = Raddish.SMembers("online:players")
-- {"Player2", "Player3"}

-- Get set size
local count = Raddish.SCard("online:players")
print(count) -- 2

Use Cases

lua
-- Online players tracking
game.Players.PlayerAdded:Connect(function(player)
    Raddish.SAdd("online:players", player.UserId)
end)

game.Players.PlayerRemoving:Connect(function(player)
    Raddish.SRem("online:players", player.UserId)
end)

-- Check if player is online
local isOnline = Raddish.SIsMember("online:players", targetUserId)

-- Player tags/badges
Raddish.SAdd("tags:" .. player.UserId, "VIP")
Raddish.SAdd("tags:" .. player.UserId, "Developer")
Raddish.SAdd("tags:" .. player.UserId, "Beta_Tester")

local tags = Raddish.SMembers("tags:" .. player.UserId)
-- {"VIP", "Developer", "Beta_Tester"}

-- Permissions system
Raddish.SAdd("permissions:admin", "kick_player")
Raddish.SAdd("permissions:admin", "ban_player")
Raddish.SAdd("permissions:admin", "teleport")

if Raddish.SIsMember("permissions:admin", "ban_player") then
    -- Admin can ban players
end

Sorted Sets

Sorted Sets are ordered by score - perfect for leaderboards, rankings, and time-based data.

Basic Operations

lua
-- Add members with scores
Raddish.ZAdd("leaderboard:global", 1000, "Player1")
Raddish.ZAdd("leaderboard:global", 2500, "Player2")
Raddish.ZAdd("leaderboard:global", 1750, "Player3")

-- Get range (sorted by score, ascending)
local top3 = Raddish.ZRange("leaderboard:global", 1, 3, true)
-- {
--   {member = "Player1", score = 1000},
--   {member = "Player3", score = 1750},
--   {member = "Player2", score = 2500}
-- }

-- Get range without scores
local topPlayers = Raddish.ZRange("leaderboard:global", 1, 10, false)
-- {"Player1", "Player3", "Player2"}

-- Get members by score range
local midRank = Raddish.ZRangeByScore("leaderboard:global", 1500, 2000, true)
-- {member = "Player3", score = 1750}

-- Get score of specific member
local score = Raddish.ZScore("leaderboard:global", "Player2")
print(score) -- 2500

-- Get rank of member (0-indexed)
local rank = Raddish.ZRank("leaderboard:global", "Player3")
print(rank) -- 1 (second place, 0-indexed)

-- Increment score
Raddish.ZIncrBy("leaderboard:global", 500, "Player1")
local newScore = Raddish.ZScore("leaderboard:global", "Player1")
print(newScore) -- 1500

-- Remove member
Raddish.ZRem("leaderboard:global", "Player1")

-- Get size
local count = Raddish.ZCard("leaderboard:global")

Use Cases

lua
-- Global leaderboard
function updateLeaderboard(player, score)
    Raddish.ZAdd("leaderboard:global", score, player.UserId)
end

function getTopPlayers(count)
    return Raddish.ZRange("leaderboard:global", 1, count, true)
end

-- Display top 10
local top10 = getTopPlayers(10)
for i, entry in ipairs(top10) do
    print(i, entry.member, entry.score)
end

-- Player ranking
function getPlayerRank(userId)
    local rank = Raddish.ZRank("leaderboard:global", userId)
    return rank and (rank + 1) or nil -- Convert to 1-indexed
end

-- Time-based events (using timestamp as score)
Raddish.ZAdd("events:timeline", os.time(), "Event1")
Raddish.ZAdd("events:timeline", os.time() + 60, "Event2")
Raddish.ZAdd("events:timeline", os.time() + 120, "Event3")

-- Get events in next hour
local upcoming = Raddish.ZRangeByScore(
    "events:timeline",
    os.time(),
    os.time() + 3600,
    true
)

-- Matchmaking queue (using skill rating as score)
function joinQueue(player, skillRating)
    Raddish.ZAdd("queue:ranked", skillRating, player.UserId)
end

-- Find players with similar skill (±100 rating)
function findMatch(playerUserId)
    local playerRating = Raddish.ZScore("queue:ranked", playerUserId)
    if not playerRating then return nil end
    
    local potentialMatches = Raddish.ZRangeByScore(
        "queue:ranked",
        playerRating - 100,
        playerRating + 100,
        true
    )
    
    return potentialMatches
end

Combining Data Structures

lua
-- Complex player profile
local playerId = player.UserId

-- Hash for basic info
Raddish.HSet("player:" .. playerId, "name", player.Name)
Raddish.HSet("player:" .. playerId, "joinDate", os.time())
Raddish.HSet("player:" .. playerId, "level", 1)

-- Sorted set for achievements (score = timestamp)
Raddish.ZAdd("achievements:" .. playerId, os.time(), "first_login")
Raddish.ZAdd("achievements:" .. playerId, os.time(), "level_10")

-- Set for owned items
Raddish.SAdd("items:" .. playerId, "sword_basic")
Raddish.SAdd("items:" .. playerId, "shield_wooden")

-- List for activity history
Raddish.RPush("history:" .. playerId, {
    action = "login",
    timestamp = os.time()
})

-- Get complete profile
local profile = {
    info = Raddish.HGetAll("player:" .. playerId),
    achievements = Raddish.ZRange("achievements:" .. playerId, 1, -1, true),
    items = Raddish.SMembers("items:" .. playerId),
    recentActivity = Raddish.LRange("history:" .. playerId, -10, -1)
}

Performance Comparison

OperationTraditionalWith RaddishSpeedup
Get player data100-300ms<1ms100-300x
Update leaderboard100-300ms<1ms100-300x
Check if onlineLoop through players<1ms1000x+
Get top 10Sort entire table<1ms100x+

"Beyond Boundaries. Beyond Imagination."