نظام السباقات في FiveM: المسارات، لوحات الصدارة والرهانات
إضافة سباقات الشوارع إلى خادم FiveM الخاص بك. منشئو المسارات، نقاط التفتيش، الرهانات، لوحات الصدارة وأفضل سكربتات السباقات لمجتمعات التعديل الجادة.
Agency Scripts
المؤسس والمطور الرئيسي في Agency Scripts
تصميم نظام إنشاء السباقات
نظام سباق شارع جذاب يبدأ بمنح اللاعبين القدرة على إنشاء وإدارة مسارات السباق الخاصة بهم. بدلاً من الاعتماد فقط على المسارات المعرفة مسبقًا، تسمح أفضل نصوص السباق للمنظمين بوضع نقاط تفتيش ديناميكيًا عن طريق القيادة على طول المسار وتحديد المواقع. يخزن كل سباق كهيكل بيانات يحتوي على معرف فريد، معرف اللاعب المنشئ، اسم، قائمة مرتبة بإحداثيات نقاط التفتيش مع زوايا التوجيه، وبيانات وصفية مثل المسافة والوقت المقدر للدورة. يجب أن تكون عملية الإنشاء بديهية: يدخل اللاعب وضع محرر السباق، يقود إلى كل نقطة تفتيش، يؤكد الموقع بزر، وينهي بالعودة إلى خط البداية. احفظ السباقات المكتملة في قاعدة بياناتك لتستمر عبر إعادة تشغيل الخادم ويمكن مشاركتها مع المجتمع. نفذ نظام مراجعة حيث يمكن للمسؤولين الموافقة على المسارات التي ينشئها اللاعبون قبل ظهورها في قائمة السباقات العامة، لمنع التخريب عبر تصميم مسارات مستحيلة أو غير عادلة.
نظام نقاط التفتيش ومنطق السباق
نقاط التفتيش هي الميكانيكية الأساسية التي تتحقق من تقدم السباق وتمنع الاختصارات. يجب تعريف كل نقطة تفتيش كمنطقة ثلاثية الأبعاد مع نصف قطر قابل للتعديل، عادة بين 8 و15 مترًا حسب عرض الطريق. استخدم دوال رسم العلامات الأصلية في GTA لعرض نقاط التفتيش بصريًا، مع تمييز نقطة التفتيش الحالية بلون ساطع وعرض النقطة التالية كمعاينة شفافة. تتبع تقدم كل متسابق عبر قائمة نقاط تفتيش مفهرسة، وتقدمهم فقط عندما يدخلون منطقة نقطة التفتيش التالية الصحيحة بالتسلسل. نفذ تدابير مكافحة الغش بتتبع الوقت بين نقاط التفتيش ووضع علامة أو استبعاد المتسابقين الذين يكملون المقاطع بسرعة مستحيلة، مما يشير إلى التنقل الفوري أو الغش في السرعة.
-- 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)
نظام لوحة المتصدرين والترتيب
تدفع لوحات المتصدرين المنافسة وتحافظ على عودة اللاعبين لتحسين أوقاتهم. خزّن نتائج السباقات في جدول قاعدة بيانات يسجل معرف اللاعب، معرف السباق، وقت الإنجاز بالميلي ثانية، طراز المركبة المستخدمة، التاريخ، وما إذا كانت الجولة أفضل أداء شخصي. عرض لوحات المتصدرين عبر واجهة NUI تظهر أفضل الأوقات لكل مسار، قابلة للتصفية حسب فئة المركبة ليتمكن اللاعبون من المقارنة بشكل عادل ضمن فئات مثل الرياضة، السوبر، العضلية، أو المدمجة. نفذ نظام ترتيب موسمي يعيد التعيين دوريًا للحفاظ على المنافسة حية، مع الحفاظ على لوحة سجلات دائمة للحقوق التاريخية في التفاخر. احسب تصنيف سباق بأسلوب ELO بناءً على الأداء وجهاً لوجه في السباقات متعددة اللاعبين، مما يمنح المتسابقين المهرة رتبة مرئية تزيد عند هزيمة خصوم أعلى رتبة وتنقص عند الخسارة أمام خصوم أقل رتبة. عرض هذا التصنيف على واجهة السباق واستخدمه للمطابقة الاختيارية عند تنظيم سباقات عشوائية.
نظام المراهنات والجوائز
نظام المراهنات يضيف رهانات مالية للسباقات ويربط مشهد السباقات باقتصاد خادمك الأوسع. يسمح لمنظمي السباقات بتحديد رسوم دخول يجب على جميع المشاركين دفعها، مع توزيع الجائزة الإجمالية بين الفائزين الثلاثة الأوائل وفقًا لتقسيم قابل للتكوين مثل 70-20-10 للمركز الأول والثاني والثالث. ينفذ نظام مراهنات للمشاهدين حيث يمكن للاعبين غير المشاركين المراهنة على النتيجة، باختيار متسابق لدعمه بأموالهم. استخدم منطق جانب الخادم حصريًا لجميع المعاملات المالية لمنع الاستغلال. أضف حصة منزلية بنسبة 5-10% على جميع الرهانات لتعمل كمصرف مالي لاقتصادك. للأحداث المنظمة الأكبر، اسمح للمسؤولين بإضافة جوائز إضافية ممولة من خزينة الخادم. تتبع إحصائيات المراهنات لكل لاعب لاكتشاف ومنع أنماط التلاعب بالمباريات، مثل متسابق يخسر باستمرار سباقات توضع عليها رهانات كبيرة ضده.
-- 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
تحتاج واجهة المستخدم للسباق إلى نقل معلومات حاسمة في الوقت الفعلي دون ازدحام الشاشة أو تشتيت السائق. صمم HUD بسيطًا يعرض المركز الحالي بين المتسابقين، رقم اللفة إذا كان ذلك مناسبًا، مؤقت تقسيم يقارن الأداء الحالي مع أفضل أداء شخصي أو رقم قياسي للمسار، وطبقة خريطة مصغرة تبرز اتجاه نقطة التفتيش القادمة. استخدم عداد سرعة يتناسب مع موضوع السباق، يعرض السرعة إما بالأميال في الساعة أو بالكيلومترات في الساعة بناءً على تفضيل اللاعب. يجب أن تعرض شاشة الردهة قبل السباق جميع المشاركين المسجلين مع مركباتهم، اسم المسار والمسافة، توزيع جوائز المسابقة، ومؤقت العد التنازلي. ابني واجهة المستخدم باستخدام HTML وCSS وJavaScript باستخدام نظام NUI، وتواصل تحديثات حالة السباق من Lua على جانب العميل إلى إطار NUI عبر SendNUIMessage. حافظ على استجابة واجهة المستخدم عن طريق تقليل تحديثات الموقع إلى 4-5 مرات في الثانية بدلاً من كل إطار، مما يقلل بشكل كبير من عبء NUI دون أي تأثير مرئي على المعلومات المعروضة. فكر في إضافة شاشة نتائج بعد السباق مع إحصائيات مفصلة مثل أعلى سرعة تم الوصول إليها، السرعة المتوسطة، والمقارنة الزمنية لكل جزء من نقاط التفتيش.
فئات السباق وفئات المركبات
نظم السباقات إلى فئات مميزة لضمان منافسة عادلة وتنوع. حدد فئات المركبات بناءً على مقاييس الأداء مثل السرعة القصوى، التسارع، وتصنيفات التحكم المستمدة من بيانات التحكم الأصلية للعبة. أنشئ قيودًا على الفئات لسباقات محددة بحيث لا يمكن للاعب بسيارة Dominator دخول سباق مخصص للسيارات الصغيرة، والعكس صحيح. بالإضافة إلى فئة المركبة، قدم تنسيقات سباق مختلفة: سباقات نقطة إلى نقطة من A إلى B عبر المدينة، سباقات الحلبة مع عدة لفات حول حلقة، سباقات السحب على طرق مستقيمة مع بدايات تعتمد على زمن رد الفعل، ومسابقات الانجراف التي تُسجل حسب الزاوية، السرعة، والقرب من نقاط القص. يتطلب كل تنسيق منطقًا مختلفًا قليلاً للتسجيل والكشف عن الانتهاء. يحتاج تسجيل الانجراف بشكل خاص إلى خوارزمية مخصصة تقيم زاوية الانزلاق للمركبة نسبة إلى متجه السرعة، السرعة المحفوظة أثناء الانجراف، ومضاعفات المكافأة لسلسلة الانجرافات المتتالية دون فقدان السيطرة. اسمح لمنظمي السباقات بتبديل خيارات مثل ميكانيكيات اللحاق، المرور عبر المتسابقين لمنع التصادمات المتعمدة، وإعدادات الطقس أو الوقت لخلق الجو المناسب.
تكامل الشرطة والسباقات غير القانونية
يجب أن يكون سباق الشوارع نشاطًا غير قانوني يخلق تفاعلات عضوية مع قوات القانون. عند بدء السباق، يتم توليد شكاوى ضوضاء من NPCs في المنطقة تظهر على نظام إيفاد الشرطة بعد تأخير قابل للتكوين، مما يمنح المتسابقين بداية مبكرة لكنه يضمن أن السباقات الأطول تجذب الانتباه. يمكن لضباط الشرطة الذين يستجيبون محاولة إيقاف السباق عن طريق نشر شرائط مسامير، إقامة حواجز على الطرق، أو ملاحقة المتسابقين الفرديين. إذا تم القبض على متسابق من قبل الشرطة، يواجه غرامات، حجز المركبة، وربما السجن، مما يضيف عواقب حقيقية تجعل مشهد السباق يشعر بالخطر والإثارة. نفذ نظام مستوى مطلوب خصيصًا للسباق يتصاعد مع التكرار، بحيث يجذب المتسابقون المتكررون ردود فعل شرطة أكثر عدوانية مع مرور الوقت. اسمح للشرطة باستخدام كاميرات المراقبة في مواقع السباق المعروفة لبناء قضايا ضد المنظمين، مما يخلق طبقة تحقيق تكافئ العمل الشرطي الصبور بمداهمات أكبر تسقط فرق السباق بأكملها بدلاً من السائقين الفرديين.
تحسين الأداء للسباقات
تتطلب أنظمة السباق أداءً سلسًا حيث يمكن أن يفسد التأخير الطفيف تجربة المنافسة. قلل من التواصل بين الخادم والعميل أثناء السباقات النشطة من خلال التعامل مع اكتشاف نقاط التفتيش وتتبع المواقع على جانب العميل، وإرسال التحديثات إلى الخادم فقط عند الوصول إلى نقطة تفتيش أو انتهاء السباق. استخدم حقائب حالة الكيان لبث المواقع بدلاً من أحداث الشبكة المخصصة، حيث أن حقائب الحالة مُحسّنة للتحديثات المتكررة وتتعامل مع عرض النطاق الترددي بشكل أكثر كفاءة. بالنسبة لرسم نقاط التفتيش، ارسم علامات لنقطة التفتيش الحالية والتالية فقط بدلاً من جميع نقاط التفتيش في نفس الوقت، واستخدم منطق LOD (مستوى التفاصيل) لتقليل تعقيد العلامات على مسافات أبعد. اجمع طلبات بيانات السباق الخاصة بك عن طريق جلب قوائم المتصدرين وقوائم السباق في عمليات مجمعة بدلاً من الاستعلامات الفردية، واحفظ النتائج على جانب العميل مع TTL قصير لتقليل حمل قاعدة البيانات خلال ساعات الذروة. اختبر نظامك مع الحد الأقصى المتوقع لعدد المتسابقين المتزامنين، عادة 8-16 لكل سباق، لضمان أن تزامن المواقع والتحقق من نقاط التفتيش يعمل بشكل صحيح دون انخفاض في الإطارات أو مشاكل في عدم التزامن.