Last updated: 06/10/2024, 02:17

Current Project: Rejuvenation of Hellkeeper.net

AssaultPath

Introduction aux AssaultPaths

L'AssaultPath est le remplaçant des AlternatePaths de Unreal Tournament, et est beaucoup plus évolué. C'est aussi un beau petit paquet de paramètres un peu mystérieux. Ce tutoriel a été écrit après la complétion de CTF-Senate, pour laquelle la gestion du pathing a été plus compliquée et plus longue à mettre en place que pour toutes les autres maps que j'avais jusqu'ici produites. Il servait à l'origine de complément à un autre tutoriel, sur Unreal-Design.com, qui expliquait la majorité des actors de pathing mais restait très schématique sur les AssaultPaths, et pour cause : je n'en avais jamais fait usage. CTF-Senate m'a forcé à aborder la question. J'ai depuis supprimé les notes sur les AssaultPaths, et ai à la place ajouté un renvoi vers ce tutoriel-ci.

Les AssaultPaths sont essentiellement des jalons que l'on place le long d'un chemin d'attaque ou de retour. Ils se trouvent dans l'actor browser comme une sous-classe (la première dans l'ordre alphabétique) de NavigationPoint. Une fois qu'ils sont placés, on définit des chaînes d'AssaultPaths qui sont les routes d'attaque elles-mêmes, et on leur ajoute quelques paramètres pour affiner le contrôle sur la stratégie des bots. Dans la pratique, il s'agit d'une phase du botpathing qui nécessite un peu de planification et peut devenir un peu confuse quand les routes se multiplient. Pour les besoins de ce tutoriel, j'utiliserai justement ma map CTF-Senate, dont voici le viewport top :

CTF-Senate vue de dessus

La base bleue se trouve à droite et la base rouge à gauche. Sur l'image qui suit, le rez-de-chaussée est en rouge, le premier étage en bleu, et le niveau supérieur en jaune. Il y a 5 entrées dans une base. Deux au rez-de-chaussée, deux à l'étage, et une tout en haut.

Chemins de CTF-Senate : rouge, niveau 1 ; bleu, niveau 2 ; jaune, niveau 3

Les bots, d'UT2004, de par leur programmation, sont peu enclins à innover : si emprunter toujours la même route conduit au désastre, ils continueront jusqu'à ce que le hasard leur octroie la réussite. Mais ce n'est pas satisfaisant. Sans AssaultPath, les bots n'emploient pratiquement qu'un seul chemin sur CTF-Senate : le chemin du rez-de-chaussée, dans ses deux configurations. Pour varier leurs chemins, il est nécessaire de placer des AssaultPaths qui leur expliqueront en cours de jeu quelles routes sont disponibles et lesquelles sont plus ou moins bonnes, donc à favoriser. Commençons par regarder la liste des paramètres d'un AssaultPath. En plus des paramètres habituels d'un NavigationPoint normal, il possède, dans l'onglet AssaultPath, les propriétés suivantes :

PathTag indique le chemin d'attaque auquel l'AssaultPath sélectionné appartient. Position indique la place de cet AssaultPath dans la chaîne et permet donc de définir directement l'ordre dans lequel des AssaultPaths sont visités par les bots. Priority permet de définir les préférences des bots entre plusieurs AssaultPaths ayant la même position.

Théorie

Utiliser les AssaultPaths nécessite un peu de planification car il faut choisir comment les bots vont évoluer sur la map de manière globale. Pour ce faire, il faut savoir à peu près comment réfléchissent les bots avec les AssaultPaths.

Un bot ayant décidé d'attaquer (par exemple parce que vous avez donné l'ordre d'assaut à votre équipe robotique) va tout d'abord établir la liste des AssaultPaths dont l'ObjectivePath est celui de l'objectif actuel et ayant pour position "0", car ils sont les premiers d'un chemin d'assaut. Il choisit ensuite l'un de ces AssaultPaths en modulant son choix suivant le champ Priority : en additionnant les priorités de tous les AssaultPaths de même position, on tombe idéalement sur 1 : par exemple, si l'ont veut que 4 chemins soient utilisés avec la même régularité, les 4 AssaultPaths doivent avoir une Priority de 0.25 chacun. En augmentant ou en diminuant la priorité d'un AssaultPath, on augmente ou on diminue sa fréquentation : si un AssaultPath a une priorité de 0, il ne sera jamais emprunté. Plus la priorité sera haute, plus le chemin aura de chances d'être choisi.

Le bot se rend ensuite à l'AssaultPath choisi. Si bNoGrouping est faux, il y attendra un camarade pendant quelques instants. Sinon, il attaquera immédiatement. Il établit la liste des AssaultPaths dont au moins un PathTag est similaire à celui de l'AssaultPath sur lequel il se trouve et procède à un choix de la même façon que pour le premier. Il s'y rend. Il continue ainsi jusqu'à ce qu'il n'y ait plus d'AssaultPath ayant le même PathTag et une position supérieure dans la chaîne, ce qui détermine alors la "fin" de la route ; il se rend alors directement vers l'objectif et, dans l'idéal, réalise l'objectif en prenant le drapeau, en prenant le contrôle d'un point de domination, en remplissant un objectif du mode Assaut, en s'emparant de la balle ou en tirant vers le but, en fonction du mode de jeu. Il a donc parcouru une chaîne d'AssaultPaths ayant le même PathTag, en suivant leurs positions dans un ordre croissant, et ce en éliminant systématiquement les AssaultPaths ayant bReturnOnly réglé sur vrai.

Pour son retour, le bot établit alors une liste inverse de la précédente : au lieu de lister les AssaultPaths ayant une position de "0" il va choisir parmi ceux qui ont la position la plus haute. Il va ensuite les parcourir dans un ordre décroissant en éliminant systématiquement ceux ayant bNoReturn réglé sur vrai.

Cas pratique : CTF-Senate

Maintenant qu'un bref résumé de ce qui se passe a été établi, examinons le cas concret de CTF-Senate.

L'idéal est de commencer par la fin : on place un AssaultPath à chaque fin de route ; généralement, pour du CTF, cela signifie un AssaultPath à chaque entrée de la base adverse. Dans notre cas, il y a 5 entrées, notées sur l'image suivante par des croix.

Entrées dans la base rouge

Commençons par nous intéresser aux quatre chemins du bas, qui sont plus simples. On verra en effet plus tard que le chemin supérieur est plus délicat.

La map est divisée en 5 grands ensembles : les deux bases, la zone centrale et les zones intermédiaires entre les bases et la zone centrale. On désignera par le mot "entrée" d'une base, la jonction entre la base et la zone intermédiaire, et par le mot "sortie" d'une base, la jonction entre la zone intermédiaire et la zone centrale. L'image suivante montre les 4 entrées de la base rouge et les 4 sorties de la base bleue. Il est bien sûr sous-entendu que tout ce que l'on va faire, et qui part du principe que les bleus attaquent la base rouge, est symétrique si l'on veut lancer les bots rouges sur la base bleue.

Zones de Senate

Depuis chacune des 4 sorties bleues, il est possible de rallier sans aucune difficulté les 4 entrées rouges. Il est donc important, dans le réglage des AssaultPaths, de conserver cette versatilité.

On commence par placer un AssaultPath à chaque entrée de la base rouge et chaque sortie de la base bleue. On s'assure que tous ont bEnabled = vrai, car les 8 doivent marcher dès le début (il est rare d'avoir des AssaultPaths désactivés en CTF et BR). Comme les 4 AssaultPaths situés aux sorties de la base bleue sont les points d'où les attaques commencent, on règle bNoGrouping sur faux, ce qui permettra aux bots de se regrouper : il vaut mieux en effet lancer l'assaut en groupe. En revanche, pour ceux situés à l'entrée de la base rouge, un bot arrivant à ces AssaultPaths sera à quelques mètres du drapeau adverse et sans doute pressé de tous côtés par les défenseurs. Il n'y a donc pas de temps à perdre. On règle donc, pour les 4 arrivées, bNoGrouping sur vrai. De plus, comme ils sont à l'entrée de la base rouge, ils seront sans doute les derniers de leurs chaînes : leur Position devra refléter cela. On met donc 1, en s'assurant que ceux situés à la sortie de la base bleue ont une position de 0.

