RTS Game AI Thread

14

J'ai un projet pour créer un jeu de stratégie en temps réel à partir de zéro. Je suis encore au début de la planification, mais j'ai programmé un peu pour voir la mécanique.

Je sais programmer. J'ai également une bonne idée de la façon dont je structurerai les classes de jeu et l'IA basée sur des règles (machine d'état) pour le joueur sur ordinateur.

Je veux développer des doctrines, qui donneront un comportement spécifique à une unité spécifique (mais peuvent être utilisées sur plusieurs unités en même temps), telles que Scout, Follow Mission Route, Hold Position (attaquer tout ennemi qui approche ou battre en retraite s'il est débordé) , etc...

Les doctrines ne s'appliqueront qu'aux unités, donc elles auront une perspective d'unité, et ne seront pas conscientes sur l'ensemble de la situation de la carte.

L'IA informatique analysera l'intégralité de la carte visible et décidera de la soctrine à affecter à chaque unité en fonction d'un autre ensemble de règles.

Je fais cela en C # avec OpenGL.

Pour l'instant, je n'ai pas grand chose, seulement quelques éléments en tests avant de commencer ma conception principale. J'ai une boucle de jeu où tout le traitement du jeu (où j'appellerai le mouvement de mise à jour, le combat, le rendu, etc., l'un après l'autre) se produira, il est appelé très souvent si l'événement Application.Idle.

Maintenant, je me demandais. Puisqu'il y aura beaucoup de choses à traiter dans la boucle de jeu, l'ordinateur AI et les unités devraient-ils sélectionner leurs actions dans cette boucle ou sera-ce trop lent?

Si je veux que tout soit simultané, dois-je créer un thread distinct pour l'IA de l'ordinateur? Ou même un fil distinct pour chaque unité?

Je n'ai pas beaucoup d'expérience avec le multi-threading. Quelle serait la meilleure approche pour cela?

Nate
la source
Indépendant - considéré comme Ogre3D à la place d'OpenGL?
En fait, non, je n'en ai jamais entendu parler. J'utilise OpenGL parce que c'est ce qu'on m'a enseigné dans mes cours. Ogre3D peut-il aussi faire de la 2D? Je suppose que c'est possible, mais on ne sait jamais ...
Oui, il a même sa propre boîte à outils GUI (cegui). Par exemple, TorchLight est construit avec lui. Cela peut vous faire gagner du temps car il s'enroule bien autour d'OpenGL. ogre3d.org/tikiwiki/MOGRE
"Ou même un fil distinct pour chaque unité" Hell no. Le surdébit d'un fil est beaucoup trop grand. Pour l'un, il y a la mémoire réservée pour la pile du thread (1 Mo par défaut). Et les commutateurs de fil sont aussi chers.

Réponses:

3

Que signifie «à partir de zéro»? Pouvez-vous utiliser quelque chose comme XNA à la place avec DirectX?

Vous devez rendre quelque chose entre 30 et 60 images par seconde pour avoir un mouvement fluide. Il n'y a vraiment pas besoin d'avoir plus de fps.

Si le rendu + la logique prend moins de moins que les 16 ms que vous donne 60fps, alors il ne devrait pas être nécessaire d'avoir un thread AI.

Si vous n'avez pas assez de temps entre le rendu des images, vous devrez réfléchir très attentivement à ce qui doit être mis à jour à chaque image et ce qui ne le fait pas.

J'imagine que la partie "doctrines" devrait être aussi simple et efficace que possible afin qu'elle puisse être mise à jour à chaque image, au moins pour les unités visibles et les autres unités à proximité. Les unités qui n'influencent pas directement les unités visibles peuvent être mises à jour moins fréquemment (et, en conséquence, avec un delta T plus grand).

L'IA principale a plus de travail à effectuer, car elle doit traiter toutes les unités sur la carte et définir une stratégie, elle devrait donc nécessiter la plupart du temps de calcul. C'est le premier candidat pour un fil séparé.

Notez que vous voudrez peut-être ajouter un autre calque entre les deux, quelque chose comme une IA de niveau escouade. Fondamentalement, l'IA de chaque unité doit s'assurer que l'unité répond "intelligemment" à la situation immédiate, elle doit donc être rapide et réactive. L'IA de l'escouade est responsable des actions "intelligentes" de plusieurs unités, réparties sur plusieurs secondes, comme trouver un pont si l'escouade a besoin de traverser une rivière. Et l'IA principale devrait diriger les actions de nombreuses escouades sur une longue période.

Surtout si vous n'avez pas beaucoup d'expérience, ne faites pas de threading si vous n'êtes pas obligé. Ce sera compliqué car c'est sans charge supplémentaire. Vous pouvez apprendre le multithreading en tant que projet distinct ou en tant qu'extension de celui-ci une fois qu'il est en état de fonctionnement . Bonne chance!


la source
0

Avoir un fil distinct pour l'IA. Mais pas pour chaque unité car elle consommerait trop de ressources OS et la synchronisation serait un cauchemar.

Assurez-vous que le thread AI trouverait une opportunité à exécuter. Ne le prenez pas à la légère, si le thread principal fait trop de choses, il ne trouvera peut-être jamais cette opportunité! Si vous donnez simplement une priorité plus élevée au thread AI, le jeu ne répond plus, ce qui est inacceptable.

Donc, sélectionnez soigneusement les points de synchronisation et / ou les événements dans la boucle principale et laissez le thread AI terminer ses calculs pendant que le thread principal s'arrête. Par exemple, si l'unité utilisateur voit une autre unité AI, synchronisez-la, de sorte que votre unité voit une unité mise à jour vice versa.


la source
0

Je travaille également sur un jeu RTS à partir de zéro. Je ne l'ai pas encore testé, mais mon idée était d'exécuter l'unité AI dans la boucle de jeu principale pour toutes les unités actuellement visibles par le joueur (dans la partie de l'écran que le joueur voit réellement ou près de la bordure de cet écran) ), car il est plus probable que le joueur bouge un peu l'écran.

