Saturday, August 15, 2026

Le fight club, version cflags

Last summer, I started reworking collisions in my game engine. The idea was to be able to define groups, so that e.g. collision-based communications between a stunned blador and its feet would never interfere with a bouncy branch and things it bounces away. Sure, there was way to do that already, by assigning them separate collision flags, but I've long ran out of these, forcing me to make weird groups and combinations.

Oui, parce que bon, ça fait maintenant un moment que j'ai ouvert la branche "new-cflags" dans laquelle on a la possibilité de définir des groupes de collision, et je m'en suis même servi pour gérer les portes, mais si je veux permettre à un appleman de rebondir contre les autres applemen tout en passant "à travers" les petits vers, je me retrouve devant un imbroglio avec la question épineuse "je le mets où, mon nouveau flag ? et est-ce que ça coince ?"

With recent work on the appleman, I wanted to make a distinction between "weapon-sensitive area, from a light object" and "weapon-sensitive area, from a heavy objects", but I wouldn't know how to encode it anymore. So far, the groups had only been used to implement the doors, but felt like it was time to define a new group, to deal with every collision that deals damage to entities in the game... which I finally decided to call the "fight" group.

Alors c'était l'occasion de se demander "et si en fait on faisait un groupe pour toutes ces actions qui retirent des points de vie à un des objets ?". Petit à petit, hein, en vérifiant qu'on ne casse rien (et donc, forcément avec une vidéo Screenshot Saturday où tout d'un coup, on passe à travers les branches au lieu de rebondir et à travers les pommes sans qu'elles ne se doutent de rien...)

Un nouveau G_FIGHT donc (j'ai un peu chipoté pour trouver le nom du groupe puis le Fight Club s'est rappelé à mon bon souvenir, tel une évidence inévitable). Peu à peu, les différents scripts-personnages sont convertis en nettoyant les vieilleries comme les scripts avec des valeurs numériques plutôt que des combinaisons de symboles. Puis arrive le moment crucial de réactiver la branche-qui-rebondit, et là, je me rends compte que garder dans G_FIGHT l'action principale F_STOMP, celle que Bilou utilise jouer à Super Mario assommant un goomba, ça ne va pas marcher. ça va imposer aux zones de collision destinées à être de simples plate-formes de faire partie du Fight Club alors qu'elles n'ont même pas de "points de vie". D'autant plus problématiques qu'on a aussi des flags du type F_PLATFORM pour, par exemple, empiler des taille-crayons sans qu'ils n'infligent de dommages.

It wasn't that straightforward ... I mostly broke everything first and then repaired things one after another. Last week, for instance, only the woodworm would still interact with Bilou. but now the code is cleaner and I think everything is repaired ... I may to a bit more time travelling to check the blador / tiled pencils interaction ... it looks like it isn't working as good as it did previously.

Then a few things just did not resume working, like jumping higher when you press the JUMP button while bouncing on a branch ... mostly because some hit areas needed to be duplicated and transition depending on them needed to be reassigned to the new area. Current GobScript doesn't make that easy to refactor. 

Ah, and yeah, below is a snippet of what the area collisions look like now.   

Heureusement, j'avais prévu de garder une portion des flags "neutres" (CFLAGS_LONE_FLAGS), valables qu'il y ait accord sur les groupes ou non. On pourra donc mettre la branche dans le groupe G_GROUND (qui n'existe pas encore) dont F_PLATFORM ferait partie et lui ajouter un "ah, oui, on prend F_STOMP aussi, même si ça ne fait pas vraiment partie du groupe". Certaines des zones de collisions ont dû être dédoublée (une avec G_FIGHT, l'autre sans), un petit défaut dans la réécriture quand ça arrive et on se retrouve avec des branches qui ne rebondissent plus aussi bien qu'avant ... un petit schéma, un peu de ddd et ça se remet en place. Le code pour tester deux zones de collisions ressemble donc maintenant à


 cflags GobArea::test(const GobArea *o, GameObject *g, cflags mask, GobCollision* gc) const {
     if (o==this) return 0;
     cflags group = mask & CFLAGS_GROUP_MASK;
-    if (group && (flags & CFLAGS_GROUP_MASK) != group) return 0;
+    if ((flags & CFLAGS_GROUP_MASK) != group) mask &= ~CFLAGS_IN_GROUP_FLAGS;
     if ((mask & flags & CFLAGS_EXPR_MASK)==0) return 0;
 
     // congratulations: you may compare coordinates, now.
     

No comments: