15 août 2024

Game dev #04: et l'aventurier décida soudainement d'encombrer ses sacs

 Salutations, voyageur !

 


 

Nous voilà à nouveau ici, pour célébrer la complétion de notre quatrième bloc de développement de Lampyre, qui était dédié aux bases de l'inventaire et du ramassage d'objets. Le but était d'apprivoiser la construction d'UI (interface utilisateur) au travers de Godot, et de permettre aux créatures de transporter des objets sur elle (dans leur sac), ainsi que dans leurs bras !

 

 La note de patch

Comme pour les blocs précédents, les fonctionnalités se sont étendues un peu plus loin que ce qui était initialement prévu. Revoyons ce qui a été fait en une courte liste:

1) Et le loot fut créé: Les objets sont maintenant une classe à part entière dans Lampyre. Il peuvent être instanciés dans le monde du jeu où il tombent à terre, ou bien être passés comme information au travers du code (dans les sacs, les coffres, les tables de butin...). Ils ont un nom, un poids, une description pipou, peuvent s'empiler à plusieurs ou rester uniques. 

Comme dans de nombreux jeux où le butin est important, maintenir la touche ALT enfoncée affiche clairement le nom de tous les objets au sol autour de nous.

2) Un seul maître, pour contrôler tous les blings: Pour faciliter la gestion des objets instanciés sur la carte, ils sont regroupés sous un node gestionnaire commun qui s'occupe de leur création et destruction dans l'arbre de la scène. Par exemple, lorsque l'on souhaite supprimer le modèle d'un objet instancié de la carte, c'est ce dernier qui relaie cette demande par signal au master node, qui s'occupe de son cas. Oui, c'est un peu comme passer un post-it à un enfant, pour indiquer à son parent qu'il doit aller le noyer dans la rivière. Mais cela optimise l'instanciation des objets. Ne jugez pas mes systèmes infanticides.

3) Viens dans mon sac, ou viens dans mes bras:  Un objet peut être ramassé par une créature de deux façon : soit dans un sac, s'il est assez petit, et si la créature possède un inventaire. Soit il doit être porté, limitant les actions de la créature tant qu'elle l'a dans les bras. Tout le système d'affichage de commandes a été révisé pour permettre au joueur de ramasser les objets proches, soit en s'en approchant, soit en passant directement la souris dessus pour les sélectionner.

4) Do you even lift, bro ?: Chaque créature a un score de force qui détermine la quantité d'objets qu'elle peut porter dans ses bras, ou la taille par défaut de son inventaire. Cette statistique est limitée entre 0 et 10 pour les vyrrlins (de 0 à 100 kg portés dans les bras), mais techniquement, elle peut monter jusqu'à 20 pour les créatures les plus imposantes. La force permet aussi de calculer la rapidité avec laquelle une créature ramasse un objet lourd (entre 0,5 et 2 secondes selon le score et le poids de l'objet), mais aussi la pénalité de vitesse infligée quand elle est chargée. 

Porter plus de 70% de sa capacité en charge draine l'énergie (cela ne vous fait pas lâcher les objets, mais peut vous mettre dans une situation délicate si des ennemis vous abordent soudainement), et à 100% et plus, tout retombe au sol. Le joueur est averti de ces limites lorsqu'il passe sa souris sur des objets soulevables (instruction en jaune = va provoquer un drain d'énergie, et instruction en rouge = va tout vous faire lâcher).

Enfin, il est évidemment impossible d'utiliser le dash, d'attaquer ou d'esquiver en portant des objets. Prendre des dégâts a une chance sur deux de faire tomber un objet de la pile que vous portez. À tout moment, le joueur peut instantanément lâcher sa charge avec un raccourci.

En outre, j'ai fait en sorte que le choix d'auto-attaque soit mémorisé avant le port d'objet. Si vous aviez désactivé vos auto-attaques avant de commencer à porter des objets, vous conserverez votre mode passif en les lâchant, jusqu'à ce que vous indiquiez le contraire. Cela vous évitera de décocher une flèche malencontreuse sur un ennemi que vous tentiez de ne pas blesser.

5) Des sacs ! Plein de sacs !: L'interface pour tous les inventaires du jeu est fonctionnelle ! De loin la partie la plus chronophage (plus d'informations par la suite sur ce segment), je vous passe les détails à propos des comportements classiques d'une fenêtre d'inventaire de RPG ; sachez juste que toutes les créatures ont un inventaire par défaut, dont la limite en poids est à nouveau dépendante de sa force. Les structures comme les coffres ou les stations sont également des inventaires, manipulables comme nos sacs.