Les autres unités sont vérifiées dans un fil distinct, et j'ai deux priorités: 1. Les unités qui sont dans des endroits qui sont visibles par l'utilisateur s'il y déplace l'écran. 2. Unités qui se trouvent dans des zones cachées (pas encore explorées et "brouillard de guerre").

Pour les unités en priorité secondes, je fais moins souvent la boucle et je compense en les déplaçant rétrospectivement si nécessaire.


la source
1
Cela semble très compliqué.
Votre idée sonne bien, sauf pour la première partie sur le déplacement des unités dans et hors de la boucle de jeu principale. Toute l'IA doit être effectuée dans sa propre boucle, où vous pouvez choisir de sauter la boucle à chaque xitération sur les unités de faible priorité.
Olhovsky
0

Que vous ayez besoin de multithread ou non, ce pourrait être une bonne idée de préparer l'IA à être multithread.

Votre thread principal mettrait à jour le monde, cocherait la physique, etc., puis remplirait une structure de données qui représente la vision du monde de l'IA: position des unités, état des ressources, etc. Cette structure de données mettrait en cache les systèmes principaux, plutôt que de simplement leur tendre des pointeurs. Ceci est parfois appelé un point de synchronisation.

Passez cette structure de données à l'IA et ne lui permettez que de raisonner sur le contenu de cette structure. Si vous trouvez que l'IA a besoin de plus d'informations, ajoutez-la à la structure. Dans le langage de l'IA, cela s'appelle souvent un tableau noir, mais pourrait également être appelé cache. Ne laissez jamais l'IA écrire dans le cache, la sortie doit passer par une structure de données distincte.

Cette configuration vous permettra de paralléliser le jeu car l'IA n'a plus de dépendance directe avec les autres systèmes de jeu. Ces systèmes n'ont pas besoin d'être threadsafe et vous ne devriez jamais obtenir de verrous. Vous pouvez exécuter en toute sécurité le moteur de rendu ou quelque chose pendant que l'IA s'éloigne.

Comme avantage secondaire, vous pouvez à l'avenir étendre le cache en dégradant les informations que vous obtenez des autres systèmes au fil du temps, en simulant l'incertitude plutôt que la connaissance exacte.

tenpn
la source