Un système de quêtes révolutionnaire
{Scripts RGSS3 pour VXAce}
Préambule
Après avoir rédigé un système de base de données étendue encore plus riche que ma précédente version, que vous pourrez trouver
ici. J'ai décidé de m'en servir pour implémenter des systèmes configurables et permissifs. Je me suis d'abord fait les dents sur un tout petit système de quêtes, que j'ai fait évoluer en quelque chose de réellement flexible. Vous l'aurez compris, l'installation du script
CustomDatabase est donc un pré-requis. (Toutes les informations d'installation sont disponibles sur la page du script
)
Version minimaliste
Cette version, présentée ci-dessous, n'a rien de révolutionnaire... elle présente juste une implémentation minimaliste en utilisant mon système de base de données.
Avant toute chose, ce script est avant tout une manière d'expérimenter la flexibilité (et le gain de temps) offert par le script de base de données personnalisable. L'objectif, ici, n'est donc pas de produire "le script le plus puissant" (le plus personnalisable et avec le plus de fonction) des systèmes de quêtes, mais plutôt un micro système, facile à prendre en main (qui donnera peut être naissance à un système plus conséquent dans le futur). Ce script permet donc de déployer rapidement des quêtes dans son projet.
Image du journal des quêtes
Installation
Ce script requiert l'installation de
CustomDatabase pour fonctionner.
Copiez le script dans votre éditeur de script au dessus de
Main, dans la rubrique
Materials. Vous pouvez lui attribuer un emplacement réservé. Et le nommer comme vous l'entendez. Personnellement, j'ai choisi le nom
MicroQuestSystem (original :P !)
Je conseil de préparer un espace script en dessous de ce script qui servira à insérer les quêtes.
Lien du micro système de quêtes
Création de quêtes
Comme précisé dans l'installation, je conseilles de préparer un espace vierge en dessous du script (mais vous pouvez écrire vos quêtes à la suite du script, sans créer d'autre espace).
La création d'une quête ne peut pas être faite ingame. Il faut impérativement les créer avant. Cependant, vous pouvez les modifier, supprimer et en ajouter durant la réalisation de votre jeu.
Syntaxe de la création d'une quête
Code (Ruby): Quest.insert(ID, NOM, DESCRIPTION, GOLD, EXP, ITEMS, WEAPONS, ARMORS)
Voyons maintenant quels sont les paramètres de l'insertion :
1.) ID Correspond à un identifiant (UNIQUE) que vous attribuerez pour accéder rapidement à une quête.
2.) NOM Le nom de la quête. Il sera affiché dans le journal des quêtes
3.) DESCRIPTION Une note plus explicite que le nom
4.) GOLD et EXP correspondent à l'argent et l'expérience reçue quand la quête est finie.
5.) ITEMS, WEAPONS, ARMORS sont des listes qui contiennent les ID's des objets/armes/armures à recevoir en fin de quête.
Par exemple :
Code (Ruby): Quest.insert(1, "Tuer slimes",
"Il faut protéger le village en tuant des slimes",
100, 777, [10],[2,3],[2,2,4]
)
Cette quête, une fois finie, donnera 100 d'or, 777 d'expérience et l'objet 10, l'arme 2 et l'arme 3, deux armures 2 et une armure 4. Alors que celui-ci :
Code (Ruby): Quest.insert(2, "Manger un chat",
"C'est très bon ... miam",
10, 78, [],[],[]
)
Ne donne que 10 d'or, 78 d'expérience et aucun objet/arme/armur.
Vous pouvez créer autant de quêtes que vous le désirez. Il faudra utiliser l'ID pour y accéder.
Lancer une quête
Le démarrage d'une quête indique qu'elle est en cours. Il suffit de faire :
start_quest(ID). Dans un appel de script (ou ailleurs). Il est donc très commode de démarrer une quête au moyen d'un appel de script dans un évènement.
Finir une quête
Une quête ne peut être finie que si elle a été commencée. Il suffit de faire
finish_quest(ID). Lorsqu'une quête est finie, la distribution de l'or, de l'expérience et des objets est effectuée toute seule.
Une quête finie est indiquée en vert dans le journal de quête, et une quête en cours est de la couleur standard.
Fonctions annexes
1.) quest_on_the_road?(ID) ou quest_in_curse?(ID) renvoi true si la quête est en cours, false sinon.
2.) quest_done?(ID) ou quest_finished?(ID) renvoi true si la quête est finie, false sinon.
Configuration complémentaire
Il est possible de modifier les textes utilisés en modifiant le module
Vocab mais aussi d'annuler l'affichage du journal dans le menu en désactivant la constante
QUEST_IN_MENU du module [/strong]Config[/strong]
Conclusion
Ce script est assez "minimaliste" mais offre toute la base nécéssaire à la construction d'un système de quête. Il s'inscrit dans le RGSS et l'usage de la base de données alternative le rend très court et très facile à maintenir (mais aussi à modifier). Il ne faut pas prendre ce script comme une tentative d'évolution mais juste comme un essai de l'usage de ma petite base de données étendue.
Le script présenté dans la suite est
beaucoup, beaucoup plus impressionnant
!
Le vrai script (super badass) :D
La première version de ce script n'offre absolument rien de novateur... Il est même assez simplet. Maintenant il est temps de passer à la vraie présentation ... mesdames, messieurs, mesdemoiselles... je vous présente mon Ultra Quest System !
Un des enjeux de ce script est surtout de permettre d'automatiser la terminaison de certaines quêtes... comme par exemple celle présentée en exemple :
tuer deux slimes. Qui, à implémenter en évènement est assez compliqué !
Le script est aussi doté d'un magasin de quête, de conditions de structures internes et de pleins d'autres fonctionnalités flexible pour customiser son jeu !
Il est important de noter que les "vues" du script sont génériques pour inciter le maker à concevoir ses propres rendus visuels !
Vues du script
Journal de quêtes
Magasin de quêtes
Installation
Ce script requiert l'installation de
CustomDatabase pour fonctionner.
Copiez le script dans votre éditeur de script au dessus de
Main, dans la rubrique
Materials. Vous pouvez lui attribuer un emplacement réservé. Et le nommer comme vous l'entendez. Personnellement, j'ai choisi le nom
Super système de quêtes trop swagg ! (original :P !)
Je conseil de préparer un espace script en dessous de ce script qui servira à insérer les quêtes.
[url=https://raw.githubusercontent.com/nukiFW/RPGMaker/master/QuestSystem/script.rb[/url]
Création d'une quête
Comme conseillé dans la directive d'installation, il est recommandé de créer un espace libre en-dessous du script qui servira à écrire les quêtes. Lorsque je parlerai de création de quêtes, je partirai du principe que vous les décrivez dans cet espace.
Syntaxe de création d'une quête
Pour créer une quête, il suffit d'ajouter ceci dans l'espace libre :
Code (Ruby): Quest.create(
:id => NUMERO_DE_LA_QUETE,
:name => "Nom de la quête",
:desc => "Description de la quête"
)
Il s'agit de la syntaxe minimale pour créer une quête. Cependant, il existe une foultitude de paramètres en plus.
Paramètres complémentaires
Les paramètres complémentaires permettent de spécialiser une quête pour lui permettre par exemple, de définir les récompenses, la condition de déclenchement, ou encore le prix de la quête (car nous verrons plus tard que les quêtes peuvent être achetées). Chaque paramètre doit être séparé par une virgule.
:gold
Il est possible de paramétrer la quantité d'Or que rendra la quête une fois terminée. Pour cela, il suffit d'ajouter l'option
:gold => QUANTITE_DOR_RECUE.
:exp
Une quête peut aussi faire gagner de l'expérience à l'équipe une fois terminée au moyen de l'option
:exp => NOMBRE_DE_POINT_D_EXPERIENCE_RECUS.
Exemple de quêtes donnant de l'expérience et de l'or
Code (Ruby): Quest.create(
:id => 1,
:name => "Rencontrer Pierre",
:desc => "Aller parler à Pierre, au nord du Village",
:gold => 200,
:exp => 120
)
:items
Comme pour l'or et l'expérience il est possible de paramétrer une liste d'objets à recevoir en cas de succès de la quête :
:items => [listes des identifiants d'objets à recevoir séparé par une virgule].
:weapons
Comme pour les objets il est possible de paramétrer une liste d'armes à recevoir en cas de succès de la quête :
:weapons => [listes des identifiants d'armes à recevoir séparé par une virgule].
:armors
Comme pour les armes il est possible de paramétrer une liste d'armures à recevoir en cas de succès de la quête :
:armors => [listes des identifiants d'armures à recevoir séparé par une virgule].
Exemple de quêtes donnant de l'expérience et de l'or et des objets
Code (Ruby): Quest.create(
:id => 1,
:name => "Rencontrer Pierre",
:desc => "Aller parler à Pierre, au nord du Village",
:gold => 200,
:exp => 120,
:items => [1,1,2],
:weapons => [2],
:armors => [3]
)
Voici une quête qui donne en cas de réussite, 200 d'or, 120 points d'expérience à toute l'équipe, 2 fois l'objet 1, une fois l'objet 2, l'arme 2 et l'armure 3.
:label
Généralement, les quêtes sont référencées par leur id. Nous verrons plus tard comment démarrer des quêtes, ou vérifier si une quête est finie, en nous servant de leur id. Cependant, les ids étant des nombres, on peut leur attribuer un label, qui est un petit mot pour qu'elles soient plus faciles à référencer. Le label est très utile lorsqu'on a une très grande collection de quêtes à manipuler. Il s'ajoute de cette manière :
:label => :nom_du_label. Par défaut, le label d'une quête est
:quest_ suivi de son ID, par exemple
:quest_1.
:cost
La notion de coût d'une quête intervient lorsque l'on verra les magasins de quêtes, pour qu'une quête soit accessible dans un magasin, elle doit impérativement avoir un coût, c'est le prix d'achat de la quête. Le coût s'ajoute avec
:cost => PRIX_DE_LA_QUETE. Si une quête n'a pas de coût, elle se sera pas affichable dans un magasin malgré la possibilité que celui-ci la contienne dans son stock.
:repeatable
Par défaut, une quête déjà lancée (donc présente dans le journal de quêtes) ne peut être relancée. Une quête répétable sera donc, une fois terminée, supprimée du journal de quête et pourra être relancée. On ajoute cette option de cette manière :
:repeatable => true (Ou alors
false. Cependant, autant ne pas spécifier l'option de répétition si une quête ne doit pas l'être).
:need_confirmation
Cet attribut est un peu particulier. En effet, il distingue la réussite d'une quête d'avec sa complétude. Par exemple, si une quête est achetée en magasin, une fois terminée, le joueur recevra automatiquement les récompenses. Si elle doit être complétée (via l'option :
:need_confirmation => true), le joueur devra se rendre dans un magasin qui peut vendre cette quête pour la compléter. Il est aussi possible de compléter manuellement une quête (via un appel de script que nous détaillerons plus tard). La confirmation des quêtes permet de forcer le joueur à retourner au lieu de démarrage de la quête pour gagner ses récompenses. Dans le menu des quêtes (le journal), on distingue une quête complète d'une quête finie.
Conditions internes
Les conditions internes sont des éléments qui rendent la création d'un jeu plus facile. En effet, lorsque je présente un exemple de quête, "tuer 3 slimes", le souci c'est que la condition de réussite de la quête est extrêmement compliquée à représenter. Nous allons voir qu'il est possible d'automatiser le succès (ou l'échec) d'une quête dans certains contextes.
:success_trigger
L'option
:success_trigger => condition_de_fin_avec_succes permet de définir une condition de succès d'une quête. Nous verrons comment concevoir des conditions de déclenchement un peu plus tard.
:fail_trigger
L'option
:fail_trigger => condition_de_fin_avec_echec permet de définir une condition d'échec d'une quête.
Créer une condition
var_check(id, value)
Cette primitive permet de vérifier la valeur d'une variable. En effet, la primitive
var_check(5, 10) sera considérée comme étant valide quand la variable 5 sera égale à 10. Il est possible de spécifier des opérateurs en 3ème argument :
• var_check(5, 10) => vérifie que la variable 5 est égale à 10
• var_check(5, 10, :>) => vérifie que la variable 5 est plus grande que 10
• var_check(5, 10, :<) => vérifie que la variable 5 est plus petite que 10
• var_check(5, 10, :>=) => vérifie que la variable 5 est plus grande ou égale à 10
• var_check(5, 10, :<=) => vérifie que la variable 5 est plus petite ou égale à 10
• var_check(5, 10, :!=) => vérifie que la variable 5 est différente 10
switch_check(id, :activated | :deactivated)
• switch_check(2, :activated) => vérifie si l'interrupteur 2 est activé
• switch_check(2, :deactivated) => vérifie si l'interrupteur 2 est désactivé
Conditions de possessions d'objets
• has_item(id, total) => vérifie que le joueur possède bien l'objet référencé par id, au moins un certain nombre de fois (défini par total)
• has_weapon(id, total) => vérifie que le joueur possède bien l'arme référencée par id, au moins un certain nombre de fois (défini par total)
• has_armor(id, total) => vérifie que le joueur possède bien l'armure référencée par id, au moins un certain nombre de fois (défini par total)
monster_killed(id, total)
A partir du déclenchement de la quête, cette primitive oblige de battre un nombre de fois (défini par total) le monstre référencé par id.
Opérations logiques entre les primitives
Avec ces primitives, il n'est pas possible de représenter par exemple, comme condition, le meurtre de 5 slimes ET la possession de l'arme 1. De même qu'il n'est pas possible de représenter la disjonction "tuer 5 slimes OU posséder 5 objets de peaux de slimes". C'est pour ça que ce script permet de lier les primitives entre elles au moyen de connecteurs logiques. Soit
& pour représenter le ET, et
| pour représenter le OU. Par exemple, imaginons une quête qui est réussie par la mort de 5 monstres 1 et par la possession de l'arme 1 :
:success_trigger => monster_killed(1, 5) & has_weapon(1, 1). De même que l'on pourrait admettre qu'une quête est réussie si la variable 10 est plus grande que 7 et si l'interrupteur 10 est activé, ou que l'arme 10 est possédée en 13 exemplaires :
:success_trigger => (var_check(10, 7, :>) & switch_check(10, :activated)) | has_weapon(10, 13). Il est possible de composer des motifs vraiment raffinés de quêtes pour ne pas devoir coder, en eventmaking, chaque embranchement d'une quête. Cependant, il est tout de même possible de terminer manuellement ces quêtes.
Exemple de quêtes avec succès automatique
Code (Ruby): Quest.create(
:id => 2,
:name => "Le slime et la potion",
:desc => "Tuer deux slimes et trouver une potion",
:gold => 100,
:exp => 100,
:success_trigger => monster_killed(1, 2) & has_item(1, 1)
)
Cette quête se terminera une fois que le joueur aura tué deux slimes et possèdera une potion. Il ne faut pas implémenter le test, et les récompenses seront données automatiquement. Un autre exemple serait :
Code (Ruby): Quest.create(
:id => 2,
:name => "Le slime et la potion",
:desc => "Tuer deux slimes et trouver une potion",
:gold => 100,
:exp => 100,
:success_trigger => monster_killed(1, 2) & has_item(1, 1),
:fail_trigger => switch_check(3, :activated)
)
Qui échouerait si l'interrupteur 3 est activé.
Condition de lancement d'une quête
Il est aussi possible d'avoir une condition de déclenchement (ou d'achat, dans les magasins) de quêtes. Pour cette section, il vaut mieux avoir des connaissances en Ruby, ou se servir de l'Event Extender pour avoir des fonctionnalités plus faciles. Il s'agit de l'option :
:verify => check{condition de lancement}. Par exemple, pour qu'une quête soit lançable seulement si le niveau du premier héros est plus grand que 3:
:verify => check{$game_actors[1].level > 3}. (Les connecteurs logiques
&& et
|| sont utilisables, évidemment).
Déclenchement d'action en fin de quête
Une fois qu'une quête est finie, il est possible de lancer une action, via l'option :
:end_action => action{Liste d'actions à effectuer en fin de quête} (L'action est déclenchée après la finition de la quête, il est donc possible de savoir, dans les actions, si la quête a été finie ou non).
Usage des appels de scripts
Dans cette section, tous les arguments id peuvent être remplacés par le label d'une quête.
• Quest.start(id) : Démarre la quête référencée par son id (même si la condition de lancement n'est pas respectée)
• Quest.finished?(id) : Renvoie true si la quête est finie, [strong]false sinon
• Quest.succeeded?(id) : Renvoie true si la quête a été finie avec succès, false sinon
• Quest.failed?(id) : Renvoie true si la quête a été finie avec échec, false sinon
• Quest.ongoing?(id) : Renvoie true si la quête est en cours, false sinon
• Quest.finish(id) : Finit la quête avec succès
• Quest.fail(id) : Finit la quête avec échec
• Quest.need_confirmation?(id) : Renvoie true si la quête demande une confirmation, false sinon
• Quest.confirm(id) : Confirme une quête finie, donne la récompense
• Quest.launchable?(id) : Renvoie true si la condition de lancement de la quête est respectée, false sinon SceneManager.questShop([liste_des_quetes_vendables]) : Lance un magasin de quêtes, avec un stock, la liste des quêtes passée en argument.
Configuration du script
En début de script, il existe un module de configuration, qui permet de changer le vocabulaire du script, mais aussi l'accès au journal des quêtes dans le menu.
Journal des quêtes et magasins
Le script dispose d'un journal des quêtes, basé sur le menu d'objets (respectant son architecture visuelle) et d'un magasin de quêtes, ressemblant aux magasins natifs. Je vous invite tout de même à faire votre propre script de magasin/journal, pour avoir quelque chose de très original.
Bonne utilisation !
Conclusion
Ces deux scripts présentent des usages concrets d'un système de base de données étendue. Et même si (surtout le deuxième) ils restent "longs", la base de données automatise beaucoup de partie ennuyantes et le scripteur peut donc se focaliser sur des choses que je trouve (IMHO) plus intéressantes. J'espère que le deuxième script vous sera utile et je vous souhaites une bonne soirée
!