Je suppose que cette question concerne davantage les jeux comme MMO et les jeux de type Diablo.
Quelles sont les conceptions habituelles pour la mise en œuvre d'une table de dépôt, où un monstre peut déposer différents types d'objets en fonction d'un pourcentage? Je suppose que le moyen le plus simple consiste à avoir un dictionnaire de `` pondération en pourcentage '' pour les types d'élément, mais cela est difficile à étendre si nous souhaitons introduire de nouveaux types d'élément (par exemple, lorsque l'expansion D2 inclut des runes et de nouveaux éléments de classe)
game-design
rpg
Extrakun
la source
la source
Réponses:
Pour un roguelike sur lequel je travaillais, j'ai implémenté un système basé sur les données assez flexible pour générer des gouttes. Je l'ai documenté ici . C'est essentiellement un petit DSL pour sélectionner un certain nombre d'éléments choisis au hasard.
Une simple goutte ressemble à:
Cela dit simplement de laisser tomber un nombre aléatoire de pièces de cuivre entre 1 et 10. Les choses deviennent plus flexibles lorsque vous ajoutez des branches:
Un "un de" sélectionne une de ses branches enfants en fonction des probabilités données, puis l'évalue. Les gouttes peuvent déposer plusieurs éléments:
Cela évaluera toutes les sous- branches et les supprimera si un jet contre leur probabilité passe. Il existe également d'autres branches pour sélectionner un élément en fonction du donjon et du niveau du joueur.
Parce que celles-ci peuvent devenir complexes, cela vous permet également de définir des macros nommées, essentiellement des fonctions qui développent une expression de branche et peuvent être réutilisées en plusieurs suppressions. De cette façon, si, par exemple, tous les nains déposent le même type de butin, vous pouvez créer une seule macro pour cela et l'utiliser sur tous ces types de monstres au lieu de copier et coller d'énormes tables de dépôt.
Un exemple de chute d' un monstre :
Ici,
(coins)
,(any-weapon)
et(any-armor)
sont tous les appels macro:qui à son tour appelle des choses comme:
Vous pouvez imbriquer des expressions de manière arbitraire profondément comme un véritable langage de programmation. Cela vous donne la composabilité qu'une approche basée sur une table simple ne donnera pas.
Comme tous les systèmes basés sur les données, vous pouvez vous submerger en créant des gouttes d'une complexité impénétrable, mais cela répond à mes objectifs:
Le code C # qui implémente ceci est ici .
la source
A Stendhal, nos tables de butin sont des listes. Chaque entrée contient le nom de l'article, une quantité min et max et la probabilité. La structure interne est très similaire à ce que nous affichons sur la page Web de la créature .
Il est important pour nous que les concepteurs de jeux qui ont une grande connaissance du monde puissent définir de telles choses. Autrement dit, sans comprendre la logique complexe au niveau du code de programme. Nous n'avons donc pas les définitions des créatures et des objets dans le code du programme, mais nous les avons déplacés vers des fichiers .xml tels que elves.xml ou club.xml . Nous avons un éditeur graphique pour eux, mais la plupart des concepteurs de jeux modifient directement le fichier .xml.
Afin de rendre les créatures et les objets facilement extensibles, nous utilisons un système de blocs de construction: Il n'y a pas de classe de programme pour "elf" ou "archer elf". Mais il existe un certain nombre de classes liées au comportement telles que "lâche", "patrouille", "agressif", "archer", "guérisseur". Les concepteurs peuvent définir de nouvelles créatures en sélectionnant ces comportements sans écrire de code de programme: Par exemple, pour créer un "elfe archer", dessinez un sprite elfe avec un arc et définissez-le comme "offensant", "archer". Définissez ensuite le niveau et les attributs similaires et ajoutez des objets elfiques à la table de butin.
Pour les articles, nous avons une approche similaire, mais elle est actuellement limitée à un seul comportement: un concepteur peut ajouter un nouvel article et définir un comportement tel que "ConsumableItem", "KeyItem" ou "AttackItem", "Spell", "Scroll" sans avoir à programmer la logique.
la source
Dans les jeux de table D&D, il existe un concept de types de butin. La plupart des monstres tomberont d'une ou plusieurs tables et ces tables seront ce que vous mettriez à jour dans votre extension. Les monstres laisseraient tomber "65% de points communs, 10% de gemmes, 15% d'art, 10% d'outils", mais vous mettriez à jour ce qui était dans chacune de ces tables.
Par exemple, Gems contient des emplacements avec des plages aléatoires qui renvoient "1 gemme (25%) 2 gemmes (50%) 5 gemmes (75%) 100 gemmes". et lorsque vous souhaitez ajouter des gemmes runiques spéciales, mettez à jour le tableau à "1 gemme (25%) 2 gemmes (50%) 5 gemmes (75%) 100 gemmes (95%) 1 gemme runique".
Mais, d'autre part, si vous avez déjà une pondération en pourcentage, pourquoi ne pas simplement mettre à jour toutes les tables de monstres dans votre extension? Les tableaux comme celui-ci sont sûrement une petite charge utile par rapport aux textures et aux maillages. De plus, vous n'avez pas non plus besoin de maintenir les pourcentages à 100, c'est juste une hypothèse que vous avez faite pour commencer et vous pouvez calculer le total réel avant de générer votre valeur aléatoire. Si les pondérations totalisent 120, générez simplement une valeur de 1-120 au lieu de 1-100.
la source
À première vue, cela semble être le même que le problème de la "sélection aléatoire pondérée".
Algorithme pour déterminer des événements aléatoires
Attribuez des probabilités relatives à chaque événement, additionnez-les, puis choisissez un nombre aléatoire dans cette plage pour décider quel événement vous souhaitez.
Même si vous préférez utiliser des pourcentages - qui est le même système, juste mis à l'échelle à 100 - vous surestimez la difficulté à ajouter des éléments. Si vous avez 100%, puis ajoutez 20% dans une extension, divisez simplement toutes les valeurs par (120/100) et vous êtes de retour à un total de 100%.
la source