Le système de biologiste Metin2 est une boucle classique où un PNJ confie au joueur des missions de collecte quotidiennes et distribue des récompenses par paliers en échange des matériaux rendus. Le biologiste (parfois appelé « érudit ») demande au joueur un certain matériau de chasse dans une certaine quantité ; une fois que le joueur l'a rassemblé et livré, il reçoit sa récompense et passe au palier suivant. Dans ce guide, je vous montre comment construire le système de zéro avec le moteur de quêtes (Lua) : les paliers de récompenses, le reset quotidien et une conception à l'épreuve des exploits, étape par étape.
Comment fonctionne le système de biologiste ?
La logique est essentiellement une simple boucle collecter–rendre–progresser. Le système comporte trois parties principales :
- Le PNJ — le biologiste auquel le joueur parle. Il possède un
vnum, et la quête se branche sur les événementschatetclickde ce vnum. - Le matériau demandé — généralement un enregistrement
item_protolâché par les monstres (un organe, une plante ou un échantillon, par exemple). Chaque palier peut demander un matériau et une quantité différents. - Les données de progression — à quel palier se trouve le joueur et s'il a utilisé sa remise du jour. On les garde dans des flags de quête (
pc.setqf/pc.getqf).
Quand le joueur parle au PNJ, la quête vérifie combien de matériaux il possède dans son inventaire. Si c'est suffisant, elle retire le matériau, accorde la récompense et augmente le palier d'un cran. Sinon, elle indique au joueur combien il lui en manque. Tout le flux peut tenir dans un seul fichier Lua.
Squelette de quête de base
Voici un squelette de quête de biologiste fonctionnel, à un seul palier. Soit 9001 le vnum du PNJ et 30301 le vnum du matériau demandé. Nous demandons 20 unités du matériau au joueur :
quest biolog begin
state start begin
when 9001.chat."Biologiste" begin
say_title("Biologiste :")
say("Apporte-moi 20 echantillons,")
say("et je te recompenserai en retour.")
say("")
local have = pc.count_item(30301)
say("Echantillons en main : "..have.."/20")
local s = select("Remettre", "Annuler")
if s == 2 then return end
if pc.count_item(30301) < 20 then
say_title("Biologiste :")
say("Tu n'as pas encore assez d'echantillons.")
return
end
pc.remove_item(30301, 20)
pc.give_item2(50300, 5) -- recompense : 5 potions
say_title("Biologiste :")
say("Merci ! Voici ta recompense.")
end
end
end
Ici, pc.count_item compte la quantité dans l'inventaire, pc.remove_item supprime le matériau remis et pc.give_item2 accorde la récompense. say/select pilotent le flux de dialogue. Ce squelette fonctionne pour une seule mission ; ce qui rend un vrai système de biologiste attrayant, c'est de le relier à des paliers et à une boucle quotidienne.
Paliers de récompenses
Dans les vrais systèmes de biologiste, le matériau demandé et la récompense augmentent après chaque remise. La façon la plus propre de concevoir cela est pilotée par les données, avec une table Lua. On garde le palier dans un flag de quête et on l'incrémente à chaque remise :
local PALIERS = {
-- {vnum_demande, quantite, vnum_recompense, quantite_recompense}
{30301, 20, 50300, 5},
{30302, 30, 50301, 8},
{30303, 40, 71001, 1}, -- recompense rare au dernier palier
}
quest biolog begin
state start begin
when 9001.chat."Biologiste" begin
local step = pc.getqf("biolog_step")
if step == 0 then step = 1 end
if step > table.getn(PALIERS) then
say("Tu as termine tous les paliers !")
return
end
local p = PALIERS[step]
local vnum, need = p[1], p[2]
local have = pc.count_item(vnum)
say_title("Biologiste :")
say("Palier "..step.." : "..have.."/"..need)
local s = select("Remettre", "Annuler")
if s == 2 then return end
if pc.count_item(vnum) < need then
say("Tu n'as pas encore assez de materiau.")
return
end
pc.remove_item(vnum, need)
pc.give_item2(p[3], p[4])
pc.setqf("biolog_step", step + 1)
say("Tu es passe au palier suivant !")
end
end
end
Cette structure passe à l'échelle : pour ajouter un nouveau palier, il suffit d'ajouter une seule ligne à la table PALIERS. Écrire la logique une fois et alimenter les données depuis une table est bien plus sain pour la maintenance que de dupliquer du code.
Reset quotidien
La partie qui donne au système de biologiste son caractère de « quête quotidienne », c'est le reset. L'objectif est de permettre au joueur une remise par jour. Pour cela, on stocke le jour de la dernière remise dans un flag et on le compare au jour courant à chaque visite. On peut dériver le jour de get_global_time() (divisez l'horodatage en secondes par 86400 pour obtenir un numéro de jour) :
local function aujourdhui()
return math.floor(get_global_time() / 86400)
end
-- dans le flux du PNJ, avant la remise :
if pc.getqf("biolog_jour") == aujourdhui() then
say_title("Biologiste :")
say("Tu as deja fait ta remise aujourd'hui.")
say("Reviens demain.")
return
end
-- ... apres une remise reussie :
pc.setqf("biolog_jour", aujourdhui())
Cette approche reste cohérente même si le serveur redémarre, car elle stocke la date dans le propre flag du joueur. Si vous le souhaitez, vous pouvez décaler le calcul du « jour » d'un offset d'une heure pour correspondre au fuseau horaire de votre serveur (par exemple un reset à 06:00 au lieu de minuit).
Conception à l'épreuve des exploits
Les systèmes de collecte-récompense sont exposés aux abus s'ils ne sont pas conçus avec soin. Surveillez ces points :
- Vérifier d'abord, supprimer ensuite : Recomptez toujours la quantité avant de supprimer le matériau avec
pc.remove_item. Sur l'écranselect, le joueur peut déplacer l'objet depuis une autre fenêtre. - Flux atomique : Exécutez les étapes de suppression et d'octroi l'une après l'autre, sans dialogue entre les deux. Sinon, le joueur peut lâcher l'objet pendant qu'il attend dans le dialogue.
- Débordement d'inventaire : Vérifiez l'espace libre avant d'accorder la récompense ; s'il est plein, prévenez le joueur et annulez la remise, sinon la récompense est perdue.
- Écrire le flag du jour en dernier : Enregistrez le jour seulement après la réussite de la remise, pour que le droit ne soit pas gaspillé en cas d'erreur.
Journaliser ce système est aussi une bonne idée : quel joueur, à quel palier, a remis quand ? Repérer des remises anormalement fréquentes vous aide à détecter tôt les bugs de duplication.
Questions fréquentes
Puis-je construire le système de biologiste sans toucher au source du serveur ?
Oui. Tout le flux est géré par le moteur de quêtes (Lua) ; les seules « nouvelles » définitions nécessaires sont le vnum du PNJ et les enregistrements item_proto. Vous pouvez construire un biologiste fonctionnel avec un simple fichier de quête et des modifications de proto, sans recompiler le source.
Comment décider du matériau demandé ?
Le matériau est un objet item_proto ordinaire. Il est généralement lié à des monstres précis en tant que drop (mob_drop_item / tables de drop). Ainsi le joueur rassemble le matériau en chassant, ce qui intègre le système à la boucle de farm.
Le joueur peut-il voir sa progression ?
Oui, vous pouvez afficher la valeur pc.getqf("biolog_step") dans le dialogue du PNJ. De nombreux serveurs présentent aussi la quantité restante et la prochaine récompense via une interface de quête ou un simple résumé say.
Vous voulez un système de biologiste à paliers, avec reset quotidien et à l'épreuve des exploits pour votre serveur ? Je peux construire et tester la logique de quête, les tables de récompenses et la boucle quotidienne de bout en bout. Contactez-moi pour parler de votre projet.