J'ai conçu un jeu RPG qui a plusieurs fils d'histoire, ce qui signifie que, selon le choix de l'utilisateur, certaines choses peuvent ou non se produire, vous pouvez réaliser la même chose de plusieurs manières, la fin peut être différente et ainsi de suite.
J'ai implémenté un moteur de décision simple, qui fonctionne bien mais qui a un gros défaut, au moment où vous prenez une décision, l'histoire est immédiatement influencée par votre décision, ce qui signifie que vous ne pouvez pas prendre une décision qui vous affectera dans un avenir lointain . En effet, l'histoire se déroule comme une branche dans une structure arborescente, et elle doit toujours savoir quel nœud est le suivant. Sous le capot, les décisions sont mises en œuvre à l'aide d'une file d'attente: chaque nœud connaît le nœud précédent et le nœud suivant (ou s'il s'agit d'un nœud de décision, il attend l'entrée de l'utilisateur pour définir le nœud suivant)
J'ai vu beaucoup de jeux qui ont des moteurs de décision complexes, et je me demande comment sont-ils fabriqués? Existe-t-il un design spécial qui rend les choses vraiment faciles? Quelqu'un a-t-il fait quelque chose de similaire et peut-il me donner un indice sur la façon de résoudre ce problème?
MISE À JOUR 1:
Un aspect important est de réussir à garder le code de l'histoire en quelque sorte indépendant, afin qu'il puisse être manipulé à partir d'un fichier externe. J'ai l'intention de l'utiliser comme moteur, donc même les choix possibles doivent provenir d'un fichier externe. Le code doit être totalement abstrait.
De plus, je suis intéressé par une solution de conception, une belle façon de le faire, comment les autres le font ou l'ont fait.
la source
if (isTree)
ou conserver uneisTree
variable globale car l'histoire peut ou non avoir ce choix. Sais ce que je veux dire? Cela ressemble plus à un moteur de choix qui servira à plusieurs histoires.isTree=true
, plus tard, il fait autre chose, comme combattre un camarade de classe qui, en retour, va couper son arbre alors que l'arbre est encore jeune parce qu'il s'est fait botter le cul. Maintenant, nous avons 2 variables qui influencent l'existence de l'arbreisTree==true' and
didFightBrat == false`. Sais ce que je veux dire? Et la chaîne peut durer éternellement, l'existence de l'arbre peut être influencée par un nombre inconnu de facteurs. Sais ce que je veux dire?Réponses:
Vous pouvez également généraliser la file d'attente en un graphique acyclique dirigé (DAG). Vous pouvez en lire plus sur Wikipédia. Fondamentalement, chaque nœud peut avoir un ou plusieurs nœuds parents dont il "dépend". Les cycles ne sont pas autorisés, c'est-à-dire que si A dépend de B, B ne peut pas dépendre de A (directement ou via une chaîne indirecte d'autres nœuds).
Chaque nœud est dans un état "actif" ou "inactif" et n'est autorisé à devenir actif que si tous ses parents sont déjà actifs. La structure du graphique (quels nœuds sont là et comment sont-ils connectés) fait partie des données du jeu, mais l'état actif / inactif fait partie des données de sauvegarde du joueur.
De cette façon, vous pouvez modéliser des choses comme: lorsque vous plantez un arbre, vous marquez une tâche "plantedTree" comme active; puis, plus tard dans le jeu, une autre tâche "treeGrown" nomme à la fois "plantedTree" et un autre nœud (partie de l'histoire) comme ses parents. Ensuite, "treeGrown" ne devient actif que lorsque le joueur arrive à ce point de l'histoire, et "plantedTree" est également actif.
Vous pouvez inclure d'autres fonctionnalités telles que des nœuds qui s'activent si l'un de leurs parents est activé, ou des nœuds qui sont activés par un parent et désactivés par un autre, etc. C'est un cadre assez général pour créer des histoires avec plusieurs fils interdépendants.
la source
D'après ce que je comprends, ce que vous voulez n'est pas seulement un moteur de décision, mais aussi un moteur de règles. Pour chaque décision, vous exécutez un sous-ensemble de règles défini par cette décision. L'exécution de ces règles dépend souvent de l'état de certaines entités comme votre exemple d'arborescence.
Fondamentalement, lorsque votre joueur prend une décision, vous recherchez cette décision, exécutez les règles, puis fournissez le prochain ensemble de décisions disponibles comme d'habitude. Cependant, vos règles sont dynamiques dans la mesure où certaines d'entre elles ne s'exécuteront que sur la base d'autres règles déjà exécutées.
Un peu plus sur Wikipédia .
De leur sous-titre Quand utiliser les moteurs de règles (c'est moi qui souligne):
Une chose à noter est qu'il est parfois préférable d'implémenter un moteur de règles en utilisant un "langage" spécifique au domaine simplifié, ou quelque chose comme YAML. Je ne suggérerais pas XML.
la source
Vous devez considérer qu'un événement n'est pas uniquement basé sur la décision de l'utilisateur. Comme vous l'avez noté, un événement doit être ajouté si, lorsqu'un ensemble de décisions est pris et puis quelque chose s'ajoute (comme deux jours après).
Je pense que vous avez besoin d'un moyen de modéliser les événements et de le déclencher. Alors que le premier est plus lié à votre cas spécifique, le second peut être modélisé par une machine à états hiérarchique (HSM) qui déclenche directement ou indirectement vos événements.
Gardez à l'esprit qu'une machine d'état souffre de la malédiction de la dimensionnalité qui n'est atténuée que par une structure hiérarchique. Bientôt, vous comprendrez que vous devez modéliser la signification complexe du statut à l'aide d'un HMS, mais également fournir un moyen de l'interroger.
Dans ce scénario, vous avez des événements de base (décisions de l'utilisateur, heure, changement de temps, etc.) qui sont traités à la fois par le HSM et par les rappels d'événement de base. Le HSM fournit un modèle pour la «mémoire» et les rappels fournissent un moyen de décrire comment cette mémoire doit être utilisée pour calculer les conséquences d'une séquence de décisions / événements externes.
Vous pouvez également finir par utiliser un dicton (ou une autre structure de collecte) de HMS, un pour chaque "aspect" de statut que vous devez calculer. Un exemple peut être d'utiliser un événement lié au HMS et un autre pour les décisions que les rappels prennent afin de déclencher des événements.
Toute cette infrastructure sert à imiter le comportement d'un maître de donjon humain: il prend généralement un enregistrement mental de la situation actuelle (HMS ["externe"]) en raison des décisions des joueurs et des conditions environnementales; quand quelque chose s'ajoute, il peut prendre des décisions en utilisant son dossier mental et enregistrer également un état de stratégie interne (HSM ["interne"]) afin d'éviter de réagir de la même manière si la situation en question s'ajoute par exemple.
la source