Best Practices
Tips for building quality addons with cLib.
1. Always Wait for cLib
-- ✅ Good
hook.Add("cLib.OnLoaded", "MyAddon", function()
-- Initialize here
end)
-- ❌ Bad - cLib might not be loaded
MyAddon.Init()2. Use Unique Prefixes
-- ✅ Good
cLib.AddColor("MyAddon.Primary", Color(100, 150, 200))
cLib.CreateFont("MyAddon.Title", "Roboto", 0.03)
cLib.Net.SetPrefix("MyAddon.")
-- ❌ Bad - might conflict with other addons
cLib.AddColor("Primary", Color(100, 150, 200))3. Use cLib.Scale for UI
-- ✅ Good - scales on all resolutions
panel:SetSize(cLib.Scale(500), cLib.Scale(400))
-- ❌ Bad - too small on 4K, too big on 720p
panel:SetSize(500, 400)4. Validate Network Data
-- ✅ Good
cLib.Net.Receive("Data", function(data, ply)
-- Server: validate player
if SERVER and (not IsValid(ply) or not ply:IsAdmin()) then
return
end
-- Validate data
if not data or type(data.value) ~= "number" then
return
end
ProcessData(data)
end)
-- ❌ Bad - no validation
cLib.Net.Receive("Data", function(data, ply)
ProcessData(data) -- Exploitable!
end)5. Clean Up Resources
-- ✅ Good
function PANEL:OnRemove()
if self._animId then
cLib.StopAnimation(self._animId)
end
if timer.Exists(self._timerName) then
timer.Remove(self._timerName)
end
end
-- ❌ Bad - animations/timers keep running6. Use Debug During Development
-- ✅ Good
if MyAddon.Config.DebugMode then
cLib.Debug.SetEnabled(true)
cLib.Debug.SetPrefix("[MyAddon]")
cLib.Debug.SetLevel("DEBUG")
end
cLib.Debug.Info("Player loaded:", ply:Nick())
cLib.Debug.Time("DataProcess", function()
ProcessLargeData()
end)7. Use i18n for Text
-- ✅ Good
button:SetText(cLib.L("myaddon.save"))
cLib.Alert(cLib.L("myaddon.error"), cLib.L("myaddon.error.save"))
-- ❌ Bad - hardcoded English
button:SetText("Save")8. Handle Edge Cases
-- ✅ Good
function MyAddon.GetPlayerData(ply)
if not IsValid(ply) then return {} end
if not ply:IsPlayer() then return {} end
local steamid = ply:SteamID64()
if not steamid then return {} end
return MyAddon.Data[steamid] or {}
end9. Use Proper Animations
-- ✅ Good - smooth easing
cLib.AnimateAlpha(panel, 0, 0.3, cLib.Ease.OutQuad, function()
panel:Remove()
end)
-- ❌ Bad - abrupt
panel:Remove()10. Organize Code Logically
-- ✅ Good file structure
myaddon/
sh_config.lua -- Configuration first
sh_lang.lua -- Then language
sv_database.lua -- Server systems
sv_network.lua
sv_functions.lua
cl_network.lua -- Client systems
cl_menu.lua
cl_hud.luaPerformance Tips
-- Cache lookups
local myColor = cLib.GetColor("MyAddon.Primary")
function PANEL:Paint(w, h)
-- ✅ Good - use cached color
draw.RoundedBox(8, 0, 0, w, h, myColor)
-- ❌ Bad - lookup every frame
draw.RoundedBox(8, 0, 0, w, h, cLib.GetColor("MyAddon.Primary"))
end
-- Use Think sparingly
function PANEL:Think()
-- Only update when needed
if CurTime() < self._nextUpdate then return end
self._nextUpdate = CurTime() + 0.1 -- 10 times per second
self:UpdateContent()
end