21 juin 2024

Game dev #03: second bloc de lumière terminé !

 Salutations, voyageur ! 

Nous faisons des progrès ! J'ai l'enjaillement infini de vous annoncer que notre second bloc de développement de Lampyre, concernant les bases de la lumière et de la corruption, est achevé ! 


 
Ce meme est si vieux, et le ressortir me fait grave plaisir.

 

Comme pour le bloc précédent, nous avons finalement implémenté bien plus qu'attendu. Pour clarifier le billet de développement, je vais d'abord faire une liste compacte de nos nouvelles fonctionnalités, et je détaillerai un peu mieux chaque catégorie par la suite.

 

 Carte :

- le sol de la carte peut désormais être instancié avec une taille dynamique (hauteur et largeur, des dimensions éminemment complexes §§).

- l'autel central du joueur, sanctuaire et condition de victoire, est désormais instancié en plein milieu.

- le mesh de navigation, pour le pathfinding des créatures, se calcule correctement sur tous les modèles bloquant le passage à l'initialisation de carte (et plus tard, s'actualisera au placement de nouveaux bâtiments ou obstacles).

Cycle jour/nuit et temps :

- le temps passe, et nous avons maintenant un soleil et une lune qui traversent le ciel de façon dynamique.

- le soleil, dés qu'il atteint un certain angle, produit un score de lumière allant de 0 à 200, et est passé à toutes les créatures de la carte via un signal, pour leur indiquer que le soleil brille.

- la nuit, dont la durée est indépendante à celle de la journée, permet l'apparition de la luminosité de la lune. Comme pour notre vraie lune, la position et l'intensité de la lumière lunaire sont indépendantes à la progression de la nuit (phases lunaires).

Score de corruption :

- chaque créature possède un score de corruption allant de 0 (totalement pur) à 100 (totalement corrompu). S'il est trop haut, ce score entraîne des pénalités croissantes quand la créature est éclairée. À 100 de corruption, une lumière de 25 inflige des pénalités de vitesse de déplacement, de régénération d'énergie et de distance de dash. À 40, des pénalités sur ses scores d'attaque (dégâts, vitesse, portée). À 50, elle commence à subir des dégâts. À 65, elle reçoit des dégâts supplémentaires de toutes les sources et enfin, à 80, elle est forcée à fuir vers une zone couverte par les ombres pour se protéger. 

Tous ces effets sont augmentés avec le score de lumière reçu (soleil + lumières artificielles). Un score de corruption inférieur à 100 atténue la quantité de points de lumière reçus (et leurs pénalités).

- les vyrrlins passent au travers de plusieurs seuils de corruption et de pureté. À moins de 15 de corruption, il est considéré pur. Entre 15 et 35, voilé. Entre 35 et 65, teinté. Entre 65 et 85, sombre, et au delà de 85, il bascule en égaré (un vyrrlin ténébreux et incontrôlable). À la sortie de leur purification (< 85), les vyrrlins sombres parviennent à marcher au soleil sans prendre de dégâts, mais subissent toutes les autres pénalités en journée.

Pour le moment, la corruption n'est acquise qu'en allant dans une zone de linceul d'ombre. À terme, les combats avec les créatures ombreuses en infligeront aussi des petites quantités. Tout le principe du jeu est de sortir des vyrrlins de leur frénésie ombreuse, pour en faire des villageois, et alliés. Mais certains bonus apportés par la corruption pourront peut-être vous faire reconsidérer l'idée de totalement purifier tous vos semblables...

- pour refléter la corruption des vyrrlins, leur modèle change d'aspect et de couleur selon leur degré d'ombre.

- le score de corruption du joueur est affiché sur l'interface générale.

Linceul d'ombre :

- la map est maintenant entourée de quatre lisières d'ombre permanentes. Ce linceul bloque totalement le score de lumière du soleil, et empêche aussi les créatures corrompues d'être bloquées par des lumières.

- les autels de corruption étendront encore davantage ce linceul autour d'eux (les patchs d'ombre procéduraux sont déjà codés et fonctionnels). Tout le but du jeu sera de détruire ces autels, pour libérer la carte de leur influence.

- les créatures ombreuses fuyant le soleil sont capables de rejoindre automatiquement la zone d'ombre la plus proche. Une fois à l'intérieur, elles essaieront de ne pas en sortir. Si un ennemi hors de portée les attaque depuis l'extérieur du voile, elles se réfugieront au centre de la zone ombreuse.

