IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

La version 0.10 de Bevy, le moteur de jeu orienté données construit en Rust, est disponible,
Elle corrige des bogues et apporte de nouvelles fonctionnalités

Le , par Bruno

9PARTAGES

6  0 
L’équipe en charge de Bevy a annoncé la sortie de la version 0.10 de Bevy, un moteur de jeu basé sur les données et construit en Rust. « Grâce à 173 contributeurs, 689 pull requests, les évaluateurs de la communauté, et nos généreux sponsors, je suis heureux d'annoncer la sortie de Bevy 0.10 sur crates.io », ont écrit les contributeurs.

Bevy est un moteur de jeu basé sur les données et construit en Rust. Il est gratuit et open source. Le code source complet est sur GitHub. Le langage de programmation Rust est un projet ambitieux de la Fondation Mozilla - un langage qui prétend être la prochaine étape de l'évolution du C et du C++.

Rust est un langage de programmation compilé multiparadigme, conçu par Graydon Hore alors employé chez Mozilla Research. Utilisé par plusieurs grandes entreprises et par de nombreux développeurs dans le monde, Rust est devenu le langage de base pour certaines des fonctionnalités indispensables du navigateur Firefox et de son moteur Gecko, ainsi que pour le moteur Servo de Mozilla.


Depuis la dernière version il y a quelques mois, l’équipe a ajouté une tonne de nouvelles fonctionnalités et corrigé des bugs. Voici, ci-dessous, quelques points forts :

Schedule ECS v3

Schedule v3 est l'aboutissement d'un important travail de conception et d'implémentation. Les API de programmation sont une partie centrale et déterminante de l'expérience des développeurs Bevy. Jetons un coup d'œil à ce qui a été livré dans la version 0.10.

Un calendrier unique et unifié

Avez-vous déjà voulu spécifier que le système_a s'exécute avant le système_b, pour vous heurter à des avertissements déroutants indiquant que le système_b n'est pas trouvé parce qu'il se trouve dans une étape différente ?

Ce n'est plus le cas ! Tous les systèmes d'un même programme sont désormais stockés dans une structure de données unique, avec une perception globale de ce qui se passe.

Cela simplifie la logique interne, rend le code plus robuste à la refonte, et permet aux auteurs de plugins de spécifier des invariants de haut niveau (par exemple, « le mouvement doit se produire avant la vérification des collisions ») sans s'enfermer dans un emplacement exact de l'agenda.

Ajout des fonctions Rust

Les systèmes (qui sont juste des fonctions Rust normales !) sont la façon de définir la logique du jeu dans Bevy ECS. Avec Schedule v3, vous pouvez ajouter des systèmes à votre application comme vous le faisiez dans les versions précédentes :

Code : Sélectionner tout
app.add_system(gravity)

Cependant, Schedule v3 a de nouveaux atouts dans sa manche ! Vous pouvez désormais ajouter plusieurs systèmes à la fois :
app.add_systems((apply_acceleration, apply_velocity))

Par défaut, Bevy fait fonctionner les systèmes en parallèle. Dans les versions précédentes de Bevy, vous ordonniez les systèmes comme suit :
Code : Sélectionner tout
1
2
3
4
app
    .add_system(walk.before(jump))
    .add_system(jump))
    .add_system(collide.after(jump))

Vous pouvez toujours le faire ! Mais vous pouvez maintenant le compresser en utilisant add_systems :

Code : Sélectionner tout
1
2
3
4
5
6
// much cleaner!
app.add_systems((
    walk.before(jump),
    jump,
    collide.after(jump),
))

before() et after() sont des outils très utiles ! Toutefois, grâce à la nouvelle fonction chain(), il est désormais beaucoup plus facile d'exécuter des systèmes dans un ordre spécifique :

Code : Sélectionner tout
1
2
// This is equivalent to the previous example
app.add_systems((walk, jump, collide).chain())

chain() exécutera les systèmes dans l'ordre où ils ont été définis. Le chaînage est également associé à la configuration par système :

Code : Sélectionner tout
app.add_systems((walk.after(input), jump, collide).chain())

Ensembles de systèmes configurables

Dans Schedule v3, l'idée d'« ensemble de systèmes » a été redéfinie pour permettre un contrôle plus naturel et plus souple de la manière dont les systèmes sont exécutés et programmés. L'ancien concept d'"étiquette système" a été combiné avec celui d'"ensemble", ce qui donne une abstraction simple mais puissante.

Les ensembles de systèmes sont des collections nommées de systèmes qui partagent la configuration du système entre tous leurs membres. Le fait d'ordonner des systèmes par rapport à un ensemble de systèmes applique cet ordre à tous les systèmes de cet ensemble, en plus de la configuration de chaque système individuel.

Voyons tout de suite à quoi cela ressemblerait. Vous définissez les ensembles de systèmes comme suit :

Code : Sélectionner tout
1
2
3
4
5
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
enum PhysicsSet {
    Movement,
    CollisionDetection,
}
Vous pouvez ajouter des systèmes à des ensembles en appelant la méthode in_set :

Code : Sélectionner tout
app.add_system(gravity.in_set(PhysicsSet::Movement))

Vous pouvez combiner cela avec les nouvelles fonctionnalités du système mentionnées ci-dessus :

Code : Sélectionner tout
1
2
3
4
5
app.add_systems(
    (apply_acceleration, apply_velocity)
        .chain()
        .in_set(PhysicsSet::Movement)
)

Les systèmes peuvent appartenir à un nombre quelconque d'ensembles :

Code : Sélectionner tout
1
2
3
4
5
app.add_system(
    move_player
        .in_set(MoveSet::Player)
        .in_set(PhysicsSet::Movement)
)

