FiveM Yarış Sistemi: Pistler, Liderlik Tabloları ve Bahisler
FiveM sunucunuza sokak yarışları ekleyin. Pist oluşturucular, kontrol noktaları, bahisler, liderlik tabloları ve ciddi modifiye toplulukları için en iyi yarış scriptleri.
Agency Scripts
Agency Scripts Kurucusu ve Baş Geliştiricisi
Yarış Oluşturma Sistemi Tasarımı
Etkileyici bir sokak yarışı sistemi, oyunculara kendi yarış rotalarını oluşturma ve yönetme gücü vermekle başlar. En iyi yarış scriptleri, yalnızca önceden tanımlanmış pistlere güvenmek yerine, organizatörlerin bir rota boyunca sürerek ve konumları işaretleyerek kontrol noktalarını dinamik olarak yerleştirmelerine olanak tanır. Her yarışı benzersiz bir tanımlayıcı, üreticinin oyuncu ID'si, bir isim, yön açılarıyla birlikte kontrol noktası koordinatlarının sıralı listesi ve mesafe ile tahmini tur süresi gibi meta verileri içeren bir veri yapısı olarak saklayın. Oluşturma süreci sezgisel hissettirmelidir: Oyuncu yarış düzenleyici moduna girer, her kontrol noktası konumuna sürer, bir tuşa basarak yerleşimi onaylar ve başlangıç çizgisine dönerek işlemi tamamlar. Tamamlanan yarışları veritabanınıza kaydedin, böylece sunucu yeniden başlatmalarında korunurlar ve toplulukla paylaşılabilirler. İmkansız veya adaletsiz pist tasarımları yoluyla trollemenin önüne geçmek için yöneticilerin oyuncu yapımı rotaları herkese açık yarış listesinde görünmeden önce onaylayabileceği bir inceleme sistemi uygulayın.
Checkpoint Sistemi ve Yarış Mantığı
Checkpoint'ler, yarış ilerlemesini doğrulayan ve kestirmeleri önleyen temel mekaniktir. Her checkpoint, yol genişliğine bağlı olarak genellikle 8 ila 15 metre arasında ayarlanabilir yarıçapa sahip bir 3D bölge olarak tanımlanmalıdır. Checkpoint'leri görsel olarak göstermek için GTA'nın native marker çizim fonksiyonlarını kullanın: Mevcut checkpoint parlak bir renkle vurgulanmalı, bir sonraki ise şeffaf bir önizleme olarak gösterilmelidir. Her yarışçının ilerlemesini indeksli bir checkpoint listesiyle takip edin ve yarışçıları yalnızca sıradaki doğru checkpoint bölgesine girdiklerinde ilerletin. Checkpoint'ler arasındaki süreyi takip ederek ve teleport ya da speed hack belirtisi olan imkansız hızda sektör tamamlayan yarışçıları işaretleyerek veya diskalifiye ederek anti-cheat önlemleri uygulayın.
-- Client-side checkpoint detection
local currentCheckpoint = 1
local raceCheckpoints = {} -- populated when race starts
CreateThread(function()
while isRacing do
local playerCoords = GetEntityCoords(PlayerPedId())
local checkpoint = raceCheckpoints[currentCheckpoint]
if checkpoint then
local dist = #(playerCoords - checkpoint.coords)
-- Draw current checkpoint marker
DrawMarker(1, checkpoint.coords.x, checkpoint.coords.y,
checkpoint.coords.z - 1.0, 0, 0, 0, 0, 0, 0,
checkpoint.radius * 2, checkpoint.radius * 2, 2.0,
45, 212, 191, 120, false, true, 2, false, nil, nil, false)
if dist < checkpoint.radius then
PlaySoundFrontend(-1, 'CHECKPOINT_NORMAL', 'HUD_MINI_GAME_SOUNDSET', true)
currentCheckpoint = currentCheckpoint + 1
if currentCheckpoint > #raceCheckpoints then
-- Race finished
local finishTime = GetGameTimer() - raceStartTime
TriggerServerEvent('racing:finished', raceId, finishTime)
isRacing = false
else
-- Notify server of checkpoint progress
TriggerServerEvent('racing:checkpoint', raceId, currentCheckpoint)
end
end
end
Wait(50)
end
end)
Liderlik Tablosu ve Sıralama Sistemi
Liderlik tabloları rekabeti körükler ve oyuncuların sürelerini geliştirmek için geri gelmelerini sağlar. Yarış sonuçlarını; oyuncu kimliği, yarış ID, milisaniye cinsinden tamamlanma süresi, kullanılan araç modeli, tarih ve turun kişisel en iyi derece olup olmadığını kaydeden bir veritabanı tablosunda saklayın. Liderlik tablolarını, her pist için en iyi süreleri gösteren bir NUI arayüzü üzerinden görüntüleyin; oyuncuların spor, süper, muscle veya kompakt gibi kategoriler içinde adil bir şekilde karşılaştırma yapabilmesi için araç sınıfına göre filtrelenebilir olsun. Rekabeti canlı tutmak için periyodik olarak sıfırlanan sezonluk bir sıralama sistemi uygularken, tüm zamanların rekorları için kalıcı bir tablo bulundurun. Çok oyunculu yarışlardaki başa baş performansa dayalı ELO tarzı bir yarış puanı hesaplayın; böylece yetenekli yarışçılar, daha yüksek dereceli rakipleri yendiklerinde artan ve daha düşük dereceli rakiplere kaybettiklerinde azalan görünür bir rütbeye sahip olur. Bu derecelendirmeyi yarış arayüzünde gösterin ve rastgele yarışlar düzenlerken isteğe bağlı eşleştirme için kullanın.
Bahis ve Ödül Sistemi
Bir bahis sistemi yarışlara finansal heyecan katar ve yarış ortamını sunucunuzun genel ekonomisine entegre eder. Yarış organizatörlerinin tüm katılımcıların ödemesi gereken bir katılım ücreti belirlemesine izin verin; toplam ödül havuzu birinci, ikinci ve üçüncü için 70-20-10 gibi yapılandırılabilir bir dağılıma göre dereceye girenlere paylaştırılsın. Yarışmayan oyuncuların sonuç üzerine bahis oynayabileceği ve paralarıyla bir yarışçıyı destekleyebileceği bir seyirci bahis sistemi uygulayın. Suistimalleri önlemek için tüm finansal işlemlerde yalnızca server taraflı mantık kullanın. Ekonominizde para eritme (money sink) mekanizması olarak tüm bahislerde %5-10 oranında kasa payı (house cut) uygulayın. Daha büyük organize etkinlikler için yöneticilerin sunucu hazinesinden finanse edilen bonus ödül havuzları eklemesine olanak tanıyın. Bir yarışçının aleyhine yüksek bahisler oynandığında sürekli yarış kaybetmesi gibi şike kalıplarını tespit etmek ve önlemek için oyuncu başına bahis istatistiklerini takip edin.
-- Server-side betting handler
local raceBets = {}
RegisterNetEvent('racing:placeBet')
AddEventHandler('racing:placeBet', function(raceId, targetRacerId, amount)
local src = source
if not activeRaces[raceId] then return end
if activeRaces[raceId].state ~= 'lobby' then
return notify(src, 'Betting is closed once the race starts.', 'error')
end
-- Validate the target racer is in this race
local racerFound = false
for _, racer in ipairs(activeRaces[raceId].participants) do
if racer.src == targetRacerId then racerFound = true break end
end
if not racerFound then return end
-- Check and deduct funds
local playerMoney = GetPlayerMoney(src)
if playerMoney < amount or amount < Config.MinBet then
return notify(src, 'Insufficient funds or below minimum bet.', 'error')
end
RemoveMoney(src, amount)
if not raceBets[raceId] then raceBets[raceId] = {} end
table.insert(raceBets[raceId], {
bettor = src,
target = targetRacerId,
amount = amount,
})
notify(src, ('Bet $%s on %s'):format(amount, GetPlayerName(targetRacerId)), 'success')
end)
NUI ile Yarış Arayüzü Geliştirme
Yarış UI arayüzü, ekranı doldurmadan veya sürücünün dikkatini dağıtmadan kritik gerçek zamanlı bilgileri iletmelidir. Yarışçılar arasındaki mevcut sırayı, varsa tur sayısını, mevcut sürüşü kişisel en iyi dereceyle veya pist rekoruyla karşılaştıran bir ara zamanlayıcıyı ve yaklaşan kontrol noktası yönünü vurgulayan bir minimap katmanını gösteren minimal bir HUD tasarlayın. Oyuncu tercihine göre hızı mil/saat veya km/saat cinsinden gösteren, yarış temasına uygun bir hız göstergesi kullanın. Yarış öncesindeki lobi ekranı, kayıtlı tüm katılımcıları araçlarıyla birlikte, pist adını ve mesafesini, ödül havuzu dağılımını ve bir geri sayım sayacını göstermelidir. UI arayüzünü NUI sistemini kullanarak HTML, CSS ve JavaScript ile oluşturun ve yarış durumu güncellemelerini client tarafındaki Lua dosyasından NUI frame yapısına şu yolla iletin: SendNUIMessage. Konum güncellemelerini her kare yerine saniyede 4-5 kez ile sınırlayarak kullanıcı arayüzünü duyarlı tutun: bu, görüntülenen bilgiler üzerinde gözle görülür bir etki yaratmadan NUI yükünü önemli ölçüde azaltır. Ulaşılan azami hız, ortalama hız ve kontrol noktası segmenti başına zaman karşılaştırması gibi ayrıntılı istatistikler içeren bir yarış sonrası sonuç ekranı eklemeyi değerlendirin.
Yarış Kategorileri ve Araç Sınıfları
Adil rekabet ve çeşitlilik sağlamak için yarışları farklı kategorilere ayırın. Oyunun yerel yol tutuş verilerinden alınan azami hız, ivmelenme ve kullanım puanları gibi performans ölçütlerine dayalı araç sınıfları tanımlayın. Belirli yarışlar için sınıf kısıtlamaları oluşturun, böylece Dominator kullanan bir oyuncu kompakt araçlara özel bir yarışa katılamasın veya tam tersi engellensin. Araç sınıfının ötesinde farklı yarış formatları sunun: şehir içinde A noktasından B noktasına uzanan noktadan noktaya sprintler, bir pist etrafında çok turlu pist yarışları, tepki süresi başlangıçlı düz yol kalkış (drag) yarışları ve açı, hız ile tepe noktalarına yakınlığa göre puanlanan drift mücadeleleri. Her format, puanlama ve yarış tamamlama algılaması için biraz farklı bir mantık gerektirir. Özellikle drift puanlaması, aracın hız vektörüne göre kayma açısını, drift sırasında korunan hızı ve kontrolü kaybetmeden art arda yapılan driftler için bonus çarpanlarını değerlendiren özel bir algoritma gerektirir. Yarış organizatörlerinin yetişme mekanizmaları (catch-up), kasıtlı çarpmaları önlemek için diğer yarışçıların içinden geçme (ghosting) ve atmosfer için hava durumu veya günün saati ayarları gibi seçenekleri açıp kapatmasına izin verin.
Polis Entegrasyonu ve İllegal Yarış
Sokak yarışları, emniyet güçleriyle organik etkileşimler oluşturan yasa dışı bir etkinlik olmalıdır. Bir yarış başladığında bölgedeki NPC'lerden yapılandırılabilir bir gecikmenin ardından polis ihbar sistemine düşen gürültü şikayetleri oluşturun, bu sayede yarışçılara bir avans verilir ancak daha uzun yarışların dikkat çekmesi sağlanır. Yanıt veren polis memurları, yol tuzakları kurarak, barikatlar oluşturarak veya yarışçıları tek tek kovalayarak yarışı durdurmaya çalışabilir. Bir yarışçı polis tarafından yakalanırsa para cezası, araç bağlama ve potansiyel olarak hapis cezasıyla karşılaşır: bu da yarış ortamını tehlikeli ve heyecanlı kılan gerçek sonuçlar ekler. Yarış için özel olarak, tekrarlanan ihlallerle artan bir aranma seviyesi sistemi uygulayın, böylece sürekli sokak yarışı yapanlar zamanla daha agresif polis müdahaleleri çeker. Polislerin organizatörlere karşı dosya oluşturmak için bilinen yarış noktalarındaki güvenlik kameralarını kullanmasına izin verin, bu da münferit sürücüler yerine tüm yarış ekiplerini çökerten daha büyük operasyonlarla sabırlı polis çalışmasını ödüllendiren bir soruşturma katmanı oluşturur.
Yarış İçin Performans Optimizasyonu
Yarış sistemleri akıcı bir performans gerektirir, çünkü en küçük bir gecikme bile rekabet deneyimini mahvedebilir. Checkpoint algılamasını ve konum takibini client tarafında yöneterek ve sunucuya yalnızca bir checkpoint'e ulaşıldığında veya yarış bittiğinde güncelleme göndererek aktif yarışlar sırasında sunucu ve client arasındaki iletişimi en aza indirin. Konum yayını için özel network event'leri yerine entity state bag'lerini kullanın, çünkü state bag'ler sık güncellemeler için optimize edilmiştir ve bant genişliğini daha verimli yönetir. Checkpoint çizimi için tüm checkpoint'leri aynı anda çizmek yerine yalnızca mevcut ve bir sonraki checkpoint için marker çizin ve daha uzak mesafelerde marker karmaşıklığını azaltmak için LOD (Level of Detail) mantığını kullanın. Liderlik tablolarını ve yarış listelerini tekil sorgular yerine toplu işlemlerle çekerek yarış veri isteklerinizi havuzda toplayın ve yoğun yarış saatlerinde veritabanı yükünü azaltmak için sonuçları kısa bir TTL ile client tarafında önbelleğe alın. Konum senkronizasyonunun ve checkpoint doğrulamasının FPS düşüşleri veya desenkronizasyon sorunları olmadan doğru şekilde ölçeklendiğinden emin olmak için sisteminizi yarış başına tipik olarak 8 ila 16 eşzamanlı yarışçı olan beklenen maksimum sayıyla test edin.