- les créatures non corrompues éviteront tout linceul d'ombre, sauf si ordonnées du contraire. Elles sont capables de sortir d'une zone d'ombre par le point le plus proche.

Lumière :

- les lampes ont été implémentées. Fixes ou portées, elles augmentent le score de lumière reçue pour les créatures présentent dans leur rayon.

- de plus, et pour instaurer un blocage spatial plus fort, toutes les lampes ont un niveau (tier) de luminosité, allant de 0 (nul) à 3 (absolu). Le périmètre de lumière d'une lampe bloquera toute créature ombreuse n'ayant pas la résistance requise pour passer. Par exemple, les ombrelgins ont une résistance à la lumière de 0, et sont bloqués par toute lumière de tier 1 ou supérieur. 

- lorsqu'une créature se baigne dans l'influence de plusieurs lumières, c'est le score le plus haut qui est retenu (elles ne se cumulent pas).

- en combat, les vyrrlins essaieront de se battre dans le rayon de lumières proches et d'attirer les ennemis à l'intérieur.

- les lampes consomment passivement une ressource, pour l'instant non nommée (mais ce sera de l'enduit inflammable, de qualité différente selon le tier 1, 2 ou 3 de la lampe). Si la ressource s'éteint, la lampe n'émet plus de lumière et ne peux plus être rallumée.

- les vyrrlins peuvent porter une torche en main secondaire, qui une fois allumée, se comporte exactement comme une lumière fixe.

- les lampes ne peuvent pas être allumées par magie, elles doivent recevoir un feu à l'aide d'une torche. Elle-même allumée à l'aide une lampe existante. Il est par contre toujours possible d'éteindre sa torche, ou toute autre lampe fixe, en effectuant une courte action contextuelle.

- l'autel central du village arbore une lampe inextinguible de tier 2 (elle ne s'éteint que si l'autel est détruit, et cela est synonyme de game over).

Additionnel / technique :

 - changement du visuel provisoire des créatures (plus épuré et permet une meilleure visualisation de leur orientation dans l'espace).

- amélioration du visuel de réception de dégâts. La teinte rouge représente toujours une perte de points de vie, mais un effet violet indique maintenant des points de corruption reçus, ou à l'inverse, une teinte jaune pâle indique une baisse du score d'ombre.

- les vyrrlins ont maintenant un modèle placeholder de leur(s) arme(s) sur eux, et les dégainent à proximité des ennemis et lorsqu'ils se battent.

- le joueur a maintenant un menu contextuel lui indiquant les touches et les actions disponibles à proximité de certains objets (e.g. liste des ordres possibles à proximité d'un allié, allumer sa torche quand on en a une à proximité d'une flamme, etc)

- il y a aussi une liste dynamique des contrôles généraux affichée à l'écran, hors déplacement et contrôle caméra (marcher, sprinter, éteindre une torche portée, retenir ses attaques inventaire...)

- changement des visuels de barre de vie et d'interface générale pour un style plus minimaliste, tant que l'on reste en graphismes placeholders .


Et voici pour la liste factuelle des mises à jour. Ci-dessous, une explication plus poussée du design de la corruption. Vous pouvez aussi fuir vers la fin du billet pour directement voir la prochaine étape de développement !


La lumière et la corruption, pour un contrôle organique des comportements et de la gestion du village

Ok. J'avais écrit dans notre précédent billet que cette partie allait être cruciale pour Lampyre. Et elle l'est.

Toute l'essence du jeu se joue autour de cette opposition entre ombre, et lumière. En soumettant l'intégralité des créatures aux mêmes règles de corruption, cela permet des comportements automatiques, organiques, et une mécanique fixe qui relie l'ensemble.

Tout le piment de Lampyre, c'est l'individualité des vyrrlins au cours d'une campagne. Leur évolution au fil du temps, qu'elle soit physique, relationnelle, ou relative à leurs compétences. Leur apparence change au fur et à mesure de leur vieillissement, de leur corruption ou de leur purification. Cette dernière conditionne leur aspect, mais aussi les interactions et les activités qui leurs sont accessibles (pas toutes, heureusement).

Plus concrètement :

- un vyrrlin avec un score de corruption élevé ne peut pas discuter ou profiter d'activités sociales développées, ne peut pas développer de relation amoureuse, voir d'amitié (plutôt négatif)

- mais un vyrrlin avec un score de corruption élevé aura aussi des exigences plus basses sur son emploi du temps ou la qualité de son logis et de sa nourriture, et moins de réactions face aux évènements (bons comme mauvais)

- un vyrrlin ombreux dort moins, va un peu plus vite et se bat mieux avec ses griffes, mais peut subir des pénalités quand il évolue en plein soleil et peut sombrer plus vite dans la corruption

À l'inverse, purifier des vyrrlins est coûteux en ressource principale (je n'ai pas encore son nom, mais c'est un fruit à croissance limitée issu, entre autres, de l'autel principal). Les vyrrlins purifiés sont socialement vifs, élégants, capables de fabriquer des objets fins (armes/armures). Ils peuvent aussi être liés d'amitié voir même d'amour (avec le joueur, et entre eux !).

