ox_lib Rehberi: Geliştiriciler İçin Olmazsa Olmaz FiveM Kütüphanesi
Sıfırdan ox_lib öğrenin. Modern FiveM scriptlerinin dayandığı bildirimler, context menüleri, callbackler, zonelar ve exportlar, gerçek kod örnekleriyle.
Agency Scripts
Agency Scripts Kurucusu ve Baş Geliştiricisi
ox_lib nedir ve neden kullanmalısınız?
ox_lib, modern script geliştirme için fiili standart haline gelmiş FiveM için açık kaynaklı bir yardımcı program kütüphanesidir. Yazdığınız her script için tekerleği yeniden icat etme ihtiyacını ortadan kaldıran, önceden oluşturulmuş devasa bir UI bileşenleri, yardımcı fonksiyonlar ve performans araçları koleksiyonu sunar. ox_lib var olmadan önce geliştiriciler kendi bildirim sistemlerini, giriş diyaloglarını, ilerleme çubuklarını ve bağlam menülerini sıfırdan oluşturmak zorundaydı; bu da genellikle aynı sunucudaki farklı scriptler arasında tutarsız bir UI ile sonuçlanıyordu. ox_lib, profesyonel görünen ve ilk andan itibaren güvenilir çalışan birleşik, özenle hazırlanmış bir bileşen seti sunarak bunu çözer. Hem Lua hem de JavaScript destekler, herhangi bir framework ile (QBCore, ESX veya standalone) çalışır ve Overextended ekibi tarafından aktif olarak sürdürülür. 2026 yılında FiveM scriptleri yazıyor ve ox_lib kullanmıyorsanız, zaten var olan şeyleri oluşturmak için gereksiz zaman harcıyorsunuz demektir.
Resource'unuzda ox_lib Kurulumu
ox_lib kütüphanesini resource dosyanıza dahil etmek yalnızca iki adım gerektirir: bağımlılığı şuraya eklemek: fxmanifest.lua ve script'lerinizde kütüphaneyi çağırmak. @ox_lib/init.lua import, paylaşılan tüm araçlara erişim sağlarken modül sistemi yalnızca ihtiyaç duyduğunuz özellikleri seçerek yüklemenize olanak tanır. Kullanılmayan modüller hiçbir zaman yüklenmediği için bu durum kaynağınızın hafif kalmasını sağlar. Sunucu yapılandırmanızdaki server.cfg dosyasına şunu ekleyerek ox_lib'in kaynağınızdan önce başlatıldığından emin olun: ensure ox_lib özel kaynaklarınızın üzerinde. İşte ox_lib kullanan yeni bir kaynak için minimum kurulum:
-- fxmanifest.lua
fx_version 'cerulean'
game 'gta5'
name 'my-awesome-script'
version '1.0.0'
-- Required: import ox_lib
shared_scripts {
'@ox_lib/init.lua',
'config.lua',
}
client_scripts {
'client/*.lua',
}
server_scripts {
'server/*.lua',
}
-- Declare ox_lib as a dependency
dependencies {
'ox_lib',
}
-- Enable ox_lib locale system (optional)
lua54 'yes'
Bildirimler: Temiz, Tutarlı Uyarılar
ox_lib bildirimleri, çoğu scriptin kullandığı çirkin varsayılan sohbet mesajlarının ve özel NUI açılır pencerelerinin yerini alır. Simgeler, renkler ve otomatik kapanma özelliklerine sahip şık toast bildirimleri olarak görünürler. Konumu, süreyi, türü (success, error, warning, info) ayarlayabilir ve hatta başlığın altına bir açıklama ekleyebilirsiniz. Bildirim sistemi yalnızca istemci tarafındadır ve inanılmaz derecede hafiftir, scriptinize neredeyse sıfır ek yük getirir. Bildirimler en yaygın kullanılan ox_lib özelliğidir ve oluşturduğunuz her scriptte oyunculara geri bildirim iletmek için varsayılan yönteminiz olmalıdır.
-- client.lua: Notification examples
-- Simple notification
lib.notify({
title = 'Vehicle Stored',
description = 'Your vehicle has been stored in the garage.',
type = 'success', -- 'success' | 'error' | 'warning' | 'info'
duration = 5000, -- milliseconds
position = 'top-right', -- 'top' | 'top-right' | 'top-left' | 'bottom' | 'bottom-right' | 'bottom-left'
})
-- Error notification with icon
lib.notify({
title = 'Access Denied',
description = 'You do not have the required key.',
type = 'error',
icon = 'lock',
iconColor = '#ff4444',
})
-- Notification from server side
-- server.lua
RegisterNetEvent('garage:store', function()
local src = source
TriggerClientEvent('ox_lib:notify', src, {
title = 'Garage',
description = 'Vehicle stored successfully.',
type = 'success',
})
end)
Bağlam Menüleri: Etkileşimli Seçenek Listeleri
Bağlam menüleri, oyuncuların eylemleri tetiklemek için tıklayabileceği kaydırılabilir seçenek listeleridir. Meslek menüleri, mağaza arayüzleri, araç seçenekleri ve bir oyuncunun birden fazla eylem arasından seçim yapması gereken her senaryo için mükemmeldir. Her menü öğesi bir simgeye, bir açıklamaya, sağ tarafta görüntülenen meta verilere ve karmaşık seçenek ağaçlarını düzenlemek için iç içe geçmiş alt menülere sahip olabilir. Menü, oyuncu açıkça kapatana veya alt menü olmayan bir seçenek belirleyene kadar açık kalır; bu da onu eşya kategorilerine göz atmak için ideal hale getirir. Bağlam menüleri ayrıca sunucu verilerine dayalı olarak dinamik olarak oluşturulabilir, böylece veritabanınızdaki gerçek zamanlı envanteri yansıtan mağaza menüleri oluşturabilirsiniz.
-- client.lua: Context menu examples
-- Simple shop menu
lib.registerContext({
id = 'weapons_shop',
title = 'Ammu-Nation',
options = {
{
title = 'Pistol',
description = 'Standard 9mm handgun',
icon = 'gun',
metadata = {
{label = 'Price', value = '$2,500'},
{label = 'Ammo', value = '12 rounds'},
},
onSelect = function()
TriggerServerEvent('shop:buy', 'weapon_pistol')
end,
},
{
title = 'Body Armor',
description = 'Standard kevlar vest',
icon = 'shield',
metadata = {
{label = 'Price', value = '$5,000'},
{label = 'Protection', value = '50%'},
},
onSelect = function()
TriggerServerEvent('shop:buy', 'armor')
end,
},
{
title = 'Attachments',
description = 'Browse weapon modifications',
icon = 'wrench',
arrow = true, -- Shows arrow indicating submenu
menu = 'attachments_submenu',
},
},
})
lib.showContext('weapons_shop')
İlerleme Çubukları ve İlerleme Daireleri
İlerleme çubukları; kilit açma, üretim, araç tamiri veya yemek pişirme gibi zamanlanmış eylemler sırasında görsel geri bildirim sağlar. ox_lib, hem doğrusal bir çubuk hem de dairesel bir gösterge sunar. İlerleme animasyonu sırasında suistimalleri önlemek için hareket, dövüş ve araca binme gibi oyuncu kontrollerini devre dışı bırakabilirsiniz. Ayrıca, çubuk dolarken eylemi görünür şekilde gerçekleştirmeleri için oyuncuya bir animasyon ve bir prop ekleyebilirsiniz. Fonksiyon şunu döndürür: true oyuncu eylemi iptal ettiyse (örneğin hareket ederek) ve false başarıyla tamamlandıysa. Oyuncunun yarıda kestiği eylemleri tamamlamamak veya eşya vermemek için bu dönüş değerini mutlaka kontrol edin.
-- client.lua: Progress bar examples
-- Linear progress bar with animation
local cancelled = lib.progressBar({
duration = 8000,
label = 'Lockpicking door...',
useWhileDead = false,
canCancel = true,
disable = {
car = true,
move = true,
combat = true,
},
anim = {
dict = 'anim@amb@clubhouse@tutorial@bkr_tut_ig3@',
clip = 'machinic_loop_mechandler',
},
prop = {
model = 'prop_lockpick_01',
bone = 57005,
pos = vec3(0.14, 0.0, -0.01),
rot = vec3(0.0, 0.0, 0.0),
},
})
if cancelled then
lib.notify({ title = 'Cancelled', type = 'error' })
else
lib.notify({ title = 'Door Unlocked', type = 'success' })
TriggerServerEvent('lockpick:success', doorId)
end
-- Circular progress (useful for quick actions)
if lib.progressCircle({
duration = 2000,
label = 'Searching...',
position = 'bottom',
useWhileDead = false,
canCancel = true,
disable = { move = true },
}) then
lib.notify({ title = 'Search cancelled', type = 'error' })
else
TriggerServerEvent('search:complete')
end
Girdi İletişim Kutuları: Oyuncu Verilerini Toplama
Girdi iletişim kutuları, sade bir modal arayüz aracılığıyla oyunculardan metin, sayı, açılır menü seçimleri, onay kutuları, renk seçiciler, tarihler ve kaydırıcı değerleri toplamanızı sağlar. Bu, ev fiyatı belirleme, plaka girme, çete adlandırma veya meslek ayarlarını yapılandırma gibi oyuncu girdisi gerektiren script'ler için gereklidir. Her girdi alanının bir etiketi, isteğe bağlı açıklaması, zorunluluk işareti ve sayılar için min/maks değerleri veya açılır menüler için önceden tanımlanmış seçenekler gibi türe özel ayarları bulunur. Fonksiyon şunu döndürür: nil oyuncu iletişim kutusunu iptal ederse ve gönderirse alan sırasına göre bir değer dizisi döner. Açıkları önlemek için dönen verileri hem client hem de server tarafında mutlaka doğrulayın.
-- client.lua: Input dialog examples
-- Vehicle listing form
local input = lib.inputDialog('List Vehicle for Sale', {
{ type = 'input', label = 'Title', description = 'Name for the listing', required = true, max = 50 },
{ type = 'number', label = 'Price ($)', description = 'Asking price', required = true, min = 1000, max = 10000000 },
{ type = 'select', label = 'Condition', options = {
{ value = 'new', label = 'Brand New' },
{ value = 'used', label = 'Used - Good' },
{ value = 'damaged', label = 'Damaged' },
}},
{ type = 'textarea', label = 'Description', description = 'Describe your vehicle', max = 500 },
{ type = 'checkbox', label = 'I agree to the marketplace terms' },
})
if not input then return end -- Player cancelled
local title, price, condition, description, agreedTerms = table.unpack(input)
if not agreedTerms then
lib.notify({ title = 'You must agree to the terms', type = 'error' })
return
end
TriggerServerEvent('marketplace:list', {
title = title,
price = price,
condition = condition,
description = description,
})
Zone'lar: Verimli Alan Tespiti
ox_lib zone'ları, her karede oyuncu konumunu kontrol etmeye dayalı eski ve verimsiz yöntemin yerini şununla alır: GetEntityCoords ve mesafe matematiği. Zone sistemi, koordinatları yalnızca yapılandırılabilir aralıklarla kontrol eden ve oyuncular zone sınırlarını geçtiğinde enter/exit callback'lerini tetikleyen optimize edilmiş bir uzamsal algılama algoritması kullanır. Zone'ları küre, kutu veya çokgen olarak tanımlayabilirsiniz; bu da onları küçük etkileşim noktalarından büyük mahalle sınırlarına kadar her şey için yeterince esnek kılar. Zone'lar rotasyonu, geliştirme için debug çizimini ve callback'lere aktarılan rastgele verileri destekler. Bir oyuncunun belirli bir alanda ne zaman bulunduğunu tespit etmesi gereken tüm script'ler için ox_lib zone'ları mevcut en yüksek performanslı çözümdür.
-- client.lua: Zone examples
-- Sphere zone for a shop entrance
local shopZone = lib.zones.sphere({
coords = vec3(25.7, -1347.3, 29.5),
radius = 3.0,
debug = true, -- Set false in production
onEnter = function(self)
lib.notify({ title = 'Press [E] to open shop', type = 'info' })
lib.showTextUI('[E] Open Shop', { position = 'right-center' })
end,
onExit = function(self)
lib.hideTextUI()
end,
})
-- Box zone with rotation for a parking spot
local parkingZone = lib.zones.box({
coords = vec3(215.3, -810.0, 30.7),
size = vec3(6.0, 3.0, 2.0),
rotation = 70.0,
debug = true,
onEnter = function(self)
lib.showTextUI('[E] Store Vehicle')
end,
onExit = function(self)
lib.hideTextUI()
end,
})
-- Clean up zones when resource stops
AddEventHandler('onResourceStop', function(resource)
if resource == GetCurrentResourceName() then
shopZone:remove()
parkingZone:remove()
end
end)
Önbellek: Akıllı Veri Erişimi
The lib.cache modülü, her karede (frame) native çağrıları yapmadan sık ihtiyaç duyulan oyuncu verilerine anında erişim sağlar. Şunun gibi değerler: cache.ped, cache.vehicle, cache.seat, cache.weapon, ve cache.playerId yoklama (polling) yerine olay dinleyicileri aracılığıyla ox_lib tarafından otomatik olarak güncel tutulur. Bu da güvenle okuyabileceğiniz anlamına gelir: cache.vehicle performans konusunda endişelenmeden kodunuzun herhangi bir yerinde. Önbellek ayrıca değerler değiştiğinde olayları tetikler, böylece şunlar için işleyiciler kaydedebilirsiniz: ox_lib:cache:vehicle bir oyuncu araca bindiğinde veya araçtan indiğinde tepki vermek için. Zone'lar ve ox_lib kütüphanesinin geri kalanıyla birleştiğinde cache sistemi, nadiren değişen koşulları kontrol ederek CPU döngülerini boşa harcayan kare tabanlı polling döngüleri yerine temiz ve olay odaklı kodlar yazmanızı sağlar.
-- client.lua: Cache examples
-- Access cached values (no native calls needed)
local myPed = cache.ped
local myVehicle = cache.vehicle -- nil if not in a vehicle
local mySeat = cache.seat -- -1 = driver, 0 = front passenger, etc.
local myWeapon = cache.weapon
-- React to vehicle changes
lib.onCache('vehicle', function(vehicle)
if vehicle then
-- Player entered a vehicle
local plate = GetVehicleNumberPlateText(vehicle)
lib.notify({
title = 'Vehicle',
description = 'Plate: ' .. plate,
type = 'info',
})
else
-- Player exited a vehicle
lib.notify({ title = 'On foot', type = 'info' })
end
end)
-- React to weapon changes
lib.onCache('weapon', function(weapon)
if weapon then
print('Player equipped weapon:', weapon)
end
end)