On peut déplacer les objets, les scinder, les organiser automatiquement, les rechercher grâce à un petit champ d'input. Les raccourcis sont toujours affichés pour ne jamais être perdu. On peut aussi balancer des objets dans la flamme éternelle de notre autel, ou carrément y jeter des piles d'objet lourds. Je souhaitais un moyen de se débarrasser de façon permanente des objets, mais je me voyais mal permettre au joueur de détruire des armes ou des armures en métal au milieu de nulle part - je trouve cette solution élégante, même s'il y aura des mécaniques de recyclage plus satisfaisantes dans le futur !

6) Ma passion pour les coffres et les tas de bois: On peut ainsi stocker les objets : soit dans des contenants, comme les coffres, pour les petits objets. Soit sur des stations adaptées pour les objets les plus lourds. Entendez par station, un endroit où ces objets sont stockés pour être protégés, et/ou emmagasinés pour servir à un autre but : des armes stockées sur un râtelier, des buches de bois qui attendent d'être travaillées à un atelier de menuiserie, un ballot de foin qui attend d'être mangé dans une auge de créature...

Le joueur peut facilement et librement récupérer ces grands objets de leur stockage, en les sélectionnant directement avec la souris.


Additionnel) G pa fé, déso: Dans la catégorie de ce que nous n'avons finalement pas implémenté, nous avons le message d'erreur global (dash impossible, inventaire plein...) car il n'est pas encore indispensable, et son adaptation future n'est pas complètement claire dans mon esprit. Et ensuite, la partie bonus où on devait essayer d'instancier un rocher pour le miner et récolter ses ressources: je suis en train de peaufiner les détails des systèmes de récoltes et préfère inclure ce bloc (haha ! LOL ! CE BLOC ! LA PIERRE, MAIS QUEL HUMOUR EDJ rFEDUH<) dans le prochain segment de développement. 


Le commentaire du développeur sauvage à propos du segment de dev

Je ne m'en cachais pas, et je l'ai mentionné en débutant cette phase de code: implémenter mes premières interfaces utilisateur sous Godot me faisait un peu peur. Je n'ai aucune idée de la tronche des outils UI sous Unity ou sous Unreal Engine, mais sur Godot, la principale qualité avancée par l'éditeur à propos de son interface UI est l'adaptabilité, via son système de containers intelligents.

C'est un peu comme si on vous demandait d'éteindre un incendie dans le Gard en vous promettant que la peinture rouge de votre lance à eau est faite avec des ingrédients bio-responsables: c'est super chouette, mais ça ne répond clairement pas à vos angoisses principales.

AKA, gérer les clics de l'utilisateur. Sélectionner et glisser des éléments. Provoquer des réponses dans la logique des contenants. Il n'y a aucun preset, ni filet. Il faut coder chaque réaction. Finalement, en progressant lentement, j'ai fini par apprivoiser la bonne hiérarchisation des nœuds de contrôle pour faire une belle UI adaptative (yay !). Mais aussi à comprendre comment me servir des signaux de ces contenants, et du focus de la souris qui passe au-dessus, pour créer une interface fluide à manipuler.

Même en sachant que je débutais sur l'UI, je ne m'attendais pas à ce que cette partie soit si chronophage. Comme pour de nombreux autres systèmes présents dans les jeux vidéos, c'est en codant qu'on se rend compte de la quantité phénoménales de normes et de règles implicites qu'une simple interface de sac se doit de respecter, pour ne pas frustrer l'utilisateur.