Vient ensuite l'étape de la priorité. A priori, les 4 entrées dans la base rouge se valent et les 4 sorties de la base bleue aussi. On met donc une priorité de 0.25 pour tous. Il y a une chance sur quatre que n'importe quel point de départ soit ainsi choisi par un bot et une chance sur quatre que n'importe quel point d'arrivée soit également choisi. Bref, toutes les routes se valent.

Maintenant arrive l'heure de définir les routes elles-mêmes.

Réglage des PathTags

Rappelons-nous qu'un bot choisit un AssaultPath de position 0 au hasard. Cet AssaultPath possède un PathTag qui lui ordonne de se rendre ensuite à un autre AssaultPath de même PathTag et de position supérieure. Au retour, ce sera la même chose : le bot porteur de drapeau choisira un AssaultPath parmi ceux ayant la position la plus haute, puis se rendra à un autre AssaultPath de même PathTag mais de position inférieure.

Commençons par donner un PathTag unique à chaque AssaultPath se situant à la sortie de la base bleue. Appelons-les "AttaqueBleu1", 2, 3 et 4. Afin que toutes les entrées de la base rouge puissent être ralliées depuis ces quatre AssaultPaths, il faut que chacun possède ces quatre PathTags. Or, il y a 4 PathTags disponibles dans un AssaultPath. Voici donc comment se présentent les choses :

