نظام الزراعة في FiveM: المحاصيل، الحيوانات وسلاسل البيع
إنشاء نظام زراعة عميق في FiveM. المحاصيل، المواشي، المعالجة، بيع NPCs وأفضل السكربتات الزراعية لاقتصادات لعب الأدوار الغامرة.
Agency Scripts
المؤسس والمطور الرئيسي في Agency Scripts
فلسفة تصميم نظام الزراعة
نظام الزراعة والفلاحة يجلب وتيرة مختلفة تمامًا إلى خوادم دور FiveM، مقدماً للاعبين بديلًا مريحًا للأنشطة الإجرامية عالية الأدرينالين وإنفاذ القانون. تخلق أفضل أنظمة الزراعة حلقة اقتصادية مكتفية ذاتيًا حيث يشتري اللاعبون البذور، يزرعون المحاصيل في الأراضي الزراعية المخصصة، يعتنون بها خلال دورات نمو حقيقية الوقت، يحصدون المنتجات، ويبيعونها في السوق للربح. يكمن تحدي التصميم في جعل النظام جذابًا بما يكفي ليعود اللاعبون بانتظام دون جعله مستهلكًا للوقت لدرجة الشعور بالعبء. استخدم دورات نمو حقيقية تستمر حتى عندما يكون اللاعب غير متصل، بحيث يجد المزارعون محاصيلهم في مراحل نمو مختلفة عند تسجيل الدخول. يحتاج نموذج البيانات الأساسي إلى تتبع كل قطعة مزرعة بموقعها، نوع المحصول، مرحلة النمو الحالية، الطابع الزمني للزراعة، مستوى الماء، وتقييم الجودة. خزّن كل هذا على جانب الخادم في قاعدة بيانات بحيث يستمر حالة المزرعة عبر إعادة تشغيل الخادم وتحمي من التلاعب من جانب العميل.
زراعة المحاصيل ومخطط قاعدة البيانات
يبدأ نظام الزراعة باختيار اللاعب للبذور من مخزونه ووضعها في مناطق زراعية صالحة. عرّف الأراضي الزراعية كمناطق مضلعة قابلة للتكوين على الخريطة حيث يُسمح بالزراعة، مما يمنع اللاعبين من زراعة المحاصيل على الأرصفة أو داخل المباني. يجب أن يحتوي كل قطعة أرض زراعية على عدد محدود من الفتحات بناءً على حجم الأرض، ويمكن للاعبين استئجار أو شراء الأراضي الزراعية من خلال NPC أو نظام العقارات. عند زرع اللاعب لبذرة، يتم إنشاء سجل في قاعدة البيانات يتتبع المحصول طوال دورة حياته. فيما يلي مخطط قاعدة بيانات عملي ومعالج الزراعة على جانب الخادم:
CREATE TABLE IF NOT EXISTS farm_crops (
id INT AUTO_INCREMENT PRIMARY KEY,
owner VARCHAR(50) NOT NULL,
farm_id VARCHAR(50) NOT NULL,
crop_type VARCHAR(50) NOT NULL,
position_x FLOAT NOT NULL,
position_y FLOAT NOT NULL,
position_z FLOAT NOT NULL,
planted_at BIGINT NOT NULL,
growth_stage INT DEFAULT 0,
water_level FLOAT DEFAULT 100.0,
quality FLOAT DEFAULT 1.0,
is_harvestable TINYINT DEFAULT 0,
is_dead TINYINT DEFAULT 0,
last_watered BIGINT DEFAULT 0,
INDEX idx_owner (owner),
INDEX idx_farm (farm_id)
);
CREATE TABLE IF NOT EXISTS farm_plots (
id INT AUTO_INCREMENT PRIMARY KEY,
farm_id VARCHAR(50) NOT NULL UNIQUE,
owner VARCHAR(50) DEFAULT NULL,
max_slots INT DEFAULT 20,
rent_price INT DEFAULT 500,
coords_center_x FLOAT NOT NULL,
coords_center_y FLOAT NOT NULL,
coords_center_z FLOAT NOT NULL,
radius FLOAT DEFAULT 30.0
);
RegisterNetEvent('farming:server:plantCrop', function(cropType, position)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local citizenid = Player.PlayerData.citizenid
local seedItem = 'seed_' .. cropType
if not Player.Functions.GetItemByName(seedItem) then
return TriggerClientEvent('QBCore:Notify', src, 'You need seeds to plant', 'error')
end
local farmId = GetFarmAtPosition(position)
if not farmId then
return TriggerClientEvent('QBCore:Notify', src, 'You can only plant on farmland', 'error')
end
local currentCrops = MySQL.scalar.await(
'SELECT COUNT(*) FROM farm_crops WHERE farm_id = ? AND is_dead = 0',
{farmId}
)
local maxSlots = MySQL.scalar.await(
'SELECT max_slots FROM farm_plots WHERE farm_id = ?', {farmId}
)
if currentCrops >= maxSlots then
return TriggerClientEvent('QBCore:Notify', src, 'Farm is full', 'error')
end
Player.Functions.RemoveItem(seedItem, 1)
MySQL.insert(
'INSERT INTO farm_crops (owner, farm_id, crop_type, position_x, position_y, position_z, planted_at, last_watered) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
{citizenid, farmId, cropType, position.x, position.y, position.z, os.time(), os.time()}
)
TriggerClientEvent('QBCore:Notify', src, 'Planted ' .. cropType, 'success')
TriggerClientEvent('farming:client:spawnCropProp', -1, position, cropType, 0)
end)
يجب أن يكون لكل نوع محصول معلمات نمو مختلفة محددة في جدول التكوين. قد ينمو القمح في 30 دقيقة حقيقية عبر 4 مراحل، بينما قد يستغرق القنب أو العنب عدة ساعات مع 6 مراحل، مما يكافئ المزارعين الصبورين بمنتجات ذات قيمة أعلى. تحدد مرحلة النمو نموذج الدعامة المعروض في العالم، حيث ينتقل من برعم صغير إلى نبات مكتمل النمو مع تقدم الوقت.
محرك دورة النمو والري
محرك دورة النمو هو حلقة على جانب السيرفر تتحقق دوريًا من كل المحاصيل المزروعة وتقدم مراحل نموها بناءً على الوقت المنقضي وظروف مثل مستوى الماء. يشغل هذا كخيط سيرفر مؤقت ينفذ كل بضع دقائق، يحسب ما إذا كان يجب لكل محصول التقدم إلى المرحلة التالية بناءً على مدة نمو نوع المحصول والوقت منذ الزراعة. مستوى الماء هو الميكانيكية الأساسية التي تبقي اللاعبين منخرطين: المحاصيل تستهلك الماء مع الوقت، وإذا انخفض مستوى الماء إلى الصفر، يتوقف النمو وتتدهور جودة المحصول. يجب على اللاعبين العودة إلى مزرعتهم واستخدام علبة ري أو نظام ري لتجديد مستويات الماء. هذا هو محرك النمو على جانب السيرفر:
local CropConfig = {
wheat = {
stages = 4,
growthTime = 1800, -- 30 min total, ~7.5 min per stage
waterConsumption = 5, -- per cycle
baseYield = 5,
sellPrice = 50
},
corn = {
stages = 5,
growthTime = 3600,
waterConsumption = 7,
baseYield = 4,
sellPrice = 80
},
tomato = {
stages = 4,
growthTime = 2400,
waterConsumption = 8,
baseYield = 6,
sellPrice = 65
},
grape = {
stages = 6,
growthTime = 7200,
waterConsumption = 4,
baseYield = 8,
sellPrice = 120
}
}
CreateThread(function()
while true do
Wait(60000 * 5) -- Run every 5 minutes
local crops = MySQL.query.await(
'SELECT * FROM farm_crops WHERE is_dead = 0 AND is_harvestable = 0'
)
for _, crop in ipairs(crops or {}) do
local config = CropConfig[crop.crop_type]
if not config then goto continue end
local elapsed = os.time() - crop.planted_at
local stageTime = config.growthTime / config.stages
local expectedStage = math.min(math.floor(elapsed / stageTime), config.stages)
-- Degrade water
local newWater = math.max(0, crop.water_level - config.waterConsumption)
local newQuality = crop.quality
-- Quality degrades without water
if newWater <= 0 then
newQuality = math.max(0.3, crop.quality - 0.05)
expectedStage = crop.growth_stage -- Pause growth
end
local isHarvestable = expectedStage >= config.stages and newWater > 0
if expectedStage ~= crop.growth_stage or newWater ~= crop.water_level then
MySQL.update(
'UPDATE farm_crops SET growth_stage = ?, water_level = ?, quality = ?, is_harvestable = ? WHERE id = ?',
{expectedStage, newWater, newQuality, isHarvestable and 1 or 0, crop.id}
)
if expectedStage ~= crop.growth_stage then
TriggerClientEvent('farming:client:updateCropStage', -1,
crop.id, expectedStage, crop.crop_type,
vector3(crop.position_x, crop.position_y, crop.position_z))
end
end
:continue:
end
end
end)
يجب أن يشعر ميكانيك الري بالتفاعل بدلاً من الملل. امنح اللاعب عنصر علبة ري يحفز حركة عند استخدامه بالقرب من المحاصيل، ويسقي عدة محاصيل قريبة في إجراء واحد بدلاً من الري واحدًا تلو الآخر. للمزارع الكبيرة، قدم ترقية نظام ري تسقي تلقائيًا جميع المحاصيل في القطعة على فترات منتظمة، مما يقلل العمل اليدوي لكنه يتطلب استثمارًا مبدئيًا في المواد. اعرض مستوى ماء كل محصول وتقدم نموه من خلال مؤشر صغير فوق العنصر عندما ينظر اللاعب إليه، باستخدام نص ثلاثي الأبعاد أو تراكب نظام استهداف.
الحصاد وجودة الإنتاج
الحصاد هو لحظة المكافأة التي تجعل حلقة الزراعة بأكملها مرضية. عندما تصل المحصول إلى مرحلته النهائية من النمو وتمت ريّه بشكل كافٍ، يصبح قابلاً للحصاد. يتفاعل اللاعب مع المحصول، يلعب رسومًا متحركة للحصاد، ويتلقى عناصر الإنتاج في مخزونه. تعتمد كمية وجودة الإنتاج على مدى اهتمام اللاعب بالمحصول خلال دورة نموه: الري المنتظم ينتج عناصر ذات جودة أعلى تُباع بسعر أعلى، بينما المحاصيل المهملة تنتج عناصر أقل جودة وأقل كمية. نفذ مضاعف جودة يؤثر على كل من عدد الإنتاج وسعر البيع، مما يخلق حافزًا قويًا للزراعة الدقيقة. بعد الحصاد، قم بإزالة المحصول من قاعدة البيانات وحذف العنصر من العالم، مما يحرر مكان القطعة لإعادة الزراعة. فكر في إضافة آلية تحويل النفايات حيث يمكن تحويل المحاصيل منخفضة الجودة إلى سماد يعزز جودة المحاصيل المستقبلية، مما يخلق حلقة صفر نفايات تكافئ النشاط الزراعي المستمر.
نظام تربية الحيوانات
تضيف الحيوانات بعدًا ثانيًا لتجربة الزراعة وتخلق مصادر دخل إضافية. نفذ حيوانات قابلة للشراء مثل الدجاج، الأبقار، والأغنام التي توضع في حظائر مخصصة على الأرض الزراعية. لكل نوع حيواني دورة إنتاج خاصة به: ينتج الدجاج البيض كل عدة ساعات، تنتج الأبقار الحليب يوميًا، ويمكن حلاقة الأغنام للحصول على الصوف بشكل دوري. تحتاج الحيوانات إلى التغذية من مخزون منتجات اللاعب، مما يربط نظام المحاصيل مباشرة بنظام الحيوانات ويخلق حلقة اقتصادية مغلقة. إليك نظام تكوين وتغذية للحيوانات الزراعية:
Config.Animals = {
chicken = {
model = 'a_c_hen',
purchasePrice = 500,
feedItem = 'wheat',
feedInterval = 3600, -- needs feeding every hour
productionItem = 'eggs',
productionAmount = 3,
productionInterval = 7200, -- produces every 2 hours
maxPerFarm = 10
},
cow = {
model = 'a_c_cow',
purchasePrice = 3000,
feedItem = 'corn',
feedInterval = 5400,
productionItem = 'milk',
productionAmount = 2,
productionInterval = 14400,
maxPerFarm = 5
},
sheep = {
model = 'a_c_sheep',
purchasePrice = 1500,
feedItem = 'wheat',
feedInterval = 4800,
productionItem = 'wool',
productionAmount = 1,
productionInterval = 21600,
maxPerFarm = 8
}
}
RegisterNetEvent('farming:server:feedAnimal', function(animalId)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local animal = MySQL.query.await(
'SELECT * FROM farm_animals WHERE id = ? AND owner = ?',
{animalId, Player.PlayerData.citizenid}
)
if not animal or not animal[1] then return end
animal = animal[1]
local config = Config.Animals[animal.animal_type]
if not Player.Functions.GetItemByName(config.feedItem) then
return TriggerClientEvent('QBCore:Notify', src, 'Need ' .. config.feedItem .. ' to feed', 'error')
end
Player.Functions.RemoveItem(config.feedItem, 1)
MySQL.update(
'UPDATE farm_animals SET last_fed = ?, hunger = 100 WHERE id = ?',
{os.time(), animalId}
)
TriggerClientEvent('QBCore:Notify', src, 'Animal fed successfully', 'success')
end)
الحيوانات التي لا تُطعم في الوقت المحدد تصبح غير سعيدة، مما يقلل من إنتاجها. إذا تُركت بدون تغذية لفترة طويلة، تتوقف عن الإنتاج تمامًا. عرض حالة الحيوان من خلال تفاعل الهدف الذي يظهر مستوى الجوع، السعادة، والوقت حتى الإنتاج التالي. يخلق هذا روتين تسجيل يومي للمزارعين يبقيهم منخرطين مع الخادم بين دورات نمو المحاصيل.
نظام السوق وبيع المنتجات
يربط نظام السوق المزارعين بالاقتصاد الأوسع للخادم. أنشئ مواقع بائعين NPC في أسواق المزارعين، متاجر البقالة، والمطاعم حول الخريطة حيث يمكن للاعبين بيع منتجاتهم. نفذ نظام تسعير ديناميكي حيث تتقلب الأسعار بناءً على العرض والطلب: إذا كان العديد من المزارعين يزرعون القمح، تنخفض أسعار القمح، مما يشجع على تنوع المحاصيل. تتبع حجم المبيعات الإجمالي لكل نوع محصول خلال نوافذ زمنية متداولة واضبط الأسعار وفقًا لذلك. تبيع المنتجات الممتازة من المحاصيل عالية الجودة بضرب سعر أعلى من السعر الأساسي، مما يكافئ الزراعة الدقيقة. فكر في إضافة خيار تجارة لاعب إلى لاعب حيث يمكن للمزارعين إنشاء أكشاك سوق في مناطق مخصصة، يبيعون مباشرة للاعبين الآخرين بأسعار مخصصة. هذا يخلق تفاعلات لعب أدوار عضوية بين المزارعين والمشترين، ويسمح للاعبين الطموحين بالربح عن طريق شراء المنتجات بالجملة الرخيصة وبيعها بزيادة التجزئة في المناطق ذات الحركة العالية.
تأثيرات الطقس على الزراعة
تكامل الطقس يضيف عنصر عدم التنبؤ والاستراتيجية للزراعة. اربط نظام الطقس في سيرفرك لتطبيق تعديلات على نمو المحاصيل واستهلاك المياه. المطر يروي جميع المحاصيل الخارجية بشكل طبيعي، مما يقلل الحاجة للري اليدوي خلال الفترات الممطرة. الحرارة الشديدة تزيد من استهلاك المياه، مما يجبر المزارعين على الري بشكل أكثر تكرارًا خلال الطقس الحار. العواصف يمكن أن تلحق أضرارًا بالمحاصيل، مما يقلل الجودة أو حتى يدمر المنتجات غير المحصودة التي تُركت لفترة طويلة. أحداث الصقيع خلال مواسم الشتاء يمكن أن تقتل أنواعًا معينة من المحاصيل بالكامل، مما يتطلب من المزارعين اختيار أصناف مقاومة للبرد أو الاستثمار في هياكل دفيئة تحمي المحاصيل من تأثيرات الطقس. نفذ نظام توقعات الطقس يمكن الوصول إليه عبر تطبيق هاتف داخل اللعبة أو بث تلفزيوني حتى يتمكن المزارعون من تخطيط جدول الزراعة بناءً على الظروف القادمة، مضيفًا طبقة تخطيط استراتيجية ترفع تجربة الزراعة إلى ما هو أبعد من ميكانيكيات النقر والانتظار البسيطة.
ترقيات المزرعة والتقدم
يمنح نظام التقدم للمزارعين أهدافاً طويلة الأمد ومكافآت للعب المستمر. يبدأ اللاعبون بقطعة أرض صغيرة يمكنها استيعاب عدد قليل من المحاصيل، ثم يتيح لهم كسب توسعات من خلال خبرة الزراعة أو الشراء المباشر. يفتح كل مستوى ترقية قدرات جديدة: أنظمة رش أوتوماتيكية تتولى الري، حظائر حيوانات أكبر لمزيد من الماشية، حظيرة لتخزين الفائض من المنتجات، محطات معالجة تحول المواد الخام إلى سلع ذات قيمة أعلى مثل القمح إلى دقيق أو العنب إلى نبيذ، ومركبة جرار تسرع الزراعة والحصاد عبر قطع كبيرة. تتبع خبرة الزراعة بشكل منفصل عن تقدم الخادم الآخر لإنشاء مهارة زراعية مخصصة تحسن جودة المحصول وتقلل أوقات النمو في المستويات الأعلى. نظام المعالجة مهم بشكل خاص للاقتصاد لأنه يضيف خطوات ذات قيمة مضافة بين المنتجات الخام والسلع النهائية، مما يخلق فرصاً لتمثيل سلسلة التوريد حيث يبيع المزارعون المواد الخام للمخابز، مصانع النبيذ، أو المطاعم المملوكة للاعبين التي تحولها إلى منتجات نهائية للمستهلكين.