Tout pouvoir fermer en cliquant ailleurs sur l'écran ("barre-toi la fenêtre bordayl, je suis attaqué §§"). En appuyant sur échap. Ouvrir automatiquement le sac en même temps qu'un coffre, mais permettre de garder le sac ouvert en fermant le coffre. Appuyer une fois sur échap pour fermer les panneaux d'UI, une seconde fois pour le menu principal du jeu. Illuminer les icônes interactifs, au bon moment, et les griser pour ne pas induire le joueur en erreur lorsqu'ils sont inactifs.

Le design de l'UI est un travail à double-tranchant: lorsque quelque chose ne réagit pas comme vous l'attendez, vous le voyez (ressentez, même) tout de suite. Mais une erreur, ou un choix d'ergonomie malavisé, peut rendre un panneau immédiatement pénible à utiliser.


Une interface bien pensée transforme la gestion de ses ressources en un plaisir. C'est vraiment un but important pour Lampyre, que ce que vous exploitiez autour de vous soit agréable à manipuler, transporter, ranger. Des automatisations vous permettront de mettre vos alliés à contribution, en leur demandant de gérer automatiquement des stocks, ou de ranger de façon ordonnées tout votre fatras acquis lors d'une journée d'expédition. Mais cette quête de satisfaction doit commencer dès la besace de base du joueur, dont le contenu est ici manipulable de simples clics.

Ce système d'inventaire est là pour durer. Il va supporter tout le reste de nos mécaniques de fabrication et de récolte, et j'en suis très contente. Si l'on pourra sans doute y apporter des améliorations au fur et à mesure, les commandes actuelles sont robustes. J'ai pour le coup très hâte de faire un saut dans le temps pour arriver au moment où l'on pourra lécher son design final (ce n'est pas sale) et en faire quelque chose de BEAU, en plus de fonctionnel.

Parce que pour l'instant, bon. Il fait exactement ce qu'on lui demande, ok. Mais il a pas pris la peine de se changer après s'être occupé du barbecue pendant trois heures sous le soleil, si vous voyez ce que je veux dire.

 

Je peux d'ailleurs aussi fièrement proclamer que, comme attendu, ce bloc de développement est le moins *visuellement* impressionnant de tout ce qu'on a pu faire jusqu'ici, bien que ce soit celui qui ai prit le plus de temps à compléter.

Aucune surprise, et je ne suis pas du tout démoralisée par cet état de fait. Ce qu'on vient de faire était délicat, et un inventaire qui fonctionne bien va devenir un pilier pour le reste du développement.


Le rythme de développement est très bon, il s'est même amélioré au fil du temps. Je n'ai pas fait le compte exact des heures passées mais nous sommes certainement à plus d'une heure de travail concentré quotidienne (souvent supérieur à l'heure et demi en réalité, hors week-end où le nombre d'heures est démultiplié). Lampyre est maintenant une habitude consolidée, et j'essaie de profiter d'autres créneaux de temps chaque jour pour développer mes idées, et les visuels !


La suite