Le but est de peaufiner une mécanique où l'ombre, comme la lumière, peuvent avoir leurs avantages selon le style de jeu, et la situation dans laquelle se retrouve le joueur. Cela provoque une narration procédurale pour les villageois selon ce qui leur arrive, et peut amener le joueur à devoir faire des choix moraux pour optimiser sa partie... ou sauver sa waifu préférée.

J'adorerai retrouver ce feeling propre à Dwarf Fortress ou Rimworld, lorsque vous recrutez des individus d'abord inconnus, qui vous accompagnent jusqu'au bout de vos péripéties, en vous décevant, ou en vous surprenant.

 

En dehors des vyrrlins, il est important de mettre en place un comportement auto-organisé pour les ennemis ombreux. Le message, s'il n'est pas révolutionnaire, a au moins le mérite d'être clair: l'obscurité amène le danger. Les ombres sont cantonnées au linceul en journée, territoire ennemi, presque impénétrable sans lumière et préparation adéquate. La nuit, elles pourront errer sur la totalité de la carte. C'est là où la gestion des lampes entre en jeu, pour protéger passivement vos constructions de la majorité des attaques. 

Construire ses braseros autour de ses ouvrages, et les allumer avec son propre feu parait être un geste anodin, mais c'est vraiment un pan de gameplay qui DOIT être extrêmement satisfaisant. Les rayons des feux seront généreux, les ombres bloquées ou affaiblies, et le combustible simple à se procurer.

Bien sûr, une fois un villageois recruté, la tournée des feux au crépuscule pourra être une des toutes premières tâches automatisées (c'est un travail assez simple pour que même un vyrrlin proche de la corruption maximale puisse s'en occuper !).


La plupart des nuits seront calmes, avec un minimum de préparation nécessaire. Mais des assauts ennemis auront parfois lieu, annoncés par une brume de linceul envahissante et des ennemis qui convergent vers votre autel. Lors d'évènements aléatoires, ou en réponse à la destruction d'un autel (le petit jeu 2D Kingdom a cette mécanique de représailles !). Il faudra alors renforcer son périmètre lumineux, et appeler ses villageois au combat pour défendre ses bâtiments.


Bref. Ces bases de corruption, et le comportement d'évitement de la lumière des créatures ombreuses, sont là pour rester, et ne changeront que très peu. Les autres mécaniques du jeu s'appuieront intégralement sur ce qu'on a implémenté ! Quelques exemples de prévu :

- pour essayer de purifier un vyrrlin égaré, il faudra le maitriser, et le ramener au village. Mais en attendant sa purification, la journée, il devra être enchainé à l'ombre, sous le bâtiment dédié ou un autre ouvrage ! Sinon... il subira des dégâts du soleil, et mourra, sauf s'il peut s'enfuir jusqu'aux lisières d'ombre.

- les ombrelgins seront parfois accompagnés de leurs grandes sœurs, les chimères. Les chimères sont plus rares, mais aussi bien plus grosses et plus dangereuses. Elles ne sont pas bloquées par les lumières de niveau 1 et reçoivent un score de luminosité réduit (et donc, moins de pénalités passives). Elles peuvent également renforcer les ombrelgins aux alentours pour leur permettre d'ignorer les lumières simples !