La configuration est ajoutée à des ensembles comme celui-ci :

Code : Sélectionner tout
1
2
3
4
app.configure_set(
    // Run systems in the Movement set before systems in the CollisionDetection set
    PhysicsSet::Movement.before(PhysicsSet::CollisionDetection)
)

Les ensembles peuvent être imbriqués dans d'autres ensembles, ce qui leur permet d'hériter de la configuration de l'ensemble parent :

Code : Sélectionner tout
app.configure_set(MoveSet::Enemy.in_set(PhysicsSet::Movement))

Les ensembles peuvent être configurés plusieurs fois :

Code : Sélectionner tout
1
2
3
4
5
// In PlayerPlugin:
app.configure_set(MoveSet::Player.before(MoveSet::Enemy))

// In PlayerTeleportPlugin
app.configure_set(MoveSet::Player.after(PortalSet::Teleport))

Il est essentiel que la configuration du système soit strictement incremental : il n'est pas possible de supprimer les règles ajoutées ailleurs. Lorsque cette règle est combinée avec les règles robustes de confidentialité des types de Rust, les auteurs de plugins peuvent prendre des décisions prudentes sur les invariants exacts qui doivent être respectés, et réorganiser le code et les systèmes en interne sans briser les consommateurs.

Les règles de configuration doivent être compatibles entre elles : tout paradoxe (comme un système défini à l'intérieur de lui-même, un système qui doit fonctionner avant et après un ensemble, des cycles d'ordre, etc) entraînera une panique à l'exécution avec un message d'erreur utile.

Programmer directement des systèmes exclusifs

Les « systèmes exclusifs » sont des systèmes qui ont un accès direct et mutable à l'ensemble du monde ECS. Pour cette raison, ils ne peuvent pas être exécutés en parallèle avec d'autres systèmes. Depuis la création de Bevy, les développeurs de Bevy ont voulu programmer les systèmes exclusifs (et les commandes de nettoyage) par rapport aux systèmes normaux. Maintenant, c'est possible ! Les systèmes exclusifs peuvent maintenant être programmés et ordonnés comme n'importe quel autre système.

Code : Sélectionner tout
1
2
3
4
app
    .add_system(ordinary_system)
    // This works!
    .add_system(exclusive_system.after(ordinary_system))

Ceci est particulièrement puissant, car les vidanges de commandes (qui appliquent les commandes en file d'attente ajoutées dans les systèmes pour faire des choses comme créer et supprimer des entités) sont maintenant simplement exécutées dans le système exclusif apply_system_buffers.

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
app.add_systems(
    (
        // This system produces some commands
        system_a,
        // This will apply the queued commands from system_a
        apply_system_buffers,
        // This system will have access to the results of
        // system_a's commands
        system_b,
    // This chain ensures the systems above run in the order
    // they are defined
    ).chain()
)

Exécutez les conditions

Les systèmes peuvent avoir un nombre illimité d'executeurs de conditions, qui sont « simplement » des systèmes qui renvoient un boolean. Si les booleans renvoyés par tous les executeurs de conditions d'un système sont vrais, le système sera exécuté. Dans le cas contraire, le système sera ignoré pour l'exécution du programme en cours :

Code : Sélectionner tout
1
2
3
4
5
6
7
// Let's make our own run condition
fn game_win_condition(query: Query<&Player>, score: Res<Score>) -> bool {
    let player = query.single();
    player.is_alive() && score.0 > 9000
}

app.add_system(win_game.run_if(game_win_condition));

Executer des conditions a aussi un certain nombre d'opérations "combinatoires",
Elles peuvent être annulées avec not() :

Code : Sélectionner tout
app.add_system(continue_game.run_if(not(game_win_condition)))

Ils peuvent également être combinés avec and_then et or_else :

Code : Sélectionner tout
app.add_system(move_player.run_if(is_alive.or_else(is_zombie)))

Bevy 0.10 est livré avec une belle collection d’exécuteurs de conditions intégrées. Il est possible de facilement exécuter des systèmes s'il y a des événements à traiter, des délais qui se sont écoulés, des ressources qui ont changé, des changements d'état d'entrée, des états qui ont changé, et plus encore.

Les exécuteurs de conditions peuvent également servir d'outil d'optimisation léger. Les exécuteurs de conditions sont évalués sur le thread principal, et chaque critère d'exécution est évalué exactement une fois à chaque mise à jour du programme, au moment du premier système de l'ensemble qui en dépend. Les systèmes désactivés par les exécuteurs de conditions ne génèrent pas de tâche, ce qui peut s'avérer utile pour de nombreux systèmes. Mais comme toujours, il faut faire des comparaisons.

Les exécuteurs de conditions ont remplacé les « critères d'exécution » des versions précédentes de Bevy. L’équipe se réjouit de s’être débarrassée des redoutables « critères d'exécution en boucle ». ShouldRun::YesAndCheckAgain n'était pas vraiment simple à comprendre, que ce soit pour les développeurs de moteurs ou les utilisateurs. C'est toujours un mauvais signe lorsque les enums de type bool ont quatre valeurs possibles.

Source : Bevy

Et vous ?

Quel est votre sur ce moteur de jeux écrits en Rust ?

Voir aussi :

C-rusted : les avantages de Rust, en C sans les inconvénients, une analyse des trois chercheurs de l'Université de Parme en Italie

Microsoft annonce Rust preview pour Windows, alors que la comparaison entre Rust et C++ reste un sujet d'actualité

Une erreur dans cette actualité ? Signalez-nous-la !