Nous quittons un instant nos sacs et nos tas de bois (oui ce sont des bûches dans ma tête, laissez-moi rêver :'|), pour faire un usage maximal des objets que nous faisons désormais tomber au sol. Aucune déviation du programme: nous allons nous attaquer à la création des principales sources de matériaux de la carte, et de leur récolte.

Le but est d'initier la récupération de bois, de minerais, et d'autres biens naturels sur la carte. Et de pouvoir progressivement débloquer les fonctionnalités du bloc suivants: la construction.

Les fonctionnalités visées, pour ce bloc numéro cinq, sont donc...

*tousse tousse*

- l’initialisation de l'arbre technologique du jeu: quelles ressources existent, dans quelles variations, et avec quelles caractéristiques importantes pour la construction et l'artisanat.

- la création et la répartition rudimentaire des biomes sur la carte de jeu (je précise que cette fonctionnalité a techniquement déjà été codée début 2024 et mise de côté, mais je vais devoir la réviser et être sûre que ses systèmes s'intègrent bien à la structure actuelle de mon code).

- l'apparition des ilots de ressource sur la carte, selon les biomes, à sa création. Optionnel: programmation de leur renouvellement (repousse des arbres, ré-émergence des pierres). Il est probable que je réserve la gestion de la croissance des végétaux pour la future partie cultivation !

- la récolte complète de chacun de ces types de ressources, réalisée à mains nues, ou à l'aide de l'outil polyvalent et unique des vyrrlins de Lampyre, provisoirement nommée serrepic. Inclut toutes les étapes à effectuer par le vyrrlin pour en extraire les matériaux obtenables SANS station d'artisanat.

 

Cette liste semble courte, mais ne vous y trompez pas, les techniques de récolte vont être un minimum interactives et différentes pour chaque grand type de ressource (j'ai dit un minimum, il faut trouver l'équilibre entre simplicité et superflu ; il n'est pas question d'enchaîner cinq QTE à chaque fois qu'on souhaite désosser un buisson).

Cette partie a également la particularité d'être un peu plus riche que les précédentes en matériel théorique, puisqu'il faut éviter de se planter lourdement sur l'organisation des ressources à gérer dans le jeu. C'est toujours à la fois excitant, et un peu angoissant de poser les fondations de ce genre de systèmes. Je prépare mes meilleurs organigrammes d'artisanat.



Les visuels du schnaps

Et maintenant, le fourre-tout visuel de notre récapitulatif, j'ai nommé les GIF de développement (issus des clips que je poste régulièrement sur twitter) !

 

1) Les premiers objets tombés au sol, et les premiers ramassages ! À ce moment là, il n'y avait pas encore d'inventaire. Je demandais juste à chaque pièce ramassée de disparaître dans le néant. 

Notez la sélection automatique de l'objet le plus proche, ou bien de celui survolé avec la souris (pour peu qu'il soit également assez proche pour être ramassé, bien sûr). Ce système sera appliqué pour la majorité des actions contextuelles du jeu, afin d'avoir des inputs fluides et rapides.

Appuyer sur ALT met en évidence tous les objets en affichant leur nom et leur quantité, comme dans tout bon jeu où le loot peut être abondant et/ou caché au sol (les Diablo, Baldur's Gate 3, et j'en passe des dizaines d'autres).


2) Première tentative de faire automatiquement regarder le modèle du joueur VERS l'objet qu'il ramasse. Sauf que ce dernier est par terre, et que notre modèle de vyrrlin provisoire est une patate géante. Donc... HEADBANG.


3) Pour correctement tester la gestion des commandes de proximité, j'ai balancé tous les objets à proximité de la flamme de l'autel. Sans survol particulier de la souris, c'est toujours la commande qui concerne le bâtiment qui prime (ici, allumer sa torche). Mais on doit toujours pouvoir sélectionner du loot tombé devant, avec le curseur de la souris, pour ne pas qu'il reste inaccessible.

 

4) Essai de placement d'un objet lourd dans les bras du joueur. Peut-être que je me suis loupée sur la première implémentation de la rotation de la charge. 


5) On porte des objets lourds en pile ! Yay ! Il n'y avait encore aucune pénalité de vitesse de déplacement à ce stade, donc on pouvait tranquillement courir pleine vitesse avec 35 kg dans les bras.

On peut sans problème transporter plusieurs types d'objets lourds à la fois. Ils forment un pile organique sur la créature. Seul compte le poids total pour déterminer ce qu'elle peut soulever.


6) Application de la pénalité de vitesse de déplacement quand on est trop chargé, ainsi que du drain progressif d'énergie quand on porte +70% de sa capacité (barre cyan en haut à gauche). 

Notre capacité de charge lourde n'a aucun rapport avec le poids de notre inventaire (sac à dos). J'ai souhaité mettre ce drain d'énergie pour ajouter une dimension de risque à se surcharger: si vous ramenez des ressources au travers d'un coin sauvage de la carte, s'accrocher à votre butin devient risqué si on vous attaque (un manque d'énergie signifie automatiquement moins d'esquives ou de dash disponibles).

Notez la commande contextuelle "carry" en surbrillance rouge, sur le dernier objet. La couleur indique que soulever cet élément va vous faire dépasser votre capacité de charge totale, et que vous allez tout lâcher par terre si vous persistez à vouloir le porter.


 

