Sistema de agricultura para FiveM: cultivos, animales y cadenas de venta
Crea un sistema de agricultura completo para FiveM. Cultivos, ganado, procesamiento, NPC vendedores y los mejores scripts para economías de rol inmersivas.
Agency Scripts
Fundador y desarrollador principal en Agency Scripts
Filosofía de diseño del sistema de agricultura
Un sistema de agricultura y cultivo aporta un ritmo completamente diferente a los servidores de roleplay de FiveM, y ofrece a los jugadores una alternativa relajante a las actividades delictivas de alto riesgo y a las fuerzas del orden. Los mejores sistemas de agricultura crean un ciclo económico autosostenible en el que los jugadores compran semillas, plantan cultivos en terrenos agrícolas designados, los cuidan durante ciclos de crecimiento en tiempo real, cosechan los productos y los venden en el mercado para obtener ganancias. El reto del diseño consiste en hacer que el sistema sea lo bastante atractivo para que los jugadores vuelvan con regularidad, sin exigir tanto tiempo que se convierta en una tarea tediosa. Usa ciclos de crecimiento en tiempo real que continúen incluso cuando el jugador esté desconectado, para que los agricultores entren y encuentren sus cultivos en distintas etapas de crecimiento. El modelo de datos principal debe registrar cada parcela individual con su posición, tipo de cultivo, etapa de crecimiento actual, fecha y hora de plantación, nivel de agua y valoración de calidad. Guarda todos estos datos en una base de datos del servidor para que el estado de la granja persista tras los reinicios del servidor y esté protegido frente a manipulaciones del cliente.
Plantación de cultivos y esquema de base de datos
El sistema de plantación comienza cuando el jugador selecciona semillas de su inventario y las coloca en zonas de terreno agrícola válidas. Define los terrenos agrícolas como zonas poligonales configurables del mapa donde se permite plantar, para evitar que los jugadores cultiven en las aceras o dentro de edificios. Cada parcela debe tener un número limitado de espacios según el tamaño del terreno, y los jugadores pueden alquilar o comprar terrenos agrícolas a través de un NPC o un sistema inmobiliario. Cuando un jugador planta una semilla, crea un registro en la base de datos que siga el cultivo durante todo su ciclo de vida. Aquí tienes un esquema práctico de base de datos y el controlador de plantación del lado del servidor:
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)
Cada tipo de cultivo debe tener distintos parámetros de crecimiento definidos en una tabla de configuración. El trigo podría crecer en 30 minutos de tiempo real y pasar por 4 etapas, mientras que el cannabis o las uvas podrían tardar varias horas y pasar por 6 etapas, recompensando a los agricultores pacientes con productos de mayor valor. La etapa de crecimiento determina qué modelo de objeto se muestra en el mundo, pasando de un pequeño brote a una planta adulta a medida que avanza el tiempo.
Motor de ciclo de crecimiento y riego
El motor del ciclo de crecimiento es un bucle del lado del servidor que comprueba periódicamente todos los cultivos plantados y avanza sus etapas de crecimiento según el tiempo transcurrido y condiciones como el nivel de agua. Ejecútalo como un hilo temporizado del servidor que se active cada pocos minutos y calcule si cada cultivo debe avanzar a la siguiente etapa según la duración de crecimiento de su tipo y el tiempo transcurrido desde la plantación. El nivel de agua es la mecánica principal para mantener a los jugadores involucrados: los cultivos consumen agua con el tiempo y, si el nivel de agua llega a cero, el crecimiento se detiene y la calidad del cultivo disminuye. Los jugadores deben volver a su granja y usar una regadera o un sistema de riego para reponer el agua. Aquí tienes el motor de crecimiento del lado del servidor:
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)
La mecánica de riego debe resultar interactiva, no tediosa. Dale al jugador una regadera que active una animación cuando se use cerca de los cultivos y permita regar varios cultivos cercanos en una sola acción, en lugar de exigir que se rieguen uno por uno. En las granjas más grandes, incorpora una mejora del sistema de riego que riegue automáticamente todos los cultivos de la parcela a intervalos regulares. Así se reduce el trabajo manual, pero se requiere una inversión inicial en materiales. Muestra el nivel de agua y el progreso de crecimiento de cada cultivo mediante un pequeño indicador sobre el objeto cuando el jugador lo mire, usando texto 3D o una superposición del sistema de interacción.
Cosecha y calidad de los productos
La cosecha es el momento culminante que hace que todo el ciclo de agricultura resulte satisfactorio. Cuando un cultivo llega a su última etapa de crecimiento y ha recibido suficiente agua, está listo para cosechar. El jugador interactúa con el cultivo, reproduce una animación de cosecha y recibe productos en su inventario. La cantidad y la calidad de los productos dependen de lo bien que el jugador haya cuidado el cultivo durante su ciclo de crecimiento: regarlo de forma constante produce artículos de mayor calidad que se venden por más, mientras que los cultivos descuidados producen menos artículos de menor calidad. Implementa un multiplicador de calidad que afecte tanto la cantidad obtenida como el precio de venta, creando un fuerte incentivo para cuidar bien los cultivos. Después de cosechar, elimina el cultivo de la base de datos y borra el objeto del mundo para liberar el espacio de la parcela y poder volver a plantar. Considera añadir una mecánica de compostaje en la que las cosechas de baja calidad se conviertan en fertilizante para mejorar la calidad de futuros cultivos, creando un ciclo sin desperdicios que recompense la actividad agrícola constante.
Sistema de ganadería
Los animales añaden una segunda dimensión a la experiencia agrícola y crean fuentes de ingresos adicionales. Implementa animales que se puedan comprar, como gallinas, vacas y ovejas, y que se coloquen en corrales designados del terreno agrícola. Cada tipo de animal tiene su propio ciclo de producción: las gallinas ponen huevos cada pocas horas, las vacas producen leche a diario y las ovejas se pueden esquilar periódicamente para obtener lana. Los animales necesitan alimento del inventario de productos del jugador, lo que conecta directamente el sistema de cultivos con el sistema de animales y crea un ciclo económico cerrado. Aquí tienes una configuración y un sistema de alimentación para los animales de granja:
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)
Los animales que no reciben alimento a tiempo se ponen descontentos y producen menos. Si pasan demasiado tiempo sin comer, dejan de producir por completo. Muestra el estado del animal mediante una interacción de objetivo que indique el nivel de hambre, la felicidad y el tiempo hasta la siguiente producción. Esto crea una rutina diaria de visitas para los agricultores y los mantiene involucrados en el servidor entre ciclos de crecimiento de los cultivos.
Sistema de mercado y venta de productos
El sistema de mercado conecta a los agricultores con la economía general del servidor. Crea ubicaciones de vendedores NPC en mercados agrícolas, tiendas de comestibles y restaurantes repartidos por el mapa donde los jugadores puedan vender sus productos. Implementa un sistema de precios dinámico en el que los precios fluctúen según la oferta y la demanda: si muchos agricultores cultivan trigo, el precio del trigo baja, lo que incentiva la diversidad de cultivos. Registra el volumen total de ventas de cada tipo de cultivo en periodos móviles y ajusta los precios en consecuencia. Los productos de cultivos de alta calidad se venden con un multiplicador superior al precio base, lo que recompensa a los agricultores cuidadosos. Considera añadir una opción de comercio entre jugadores en la que los agricultores puedan instalar puestos de mercado en zonas designadas y vender directamente a otros jugadores a precios personalizados. Esto crea interacciones de roleplay espontáneas entre agricultores y compradores, y permite que los jugadores emprendedores ganen dinero comprando productos al por mayor a bajo precio y vendiéndolos con un margen minorista en zonas concurridas.
Efectos del clima en la agricultura
La integración del clima añade imprevisibilidad y estrategia a la agricultura. Conéctate al sistema meteorológico del servidor para aplicar modificadores al crecimiento de los cultivos y al consumo de agua. La lluvia riega de forma natural todos los cultivos al aire libre y reduce la necesidad de riego manual durante los periodos lluviosos. El calor extremo aumenta el consumo de agua, lo que obliga a los agricultores a regar con más frecuencia cuando hace calor. Las tormentas pueden dañar los cultivos, reducir su calidad o incluso destruir los productos sin cosechar que se hayan dejado demasiado tiempo. Las heladas durante el invierno pueden acabar por completo con ciertos tipos de cultivos, por lo que los agricultores deben elegir variedades resistentes al frío o invertir en invernaderos que protejan los cultivos de las condiciones meteorológicas. Implementa un sistema de pronóstico del tiempo accesible desde una aplicación del teléfono del juego o una emisión de televisión para que los agricultores puedan planificar sus siembras según las condiciones previstas. Así se añade una capa de planificación estratégica que lleva la experiencia agrícola más allá de simples mecánicas de pulsar y esperar.
Mejoras y progresión de la granja
Un sistema de progresión ofrece a los agricultores objetivos a largo plazo y recompensa el juego constante. Empieza a los jugadores con una parcela pequeña en la que quepan unos pocos cultivos y luego permíteles conseguir ampliaciones mediante XP de agricultura o comprándolas directamente. Cada nivel de mejora desbloquea nuevas capacidades: sistemas de aspersores automatizados que se encargan del riego, corrales más grandes para tener más ganado, un granero para almacenar excedentes de productos, estaciones de procesamiento que convierten materias primas en productos de mayor valor, como trigo en harina o uvas en vino, y un tractor que acelera la siembra y la cosecha en parcelas grandes. Registra los XP de agricultura por separado del resto de la progresión del servidor para crear una habilidad de agricultura específica que mejore la calidad de la cosecha y reduzca los tiempos de crecimiento en los niveles más altos. El sistema de procesamiento es especialmente importante para la economía porque añade etapas que aportan valor entre las materias primas y los productos acabados. Así se crean oportunidades para el roleplay de la cadena de suministro, en el que los agricultores venden materias primas a panaderías, bodegas o restaurantes propiedad de jugadores, que las transforman en productos finales para los consumidores.