- la flamme immuable de l'autel permet au joueur de toujours avoir une petite condition de victoire, même si les conditions sont dantesques. C'est aussi la source garantie d'une étincelle pour allumer les autres lampes (et un visuel satisfaisant ? Imaginez récupérer la flamme éternelle de l'autel de votre demi-dieu, chaque soir, pour protéger votre foyer avec sa lumière :o)


Et il est où le code du game dev journal, Micheline ?

Alors. Beaucoup de développeurs s'amusent à faire des démonstrations de leurs systèmes et de leurs scripts. C'est d'ailleurs super intéressant quand on code soit-même son jeu (et rarement pour copier-coller des scripts, comme on pourrait le penser, mais davantage pour voir l’ingéniosité dont font preuve les devs pour contourner les problèmes rencontrés).

Le problème, c'est que publier ce genre de contenu prend du temps. Dans le genre, vraiment, beaucoup de temps. Pour présenter cela correctement, de façon reproductible, et compréhensible. Quand j'ai commencé le journal de dev, je me suis dit que ce serait peut-être intéressant de publier des bouts de scripts par-ci par-là.

À mon grand plaisir, je passe en ce moment plusieurs heures par jour à développer Lampyre. Et chaque heure que je prends pour renflouer le blog, est une heure que je ne passe pas sur mon délicieux script (et le game design, et l'architecture, et dans un futur proche les concepts arts, l'UI, la présentation du gameplay...).

Les billets de conclusion de bloc de développement restent ! Ainsi que les GIF rigolos. Mais je ne dédierai aucun temps à la présentation de code pour le moment. Rien d'incroyablement ingénieux ou révolutionnaire n'a encore été programmé, je me garderai donc de les communiquer au grand jour.

Sur cette promesse de non-effort, voici une petite compilation des GIF de développement de ce bloc de lumière.

 

Une amélioration du dash des créatures, lorsqu'elles bondissent d'une zone d'AOE. Le mouvement était précédemment forcé sur l'algorithme de pathfinding ("poussée" dans une direction via la navigation). Il est maintenant basé sur la vélocité directe du rigidbody, et ainsi plus fluide.

 

La première implémentation des affaiblissements et dégâts infligés par le soleil aux créatures ombreuses. ELLES BRÛLENT (et sont moins rapides, moins dangereuses...).

 

L'éventail des différentes formes de vyrrlin, selon leur score d'ombre. En partant de la droite: pur (0 de corruption), voilé (20), teinté (50), sombre (70) et égaré (85), ainsi qu'un ombrelgin (100 de corruption permanente). On peut voir qu'avec le soleil levant, le vyrrlin égaré subit des dégâts (même si moindres que l'ombrelgin), et le vyrrlin sombre a une pénalité de vitesse de déplacement.

 

Un aperçu grand angle des bordures ombreuses et de deux zones de linceul irrégulières. La carte de debug tient sur un mouchoir de poche mais la zone de jeu finale sera évidemment bien, bien plus grande.

 

Le comportement de refuge des vyrrlins dans le linceul, lorsque le soleil est levé ! À la nuit tombée, lorsque le score est à zéro, ils peuvent à nouveau errer en dehors de ses limites.

 

Les ombres cherchent à se réfugier à l'intérieur du linceul si elles ne peuvent pas en sortir pour atteindre un ennemi. Cela limitera les possibilités de marouflage de la part du joueur. Notez mon score de corruption à 84, qui me ralentit en plein soleil (icône de debuff :( ).

 

Un allié qui sort précipitamment de la zone de linceul, par le point le plus proche. Il évite d'y retourner, sauf si on lui ordonne de nous suivre à l'intérieur. Notez aussi le petit effet violet sur les vyrrlins, indiquant un score de corruption qui monte !

 

Un ombrelgin bloqué par les rayons des braseros. Ce comportement est vraiment, très plaisant à coder. Je pense rendre les zones d'effet des lumières plus grandes pour les rendre plus satisfaisantes, et plus utiles !


Des alliés, qui reculent et utilisent des lumières proches pour se battre, au lieu de rester dans le noir ! Notez que celui qui se bat au corps à corps finit tout de même par s'approcher des ennemis pour les toucher. Le but reste de défaire ses adversaires.

 

Une démonstration des tiers de lampe en action. Les lampes classiques sont de tier1, et la bleue est en tier 2. Notre ombrelgin a ici reçu un buff, qui lui permet d'ignorer la lumière de niveau 1... mais pas celle de niveau 2.

 

Les premiers essais d'instanciation de torche sur le joueur. J'ai peut-être oublié de limiter la quantité de modèles créés.

 

L'extinction des lampes, lorsque leur réserve de combustible s'épuise et s'approche de zéro. Notez que la surface ET la quantité de lumière émise sont diminués (ici en version accélérée).

 

Le même effet avec une torche portée ! TABASSAGE DANS LA NUIT.

 

La démonstration du menu contextuel de commande tout neuf, et de l'allumage des feux (avec d'autres feux, zOMG) ! On se permet même d'éteindre sa torche en restant appuyé sur une touche. Wow.