7) Le sac à dos du joueur, qui se remplit d'objets ramassés au sol. Les icônes placeholder jaunes, représentent un type d'objet qui est empilable. Clic du milieu sur ces piles les scinde automatiquement en deux. J'aime beaucoup ces actions de gestion simples, par clic, grandement inspirées de V Rising (d'autres jeux fonctionnent similairement, je n'en doute absolument pas).


8) Diviser les piles par deux est pratique, mais parfois insuffisant. J'ai donc développé ce mini-panneau accessible avec clic du milieu + ALT. Il permet d'indiquer la taille exacte de la pile que l'on souhaite obtenir, soit en la tapant, soit en cliquant sur les signes d'augmentation/soustraction de valeur. World of Warcraft utilise ce système fort pratique depuis longtemps.



9) Lâcher les objets en les glissant en dehors de l'inventaire. Rapide, pratique, indispensable.

La simulation physique, et l'apparition à une position aléatoire autour du joueur renforce cette délicieuse petite impression de chaos. J'imagine déjà avec des vrais modèles d'objets texturés.



10) La destruction d'objets ! Comme mentionné précédemment, je trouvais important de pouvoir détruire des objets de façon permanente. Mais pour ajouter une petite touche de roleplay, j'ai décidé de rendre ça possible... par la flamme de l'autel.

L'inventaire du joueur a donc cette option représentée par un icône de flamme sur sa gauche. Elle devient active quand on est assez proche de l'autel. Y glisser des objets les détruit de façon permanente ; un petit encadré vous décrit l'action lorsque la souris survole l’icône de flamme.


11) Le bouton de tri automatique. Un autre indispensable. Il réorganise tout le contenu de l'inventaire pour agréger les objets similaires, et rassembler toutes les piles isolées qui peuvent l'être.


12) La petite fonction de recherche intégrée à l'inventaire ! Elle ne fonctionne pour le moment que pour son propre contenu, mais on pourrait bien l'imaginer fonctionner pour les deux inventaires ouverts en même temps à l'écran. 

J'ai hésité à implémenter cette fonction pour le prototype, mais je la trouvais fort utile, même à des fins de débug (chercher des objets spécifiques dans un sac bien rempli, à l'aide). Et elle aurait définitivement existé dans la version finale du jeu, dans tous les cas.


13) Les premiers coffres ! Étant eux-mêmes des inventaires, ils bénéficient de toutes les fonctions qui ont été précédemment codées. 

Avoir son inventaire, et un contenant ouvert à l'écran, débloque deux nouveaux boutons : le transfert rapide (je balance tout dans l'autre sac), et le transfert que j'appelle "de complétion". Déjà présent dans beaucoup d'autres jeux, il vous permet de rapidement bouger les objets qui sont déjà présents dans l'autre sac. E.g, un coffre contenant des pommes. J'appuie sur le bouton, et toutes les pommes de mon sac y sont transférées. Les autres objets ne bougent pas.

Il y a un autre type de transfert automatique que je souhaite implémenter dans le futur : le transfert par catégorie. Vous pourrez définir un coffre comme un contenant spécifique pour une ressource ou un genre d'objet ("bois", "fruits", "soie", "tissus") et ce boutons rangera automatiquement tous les éléments de votre inventaire qui rentrent dans les conditions indiquées.

Déplacer un objet d'un contenant à l'autre ne demande qu'un clic droit.


14) Les dernières fonctionnalités implémentées: jeter des charges lourdes dans le feu de l'autel pour les détruire, et les stocker sur une station adaptée. Par station, j’entends tout bâtiment qui acceptera ces objets pour les conserver en sécurité, ou les utiliser pour l'artisanat ou la consommation.



Merci à vous de suivre mes pérégrinations logicielles ! Le prototype monte en puissance et on continue directement notre lancée dans les mécaniques principales du jeu. Je commence également à me chauffer pour produire des concepts et key art visuels, un peu plus attrayants que mes patates non-texturées qui portent des cylindres. Mais quand le temps est limité, la programmation prime toujours.

Vous pouvez me suivre sur twitter (@Ariatowl) pour avoir des nouvelles régulières du développement.

Prenez-soin de vous, à la prochaine !