Configuration complète des 4 routes inférieures

On peut bien entendu affiner cette disposition. On peut par exemple augmenter et diminuer des priorités si certains chemins sont plus ou moins fréquentés ou plus ou moins dangereux. De plus, dans le cas de CTF-Senate, l'une des entrées de la base rouge n'est pas, ou très difficilement utilisable pour le retour : il s'agit de celle située le plus en haut (sur l'image ci-dessus, l'entrée sur un chemin bleu qui se trouve en haut à droite). J'ai donc réglé le bNoReturn de cet AssaultPath-ci à vrai.

Voilà qui permet déjà aux bots d'utiliser les 4 routes principales. Mais il reste le cas de la route supérieure, dont j'ai fait remarquer plus haut qu'elle était plus complexe à mettre en oeuvre.

Application plus complexe

Le cas de ma route supérieure est plus intéressant parce qu'il offre plus de possibilités. En effet, les 4 routes inférieures sont, au final, 4 lignes droites avec un seul choix à faire : celui du point de départ et du point d'arrivée, pour établir la route. Une fois ceci fait, il n'y a plus qu'à dérouler. Cependant, dans ma route supérieure, il y a un choix supplémentaire à faire :

Les choix sur la voie du haut à l'aller

Sur cette image, on voit que les deux points d'accès au troisième niveau, dans la base bleue, aboutissent au même point. À partir de là se pose un problème : le bot doit choisir entre la route directe, qui passe tout droit jusqu'au centre de la carte, ou faire un détour par le sud, récupérant au passage le canon flak, qui est un atout important. Une fois au centre, le même choix s'impose. Dans ma première version, j'avais simplement placé un AssaultPath à chaque base et bien entendu les bots prenaient toujours la route directe, le canon flak étant totalement ignoré.

Afin de résoudre cela, il faut une chaîne d'AssaultPaths plus complexe. Pour être très précis, il m'en a fallu au total 6 pour chaque équipe. Voici comment se présentent les choses :

On commence par placer, au niveau du point d'interrogation situé le plus à droite sur l'image précédente, un premier AssaultPath, qui servira de point de départ à toute attaque passant par la route supérieure. On lui donne une position "0". Comme il se retrouve en concurrence avec les 4 AssaultPaths de départ des routes inférieures, on va baisser les priorités des 4 AssaultPaths du bas à 0.2 et mettre 0.2 également à la priorité de l'AssaultPath du haut. Ainsi, des 5 points de départ dans la partie bleue, tous ont autant de chances d'être utilisés : 20%, ou 1/5. Il est configuré strictement à l'identique des 4 points de départ inférieurs, à ceci près que son PathTag sera bien entendu différent. Mettons "AttaqueBleuHaut".

Il faut maintenant que le bot choisisse entre la route directe et le détour par le canon flak. On met donc un AssaultPath identique au premier au niveau de chacun de ces deux passages et on leur donne le même PathTag (AttaqueBleuHaut), mais une position de 1. On ajoute une priorité de 0.4 pour la route directe et une de 0.6 pour le canon flak. En effet, les deux AssaultPaths que nous venons d'ajouter sont les seuls auxquels est relié le premier AssaultPath de la route supérieure que nous avons ajouté. Ils ne sont en concurrence que l'un avec l'autre. Une plus forte priorité du côté du flak assurera une fréquentation régulière du détour, supérieure même à la route plus courte mais moins intéressante.