Et la bataille FINAAAAALE du bloc de développement, pour mettre à l'épreuve le process time de notre jeu et ses mécaniques actuelles. ON A NOTRE RETRAITE DES OMBRES VERS LE LINCEUL AU SOLEIL LEVANT ! FUYEEEEEZ PAUVRES FOUUUS !



 La suite des festivités: le bloc de développement numéro 3

 Alors, quelle est la roadmap mise à jour ? Une partie de moi avait très envie d'implémenter le système de purification. Mais celui-ci va nous demander des bâtiments et des ressources. La prochaine étape est donc...

... LE LOOT ET L'INVENTAIRE !

Nous allons délaisser un moment la violence des combats et les ombres, pour coder les fonctionnalités suivantes:

- implémentation des objets tombés au sol dans le monde, avec ou sans physics.

- programmation des classes d'objets Item (qui existe déjà, et dont les armes sont héritées) et Inventory. Un inventaire sera ici tout système recevant et conservant des objets dans le jeu. L'inventaire des vyrrlins, les contenants, les stations d'artisanat...

- les inventaires doivent pouvoir être rapidement paramétrables avec entre autres un nombre d'emplacement et un poids limite.

- ils doivent aussi pouvoir afficher leur contenu de façon flexible dans une interface commune, permettre de déplacer ou de diviser les objets.

- les objets devraient pouvoir afficher leur nom, leur description et leurs informations dans une info-bulle d'inventaire.

- les objets tombés au sol seront soit en surbrillance permanente, soit mis en évidence grâce à une touche du clavier dédiée (pensez à la touche d'affichage des noms d'objets au sol, de Baldur's Gate 3 ou de Diablo).

- les objets seront divisés en deux catégories: ceux qui sont transportables dans un inventaire, et ceux plus gros, qui devront être portés. Les armes, les grosses bûches, ou les armures, ne pourront pas être empilées et transportés par magie dans un sac à dos invisible. Ce type d'objet devra être porté dans les bras. Mais ne vous inquiétez pas, le but n'est pas de rendre le système frustrant ; au contraire.

- les objets transportés doivent pouvoir être ramassés, cumulés dans les bras selon leur type et leur poids, et lâchés au sol ou sur une station possédant des réceptacles adéquats (un râtelier d'arme par exemple). Ils bloquent toute attaque ou action tant qu'ils occupent les mains du porteur. Le système n'est pas exclusif aux vyrrlins, je veux que toute créature puisse porter des objets lourds sur elle.

- le joueur doit pouvoir ouvrir son inventaire, manipuler les objets à l'intérieur, les lâcher au sol, trier automatiquement son inventaire pour cumuler les piles qui peuvent l'être ou ordonner ses objets par type ou ordre alphabétique.

- il doit aussi pouvoir transférer des objets d'un contant à son inventaire, et vice-versa (et on devrait pouvoir le faire programmatiquement entre n'importe quelle paire de contenants, pour être honnête).

- un message doit apparaître à l'écran pour informer le joueur que son personnage, ou toute autre entité ne peux pas réaliser une action (ramasser un objet avec l'inventaire plein, esquiver alors que l'on a plus d'énergie...)

Et en bonus, nous instancierons au final notre tout premier rocher, que nous minerons pour faire tomber des objets ! Ce sera le début de notre phase de récolte (omg je spoile tout).


Merci à vous de suivre ces péripéties insensées. Je vous donne rendez-vous sur Twitter (@Ariatowl) pour suivre de plus près le progrès de ce bloc #3 de développement, j'ai nommé, LE LOOT. Et je vous dis à la prochaine sur ce blog.

Prenez-soin de vous !

Aucun commentaire: