Client-Side Example

Examples Updated: Dec 10, 2025

Client-Side Example

Complete client-side code for an addon.

Network Handlers

-- myaddon/cl_network.lua
cLib.Net.SetPrefix("MyAddon.")

-- Store player data locally
MyAddon.PlayerData = {}

-- Receive synced data
cLib.Net.Receive("SyncData", function(data)
    if data.success == false then
        cLib.Alert("Error", data.message or cLib.L("myaddon.error"))
        return
    end
    
    if data.message then
        cLib.Notify(data.message, "success", 3)
    end
    
    MyAddon.PlayerData = data
    
    -- Update UI if open
    if IsValid(MyAddon.MenuFrame) then
        MyAddon.RefreshMenu()
    end
end)

-- Request data from server
function MyAddon.RequestData()
    cLib.Net.SendToServer("RequestData", {})
end

-- Save data to server
function MyAddon.SaveData(data)
    cLib.Net.SendToServer("SaveData", data)
end

Main Menu

-- myaddon/cl_menu.lua
MyAddon.MenuFrame = nil

function MyAddon.OpenMenu()
    if IsValid(MyAddon.MenuFrame) then
        MyAddon.MenuFrame:Remove()
        return
    end
    
    local frame = vgui.Create("cLib.DFrame")
    frame:SetSize(cLib.Scale(700), cLib.Scale(500))
    frame:SetTitle(cLib.L("myaddon.title"))
    frame:Center()
    frame:MakePopup()
    frame:EnableBlur(true)
    
    MyAddon.MenuFrame = frame
    
    local container = frame.mainContainer
    
    -- Create tabs
    local tabs = vgui.Create("cLib.DTabPanel", container)
    tabs:Dock(FILL)
    tabs:DockMargin(cLib.Scale(10), cLib.Scale(10), cLib.Scale(10), cLib.Scale(10))
    
    -- Dashboard tab
    local _, dashboard = tabs:AddTabPanel("Dashboard", "icon16/house.png")
    MyAddon.CreateDashboard(dashboard)
    
    -- Settings tab
    local _, settings = tabs:AddTabPanel(cLib.L("myaddon.settings"), "icon16/cog.png")
    MyAddon.CreateSettings(settings)
    
    -- Animate opening
    cLib.PopIn(frame, 0.2, cLib.Ease.OutBack)
end

function MyAddon.CreateDashboard(parent)
    local title = vgui.Create("DLabel", parent)
    title:SetText("Welcome, " .. LocalPlayer():Nick())
    title:SetFont("MyAddon.Title")
    title:Dock(TOP)
    title:DockMargin(0, cLib.Scale(20), 0, cLib.Scale(10))
    title:SetContentAlignment(5)
    
    -- Stats cards
    local cardGrid = vgui.Create("cLib.DCardGrid", parent)
    cardGrid:Dock(TOP)
    cardGrid:SetTall(cLib.Scale(150))
    cardGrid:DockMargin(0, cLib.Scale(10), 0, 0)
    cardGrid:SetCardWidth(cLib.Scale(180))
    cardGrid:SetCardHeight(cLib.Scale(120))
    
    local data = MyAddon.PlayerData or {}
    
    local card1 = cardGrid:AddCard("Play Time", (data.playtime or 0) .. " hours")
    local card2 = cardGrid:AddCard("Score", tostring(data.score or 0))
    local card3 = cardGrid:AddCard("Rank", data.rank or "New")
end

function MyAddon.CreateSettings(parent)
    local scroll = vgui.Create("cLib.DScrollPanel", parent)
    scroll:Dock(FILL)
    
    -- Setting toggles
    local notifToggle = vgui.Create("cLib.DToggleLabel", scroll)
    notifToggle:SetText("Enable Notifications")
    notifToggle:SetValue(MyAddon.PlayerData.notifications ~= false)
    notifToggle:Dock(TOP)
    notifToggle:DockMargin(0, cLib.Scale(10), 0, 0)
    
    local soundToggle = vgui.Create("cLib.DToggleLabel", scroll)
    soundToggle:SetText("Enable Sounds")
    soundToggle:SetValue(MyAddon.PlayerData.sounds ~= false)
    soundToggle:Dock(TOP)
    soundToggle:DockMargin(0, cLib.Scale(10), 0, 0)
    
    local hudToggle = vgui.Create("cLib.DToggleLabel", scroll)
    hudToggle:SetText("Show HUD")
    hudToggle:SetValue(MyAddon.PlayerData.hud ~= false)
    hudToggle:Dock(TOP)
    hudToggle:DockMargin(0, cLib.Scale(10), 0, 0)
    
    -- Save button
    local saveBtn = vgui.Create("cLib.DButton", scroll)
    saveBtn:SetText(cLib.L("myaddon.save"))
    saveBtn:Dock(TOP)
    saveBtn:DockMargin(0, cLib.Scale(20), 0, 0)
    saveBtn:SetTall(cLib.Scale(40))
    saveBtn:SetBackgroundColor(cLib.GetColor("MyAddon.Primary"))
    
    saveBtn.DoClick = function()
        MyAddon.SaveData({
            notifications = notifToggle:GetValue(),
            sounds = soundToggle:GetValue(),
            hud = hudToggle:GetValue()
        })
    end
end

function MyAddon.RefreshMenu()
    if not IsValid(MyAddon.MenuFrame) then return end
    MyAddon.MenuFrame:Remove()
    MyAddon.OpenMenu()
end

-- Keybind
hook.Add("PlayerButtonDown", "MyAddon.OpenMenuBind", function(ply, button)
    if button == KEY_F5 then
        MyAddon.OpenMenu()
    end
end)

HUD

-- myaddon/cl_hud.lua
hook.Add("HUDPaint", "MyAddon.HUD", function()
    if not MyAddon.Config.Features.HUD then return end
    if MyAddon.PlayerData.hud == false then return end
    
    local x = cLib.Scale(20)
    local y = ScrH() - cLib.Scale(100)
    
    -- Background
    draw.RoundedBox(8, x, y, cLib.Scale(200), cLib.Scale(80), Color(0, 0, 0, 150))
    
    -- Logo
    local logo = cLib.GetMaterial("MyAddon.Logo")
    surface.SetDrawColor(255, 255, 255)
    surface.SetMaterial(logo)
    surface.DrawTexturedRect(x + cLib.Scale(10), y + cLib.Scale(10), cLib.Scale(32), cLib.Scale(32))
    
    -- Text
    draw.SimpleText("My Addon", "MyAddon.SubTitle", x + cLib.Scale(50), y + cLib.Scale(15), color_white)
    draw.SimpleText("Score: " .. (MyAddon.PlayerData.score or 0), "MyAddon.Text", x + cLib.Scale(50), y + cLib.Scale(40), Color(200, 200, 200))
end)