On ajoute ensuite un AssaultPath au milieu de la map au niveau supérieur. Il conserve le PathTag des trois AssaultPaths précédents mais possède la position 2 et la priorité 1. Il n'y a en effet pas de choix à effectuer ici : un attaquant sur la route supérieure est obligé d'emprunter ce passage central (où se trouve le UDamage) et la priorité n'a donc pas beaucoup d'importance. Il s'agit surtout de forcer les bots à prendre la bonne direction une fois arrivés à ce point-ci.

À partir de là, il y a plusieurs solutions : soit on place de nouveau un AssaultPath sur la route directe, un sur le flak côté rouge, puis un au niveau de l'entrée supérieure de la base rouge, soit, et c'est la décision que j'ai prise, on pose simplement un autre AssaultPath à l'entrée supérieure rouge. Le bot arrivé au centre de la map se rendra alors directement à la base adverse, sans tenter de récupérer le flak des rouges. J'ai choisi cette solution car cette route est plus directe et rapide. En conséquence, un bot bleu aura cette trajectoire sur la route supérieure, avec 60% de chance de prendre le détour sud avec le canon flak et 40% de chance de prendre la route directe avec le lighting gun :

Voie du haut sans détour inutile

Maintenant, les choses se compliquent : il faut penser au retour, et la route supérieure est aussi valide qu'une autre pour ça. Malheureusement, le bot, arrivé au dernier AssaultPath, doit sauter en contrebas pour atteindre le drapeau et ne peut donc pas récupérer tout de suite la route du haut. On règle donc bNoReturn sur vrai dans le dernier AssaultPath. Au passage, on peut lui mettre bNoGrouping = vrai également, car il s'agit du dernier AssaultPath de cette route et le bot qui se trouve là n'a pas le temps d'attendre des coéquipiers.

Le bot qui emprunterait la route supérieure est sans doute peu intéressé par le canon flak au retour : la vitesse, en revanche, est cruciale. On met donc bNoReturn à vrai, également dans l'AssaultPath se situant au niveau du canon flak : ainsi, le bot qui revient avec le drapeau foncera par la route directe jusqu'à sa base.

Maintenant, il s'agit de trouver un moyen pour le bot de récupérer la route supérieure une fois qu'il a pris le drapeau.

Retour par une autre voie

Comme le bot va lister tous les AssaultPaths disponibles en fin de route, il va falloir baisser la priorité des 4 AssaultPaths qui se trouvent au bout des routes inférieures, ceux qui sont à l'entrée de la base rouge. On baisse donc leur priorité à 0.2, pour qu'ils aient tous 20% de chance d'être empruntés. Tous combinés, on obtient 80%. Les 20% restants seront donnés à l'AssaultPath qui va nous permettre de spécifier le retour par la voie supérieure.

L'AssaultPath qui se trouve en fin de chaîne de la route supérieure (PathTag "AttaqueBleuHaut") a bNoReturn = vrai et n'est donc pas pris en compte pour le chemin du retour. Du même coup, cela élimine toute la route supérieure, ce qui est un problème. Cependant, il y a deux ascenseurs qui permettent de récupérer la route du haut :

Accès au dernier niveau

L'ascenseur A n'est accessible que depuis le deuxième niveau et se trouve malheureusement à proximité du seul chemin inférieur que nous avons défini comme bNoReturn = vrai. Cela signifie qu'il se situe sur un chemin que nous avons délibérément interdit à un bot sur le retour, car il est trop dangereux : il nécessite en effet que le bot soit longuement exposé en restant dans la grande salle du drapeau. En revanche, l'ascenseur B se trouve au rez-de-chaussée et permet de retrouver le troisième étage. Il s'agit donc d'un bon point de passage.

La solution est donc de dupliquer l'AssaultPath qui se trouve au bout de la route supérieure et d'en placer une copie au sommet de l'ascenseur B, en mettant bNoReturn = faux et bReturnOnly = vrai. Il faut alors conserver le bNoGrouping à vrai, mais aussi la position à 3 : il faut se rappeler que le bot va chercher tous les AssaultPaths en fin de chaîne et que l'AssaultPath qui se trouve au bout du chemin d'attaque a pour position 3. Comme il est éliminé au retour, en raison du bNoReturn, il faut un AssaultPath de position équivalente pour que cette route soit prise dans le sens inverse. Quand à la priorité, elle était à 1 à l'aller, car l'AssaultPath d'attaque était le seul chemin que nous avions défini pour l'attaque, mais pour le retour, notre nouvel AssaultPath est en concurrence avec les 4 AssaultPaths des routes inférieures, et la valeur de 1 (100%) doit donc être partagée entre 5 points. 1/5 = 0,2.

