>_ DevTrendsfr

Langue

Accueil

Langages

Sections

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embarqué Sécurité
Rust

Comment mettre de l'ordre dans la logique d'IA pour les jeux et la robotique avec la bibliothèque Bonsai

Bonsai

Quiconque a déjà essayé de programmer le comportement d'un PNJ complexe pour un jeu ou d'un robot autonome en utilisant des machines à états finis (FSM) connaît ce moment de désespoir. Au début, tout est simple : trois états ("patrouille", "poursuite", "attaque") et une poignée de transitions. Mais le projet grandit. Des vérifications de santé apparaissent, des réactions aux tirs par derrière, se mettre à couvert, recharger l'arme. Soudain, le graphe de transitions se transforme en un gâchis de spaghetti, où l'ajout d'une nouvelle action casse la moitié des anciennes connexions.

Le développement de jeux a longtemps trouvé un remède à ce problème sous la forme des Behavior Trees. Ils ont été popularisés à l'époque par Halo 2 et Unreal Engine. Aujourd'hui, ce concept est activement utilisé en robotique et dans les systèmes autonomes.

Récemment, je suis tombé sur Bonsai — une implémentation légère et rapide des behavior trees en Rust, avec des liaisons Python fournies par l'auteur.

Qu'est-ce qu'un Behavior Tree en termes simples

Si l'on écarte la terminologie académique, un behavior tree est une structure hiérarchique de règles qui définit la réaction d'un agent au monde. Le principal avantage de cette approche est la modularité. Chaque nœud est isolé et renvoie l'un des trois statuts à son parent :

  • Success (action terminée avec succès)
  • Failure (l'action a échoué)
  • Running (l'action est toujours en cours)

Le nœud parent décide qui appeler ensuite en fonction de ce résultat.

Dans Bonsai, la logique est assemblée à partir de plusieurs types de nœuds de base :

// Выполняет A, затем B. Если A падает, цепочка прерывается
Sequence([A, B])

// Пробует A. Если падает, пробует B
Select([A, B])

// Классическое ветвление
If(condition, A, B)

// Выполняет A и B параллельно, ожидая завершения обоих
WhenAll([A, B])

// Запускает параллельно и ждет первого завершившегося
Race([A, B])

L'arbre est parcouru de haut en bas, de gauche à droite. Si un ennemi disparaît du champ de vision pendant le visée, la branche d'interruption réagira instantanément au prochain cycle de tick. Vous n'avez pas besoin d'écrire manuellement des centaines de conditions de sortie pour l'état actuel, comme dans les FSM ordinaires.

Comment fonctionne Bonsai en coulisses

Bonsai est écrit en Rust pur sans surcharge supplémentaire. Pour l'ajouter à votre projet, ajoutez simplement la dépendance à Cargo.toml :

[dependencies]
bonsai-bt = "*"

Si vous travaillez en tandem avec Python (par exemple, pour le prototypage ou les scripts de robots sur ROS), le package s'installe via pip :

pip install bonsai-bt

Le problème des tâches longues

L'arbre de comportement doit être interroger régulièrement et sans délai. Si un nœud à l'intérieur bloque le thread pendant une demi-seconde (par exemple, effectuant un pathfinding lourd ou une requête réseau vers un capteur), tout le système se figera.

L'auteur de Bonsai a résolu ce problème grâce au statut Running et aux canaux de messages. Les tâches synchrones ou asynchrones longues sont déplacées vers des threads d'arrière-plan. Le nœud de l'arbre retourne simplement Running à chaque tick jusqu'à ce qu'un signal de complétion ou d'erreur arrive du canal. Le dépôt contient un exemple clair async drone démontrant le contrôle de drone en mode asynchrone.

Où cela s'avère utile

Les tags du dépôt ne sont pas un hasard : ROS2, Bevy et Unreal Engine. Voici les scénarios typiques où Bonsai vous sauve les nerfs :

  1. Jeux sur Bevy ou autres moteurs Rust. Pour implémenter l'IA ennemie, les alliés ou les événements procéduraux.
  2. Robotique et drones. Construire des algorithmes de navigation déterministes, l'évitement d'obstacles et l'exécution de missions.
  3. Pipelines backend avec branchement complexe. Si vous avez une chaîne de tâches avec des retries, des timeouts et des branches parallèles, l'assembler via Behavior Tree est souvent plus pratique que de construire des instructions match et try/catch imbriquées.

Avantages et inconvénients

Le projet laisse une impression agréable par son minimalisme. Il n'y a pas d'abstractions surchargées ici, le code est propre et le déterminisme de la logique rend le débogage prévisible.

Du côté des inconvénients : la documentation dans le README lui-même est assez brève. Pour comprendre toutes les nuances des nœuds parallèles (WhileAll, After), vous devrez explorer le dossier examples/ et les tests. Il n'y a pas non plus d'éditeur visuel d'arbre prêt à l'emploi, vous devrez donc construire l'arbre en code.

Si vous avez besoin d'un outil clair, rapide et prévisible pour la logique des agents en Rust ou Python sans dépendances lourdes, Bonsai mérite définitivement une étoile sur GitHub et un test dans votre projet personnel.

Projets similaires