Comme tous les AssaultPaths de la voie supérieure ont le même PathTag, la route sera utilisable aussi bien à l'aller qu'au retour et le bot n'est pas confus. Voilà le système complet de notre route supérieure :

Système complet de la route supérieure

Il ne reste plus qu'un seul paramètre à régler : sélectionner tous les AssaultPaths et définir qu'ils servent à attaquer le drapeau rouge ! En effet, ces AssaultPaths ne servent à rien si les bots savent qu'ils existent mais ignorent à quel objectif ils se rapportent. Les objectifs sont les objectifs du mode Assaut, les drapeaux de CTF, la balle et les buts de BR, les points de domination du mode Double domination et les relais et générateurs d'ONS. Ils sont tous des sous-classes de GameObjective. Pour faire simple, les bots décident d'utiliser un AssaultPath quand son ObjectiveTag correspond au Tag (Event => Tag) d'un objectif qu'ils désirent attaquer. Dans notre cas, il s'agit du drapeau rouge. Par défaut, les drapeaux de CTF ont pour tag "xRedFlagBase" et "xBlueFlagBase". Pour les AssaultPaths empruntés par les bots de l'équipe bleu, il faut donc mettre ObjectiveTag = xRedFlagBase, car il s'agit de l'objectif qu'ils désirent attaquer. Ne vous inquiétez pas pour le retour : les bots savent qu'une fois qu'ils possèdent le drapeau, ils doivent suivre les AssaultPaths qui ont ce même ObjectiveTag dans le sens inverse, bien qu'en réalité, leur véritable "objectif" à ce moment là soit le drapeau bleu.

Voici donc ce qui se passe lorsque qu'un bot bleu décide ou reçoit l'ordre d'attaquer:

Il utilise ainsi toutes les routes à l'aller comme au retour. On peut remarquer qu'aux étapes 3 et 7, il y a une situation étrange : à chaque fois, le bot a 20% de chances de choisir n'importe laquelle des 4 routes disponibles. Il lui reste donc, à ce moments-là, 20% de "chances inutilisées" (c'est à dire que les priorités additionnées des AssaultPaths qu'il consulte ne s'additionnent pas pour atteindre 1, ou 100%, mais n'atteignent que 0.8, 80%). Cela a lieu car les mêmes AssaultPaths sont utilisés à l'aller comme au retour, où les paramètres opérationnels sont différents. Ceci dit, ça n'a aucune importante : tant que la valeur des priorités est inférieure à 1 et égale partout, les bots ne manifesteront pas de préférence et utiliseront les différentes routes de manière égale. Ils se comporteront tout simplement comme si chacune des routes disponibles à ce moment-là avait une priorité de 0.25.

Une fois que ceci est fait, les bots bleus sont compétents. Il faut alors dupliquer tout le travail accompli en changeant le nom des PathTags et de leur ObjectiveTag pour pointer dans l'autre sens sur le drapeau bleu. Ainsi, les bots rouges posséderont le même arsenal de chemins que leurs adversaires.

C'est ainsi que CTF-Senate est configurée et c'est ainsi que fonctionnent les AssaultPaths. Comme on le voit, il peut valoir le coup, une fois la map terminée et le pathing presque finalisé, de prendre quelques instants pour planifier correctement les AssaultPaths en considérant bien quelles routes doivent ou ne doivent pas être prises à tel ou tel moment. Plus le nombre de route augmente, plus la manière dont elles se croisent se complexifie, plus il devient crucial d'avoir un grand nombre d'AssaultPaths intelligemment configurés pour que les bots restent efficaces.

Les AssaultPaths pour d'autres modes

On l'a vu, ce tutoriel est centré sur le mode CTF. Ceci dit, les choses restent valables dans leur entièreté dans les autres modes à objectifs. Cependant, il sera important de faire plus d'efforts :

© 2005-2024, by Hellkeeper.

Valid XHTML 1.1 & CSS 3