promotional bannermobile promotional banner

Evolution: You Become What You Do

You become what you do - a behavioural RPG for Minecraft.
Back to Files

evolution-1.1.1.jar

File nameevolution-1.1.1.jar
Uploaded
Aug 4, 2026
Downloads
12
Size
4.7 MB
Mod Loaders
NeoForge
File ID
8575920
Type
R
Release
Supported game versions
  • 1.21.1

Curse Maven Snippet

NeoForge

implementation "curse.maven:evolution-you-become-what-you-do-1635902:8575920"

Learn more about Curse Maven

What's new

Journal des versions

1.1.0

Multijoueur : un défaut du mod ne peut plus déconnecter personne

Symptôme rapporté : un second joueur se connecte, le chat affiche « a rejoint la partie », le joueur ne peut pas bouger, puis « a quitté la partie ». L'hôte, lui, joue sans rien remarquer.

Le mécanisme est structurel. PlayerLoggedInEvent est émis à la fin de PlayerList.placeNewPlayer, après le message d'arrivée ; l'appelant entoure le tout d'un try/catch qui journalise « Couldn't place player in world » et coupe la connexion. Tout le travail de connexion du mod s'exécutait là. N'importe quelle exception — la sienne ou celle d'un mod voisin — suffisait donc à laisser le joueur sans chunks ni position, figé jusqu'à l'expiration du délai.

  • Le travail de connexion est différé au premier tick. Les trois handlers de cycle de vie ne posent plus qu'un drapeau. Le mod ne peut plus empêcher une connexion, et il travaille désormais sur un joueur réellement posé dans le monde — jusqu'ici le chunk n'était pas chargé, si bien que tout ce qui interrogeait le décor (visibilité du ciel, lumière, blocs alentour) répondait faux au moment de la connexion.
  • Le tick du joueur passe par une barrière. Une exception y remontait jusqu'au tick du monde et arrêtait le serveur pour tous les joueurs, à cause d'un seul. La première occurrence est journalisée avec sa pile, les suivantes au plus une fois par demi-minute.
  • Doublon supprimé sur la réapparition et le changement de dimension. Deux handlers coupaient les bascules sur les mêmes événements, sans ordre garanti : le premier à passer rendait le second sans effet, et le message d'interruption n'apparaissait donc qu'une fois sur deux. Il est maintenant transporté par la demande de mise en place et affiché quand le joueur est arrivé, au lieu d'être joué pendant le transfert.

Multijoueur : quatre défauts invisibles en solo

Tous partagent le même profil — l'hôte d'une partie locale ne peut pas les voir, parce qu'il n'y a chez lui qu'un seul processus, un seul fichier de configuration et une connexion mémoire qui n'encode rien.

  • Marques des mobs. La valeur par défaut de l'attachement est une instance unique partagée par tous les mobs du monde, et ses deux ensembles étaient modifiables. Aucun code ne les modifiait, mais la signature l'autorisait sans avertissement : un seul ajout aurait basculé tous les monstres du serveur d'un coup, sauvegarde comprise. Le record est désormais réellement immuable. Au passage, un mob ordinaire n'écrit plus une balise vide dans sa sauvegarde.
  • Autel. L'aperçu de transfert se recalculait aussi côté client, écrasant les valeurs envoyées par le serveur avec un calcul fondé sur une progression vide. Un joueur ayant investi dans ARCANE voyait la perte maximale et le bouton grisé à tort. Le calcul est redevenu ce qu'il aurait toujours dû être : une affaire de serveur.
  • Boutons de rangement. Le réglage n'était vérifié qu'à l'affichage. La configuration du mod est de type COMMON, donc jamais transmise : un serveur qui désactivait le rangement voyait les demandes arriver quand même. Le serveur les refuse maintenant.
  • Besace. Le repli du menu client, en cas de tampon absent, ouvrait cinq rangées face à un serveur qui pouvait n'en avoir ouvert qu'une — de quoi déconnecter le joueur au premier clic. Branche inatteignable aujourd'hui, corrigée pour ne pas devenir un piège.

Verrouillé par checkLifecycle, quatrième vérification du build, doublée en Python avec ses deux cas de régression (dix-neuf au total). Trois GameTests s'ajoutent, dont un qui fait passer un joueur neuf par le vrai placeNewPlayer : la suite existante l'aurait déjà signalé si elle avait été lancée.

Textures : la cohérence avec le jeu de base, par construction

Les 113 textures sont refaites. Les anciennes juraient à côté du reste du jeu pour une raison mesurable : cinq tons plats et un contour uniforme, là où le jeu en utilise sept à onze, éclairés depuis le coin supérieur gauche. L'épée comptait 40 pixels remplis contre 84 pour celle du jeu, la pioche 27 contre 68.

  • Les silhouettes sont désormais celles du jeu de base, reteintées par palier. C'est exactement ce que fait le jeu entre le fer, l'or et le diamant : le même dessin sous trois palettes. En reprenant le procédé, la cohérence est acquise par construction plutôt que visée à l'œil.
  • Le bois reste du bois. Manche d'outil, corde d'arc et gangue de pierre gardent les couleurs exactes du jeu. Seul l'arc fait exception : ses branches sont le matériau, elles suivent donc la teinte du palier.
  • Chaque sprite tourne autour de sa propre teinte. Sans cela, le grimoire — un livre brun — virait au rouge en vert, au jaune en bleu, au vert en violet.
  • La clarté passe par une puissance, pas par un facteur, sinon les paliers clairs perdaient tout relief en débordant au-delà du blanc.
  • Baguette, focus, lampe, autel, fiole et particule n'ont pas d'équivalent dans le jeu : ils sont construits, la forme donnant la normale et la normale le ton, sous le même éclairage que le reste.
  • Les couches d'armure reprennent le dépliage UV du jeu — la question du joueur emmuré dans un bloc de couleur ne se pose plus.

Contrôle ajouté : check_roundtrip.py rend chaque source sous un palier construit sur les valeurs du diamant lui-même et exige la texture d'origine au pixel près. Décomposer puis recomposer 75 couleurs perd de l'information sans prévenir, et le défaut se serait propagé partout sans être vu.

Jauge de mana : plus de recouvrement

  • Elle était posée à guiHeight() - 30, c'est-à-dire exactement sur la barre d'expérience (lignes −29 à −24), et son cadre mordait le bas des cœurs et de la nourriture. Une seule cause pour les deux : une ordonnée choisie à l'œil au lieu d'être dérivée de la disposition du jeu.
  • Elle se place maintenant au-dessus de la colonne d'état, à une hauteur calculée comme celle de Gui.renderHearts — indispensable ici, puisque le mod pousse la vie jusqu'à trois ou quatre rangées de cœurs et qu'une position fixe finirait forcément par passer dessous. L'armure est prise en compte.
  • Le chiffre passe au-dessus de la barre plutôt qu'à sa droite, où il tombait au niveau des bulles d'air.

Multijoueur : vérifié plutôt que supposé

  • Séparation client/serveur rendue exécutable. gradlew build échoue désormais si une classe commune importe net.minecraft.client ou touche une classe de client/ hors d'un test de dist. C'était la règle 3 du projet, et elle n'avait jamais été vérifiée : le solo ne la révèle jamais, seul un serveur dédié plante. Les 120 classes communes passent.
  • Trois tests : deux joueurs ne partagent aucun état, dans les deux sens ; les index venus du client sont bornés sur les quatre points d'entrée qui en reçoivent un ; les mutations, rangs de prestige et ascensions traversent la synchronisation réseau.
  • Les bornes étaient déjà en place dans le code — le test les verrouille.

Performances

  • /evolution perf mesure les phases du mod sur la machine du joueur : moyenne, pire cas, et part d'un tick de 50 ms. Désactivé par défaut, où chaque point de mesure se réduit à une lecture de booléen.
  • Analyse statique du coût : environ 1 400 opérations par joueur et par seconde, plus un balayage de 1 331 blocs toutes les six secondes pour qui porte la vision des veines. Rien de chaud, mais l'estimation ne convaincra personne — d'où la mesure.
  • Une optimisation concrète : les avancements étaient relus deux fois par seconde et par joueur pour, presque toujours, ne rien accorder. Ils ne sont plus relus qu'au changement, avec un rattrapage toutes les dix secondes qui préserve la propriété utile — une partie déjà avancée finit par recevoir ses avancements.
  • revealOres plafonné à 48 minerais : un rayon de dix blocs représente neuf mille positions, et une veine dense y produisait des centaines de paquets.

Le monde réagit à ce que vous êtes

  • Huit présages, un par catégorie de statistiques : la pierre qui se souvient d'un mineur, la traque nocturne d'un combattant, la route qui s'ouvre, la marée arcanique, le second souffle, la vue lointaine, l'acclimatation, l'afflux de force.
  • Le présage attendu est essayé d'abord, mais le monde ne reste pas muet si les conditions du moment ne s'y prêtent pas : un autre est tenté.
  • Aucun ne modifie le monde durablement. Tous passent par des systèmes existants — effets, particules, mobs adaptés. Un évènement rare qui casse un décor est un évènement qu'on regrette, et rien ne permet de le défaire.
  • Rien avant le niveau global 12 : des présages sur un débutant seraient du bruit.

Prestige et ascension

  • Une statistique au plafond ne rapportait plus rien. Passé cent, chaque action continuait à être comptée et jetée, sans que rien ne le dise. Le prestige rend un usage à ce moment : la statistique repart de zéro et son plafond monte de dix. Cinq rangs, et le plafond vaut 150 — la statistique finit plus forte qu'elle ne l'a jamais été.
  • Chaque rang accélère l'expérience de toutes les statistiques. Ne l'appliquer qu'à celle remise à zéro aurait fait du prestige un ralentissement net, que personne n'aurait choisi.
  • L'ascension efface la vie en cours — statistiques, traits, évolutions — et ne garde que ce qui la dépasse : mutations, rangs de prestige, biomes connus, et deux cœurs permanents par ascension. Elle demande cinq rangs et une évolution légendaire : l'un mesure la durée, l'autre l'aboutissement.
  • Les deux sont volontaires et ne se déclenchent jamais seules. L'ascension demande confirmation en deux temps et annonce exactement ce qui sera perdu.
  • Le plafond est lu en un seul endroit (maxLevel), donc le bonus de prestige s'applique partout — progression, effets, conditions d'évolution — sans autre changement.
  • Deux tests verrouillent les invariants : le plafond monte réellement après un rang, et une ascension conserve exactement ce qu'elle annonce.

Mutations

  • Douze mutations obtenues par hasard et non par mérite : cinq bienfaits, six à double tranchant, une affliction. C'est le seul élément du mod qui ne se gagne pas — deux parties menées de la même façon ne donneront plus le même personnage.
  • Le tirage est adossé au changement d'évolution, pas à un minuteur : c'est le seul moment où le corps du personnage change vraiment, et cela borne le nombre de tirages à la longueur de l'arbre plutôt qu'aux heures jouées.
  • Une mutation est définitive. Une altération qu'on peut retirer devient un équipement qu'on optimise ; celle-ci se subit.
  • Les mutations à double tranchant sont les plus courantes : un hasard qui n'apporte que du bon n'est pas du hasard, c'est une récompense déguisée.
  • Notification en violet trouble, distincte du vert d'un trait et de l'or d'une évolution — une mutation n'est pas forcément une bonne nouvelle.

Codex

  • Cinquième onglet dans l'écran RPG (touche K), avec recherche : traits, évolutions, capacités, synergies et mutations, chacun avec sa description et ses conditions chiffrées face au niveau atteint.
  • Les évolutions secrètes non obtenues n'y figurent pas : les révéler retirerait tout leur intérêt aux dix évolutions dont le sel est de ne pas être annoncées.

Arbre d'évolution

  • Les paliers 4 à 6 étaient invisibles. L'onglet s'arrêtait au troisième : quarante-cinq évolutions, dont toutes les légendaires, n'apparaissaient nulle part. Les sept paliers défilent maintenant horizontalement.
  • Les hybrides sont enfin lisibles : signalés par un marqueur, leurs deux parents listés dans l'infobulle, et les liens de filiation tracés au survol. L'écran testait parent() — le premier parent seulement — ce qui ne disait qu'une moitié de la condition.
  • Une évolution fermée par un choix antérieur est barrée et le dit : le joueur ne peut plus attendre indéfiniment une voie hors d'atteinte.

Sons et particule propres

  • Huit sons synthétisés remplacent les emprunts au jeu de base : palier de statistique, trait, évolution, synergie, sort, mana épuisé, autel, Nemesis. Une évolution ne sonne plus comme un totem d'immortalité.
  • Le son du palier monte en hauteur avec le niveau : la progression s'entend sans qu'aucun texte ne l'annonce.
  • L'évolution ne joue plus qu'un seul son. L'empilement de trois sons vanilla couvrait l'évènement au lieu de le marquer.
  • Une particule au mod, evolution:mote — une poussière lente qui s'élève et s'efface. Elle porte désormais les effets ; les particules vanilla ne font plus que les accompagner.
  • Générateur versionné dans tools_sounds/. Les huit fichiers pèsent 59 ko.
  • Trois règles de vérification ajoutées : fichier son manquant, fichier son orphelin, particule sans texture. Le test de régression passe à quinze cas.

La faim redevient une contrainte

  • Le joueur n'avait plus jamais faim. La statistique FAIM et trois traits regarnissaient le rassasiement en continu. Or Minecraft entame le rassasiement avant la barre de nourriture : le remplir, même de 0,25 par seconde, ne ralentit pas la faim, il la supprime. Trois effets modestes s'additionnaient en une invulnérabilité complète.
  • La statistique agit désormais sur l'épuisement, pas sur le rassasiement — elle ralentit sans jamais arrêter. Facteur 1 / (1 + niveau × 0,01) : exactement la faim vanilla à niveau 0, moitié moins vite à 100.
  • Les traits métabolisme efficace, nomade et résistant à la faim s'appliquent de la même façon, en multipliant ce facteur.
  • Un plancher rend l'invariant structurel : la borne inférieure du réglage est strictement positive, aucune combinaison de statistique, de traits ou de configuration ne peut donc annuler la faim.
  • Vider la barre en sprintant : 2 min 30 sans progression, 6 min 30 au maximum avec tous les traits.
  • Un test automatisé verrouille l'invariant.

Profils de réglage

  • /evolution preset gentle | balanced | demanding fixe d'un coup les quinze options qui décident du ressenti : rythme, vie de départ, décroissance, anti-farm, élites, Nemesis, butin, sac magique.
  • Niveau 50 sur une statistique visée : environ 1 h en doux, 2 h en équilibré, 3 h 30 en exigeant.
  • Le profil écrit dans le fichier de configuration au lieu de s'appliquer par-dessus. Une couche invisible qui l'emporte silencieusement sur ce que le joueur a saisi est une source d'incompréhension garantie ; ici, le résultat se lit dans le fichier et reste modifiable option par option.
  • Vérifié par simulation : les trois profils décalent le rythme sans rouvrir l'écart entre statistiques, qui reste à 1,15× dans les trois cas.

Avancements

  • Vingt-quatre avancements, un arbre complet : progression des statistiques, traits, évolutions jusqu'aux légendaires et secrètes, mana, sac magique, les cinq Magirite, la panoplie complète, l'autel, le Nemesis.
  • L'attribution est déduite de l'état du joueur à chaque évaluation, jamais déclenchée par un évènement. Conséquence utile : une partie déjà avancée reçoit ses avancements dès la prochaine évaluation, sans avoir à refaire quoi que ce soit.
  • Cinq d'entre eux — ceux qui portent sur un objet possédé — utilisent le déclencheur d'inventaire du jeu et ne coûtent pas une ligne de Java.
  • Générés depuis une déclaration unique (tools_advancements/), et leurs liens, icônes et traductions vérifiés au build.

Vérification des ressources au build

  • gradlew build échoue désormais si une ressource est incohérente : recette au motif invalide, modèle sans texture, bloc sans objet ou sans table de butin, couche d'armure sans transparence, chaîne de génération rompue, traduction manquante.
  • Écrite en Groovy, sans dépendance au-delà du JDK.
  • Les règles sont éprouvées : tools_checks/ réintroduit dix bugs réellement vécus et exige que chacun soit détecté. Les quatre premiers sont ceux qui ont coûté le plus cher — les vingt armures introuvables, l'armure opaque, les modificateurs de biome muets, le plantage en créatif.

La Magirite n'apparaissait dans aucun monde

  • Les modificateurs de biome étaient dans le mauvais dossier. Ils vivaient dans data/neoforge/biome_modifier/ au lieu de data/evolution/neoforge/biome_modifier/ : le segment neoforge vient du namespace du registre et s'ajoute après celui du mod. Le jeu ne lisait donc jamais ces fichiers, et aucun minerai n'était injecté dans le monde. Aucune erreur au chargement — d'où la difficulté à le repérer.
  • Tout le reste de la chaîne était correct : blocs, modèles, blockstates, textures, features et remplacements de pierre par dimension.
  • Nouvelle commande /evolution ore : compte les minerais de Magirite dans un rayon de trois chunks et distingue les trois causes possibles d'une absence — chunk déjà généré, mauvaise dimension, chaîne cassée.

Interface de l'autel

  • Une étiquette au-dessus de chaque emplacementDétruit, Renforcé, Magirite — et une flèche entre les deux outils. L'opération est irréversible et asymétrique : rien n'indiquait lequel des deux disparaissait.
  • Panneau agrandi de 166 à 190 px pour loger la ligne de texte sans serrer le reste ; l'aperçu du transfert ne chevauche plus le libellé « Inventaire ».

Textures

  • Les 112 textures redessinées à partir de gabarits partagés, un par objet, déclinés sur les cinq paliers. Silhouettes conformes aux proportions du jeu de base, trois tons plus un contour, plus aucun sprite à 21 pixels sur 256.
  • Couches d'armure portée reconstruites. Elles remplissaient les 64×32 pixels sans une seule zone transparente : l'armure enfermait le joueur dans un bloc de couleur, visage compris. Elles suivent désormais le dépliage du modèle, avec l'ouverture du visage et les bottes au bas des jambes.
  • Arc tracé en diagonale, comme celui du jeu de base : le modèle item/bow applique des rotations calées sur cette orientation, et un arc vertical apparaissait de travers dans la main.
  • Générateur versionné dans tools_textures/, avec sa documentation.

Équilibrage de la progression

  • Anti-farm : décroissance exponentielle de la saturation. L'ancienne décroissance linéaire n'avait que deux états stables — une action toutes les 1,74 s rapportait huit fois moins qu'une action toutes les 1,76 s. Cette marche expliquait l'essentiel des écarts entre statistiques.
  • Corrections de rythme recalculées pour les 38 statistiques, à partir d'une simulation d'une heure de jeu par activité plutôt qu'à l'estime. Une statistique visée atteint le niveau 50 en 2 h environ, contre 6 min à 1 h 50 auparavant selon laquelle. L'écart entre la plus rapide et la plus lente passe de 18× à 1,1×.
  • xpScale passe de 90 à 35 : la table de correction est recentrée sur 1, le rythme d'ensemble se règle donc d'un seul curseur.

Affichage

  • Écran de réglages en jeu, touche O : ATH, gains d'expérience, opacité et taille, avec un aperçu en direct.
  • Réglages d'affichage déplacés dans une configuration client. Ils étaient dans la configuration commune, que le serveur possède : en multijoueur un joueur ne pouvait pas régler son propre affichage.
  • Opacité de l'incrustation d'expérience portée à 50 %.

Corrections avant publication

  • Plantage à l'ouverture de l'inventaire créatif. L'autel de renforcement n'avait pas d'objet associé à son bloc : l'onglet créatif tentait d'afficher une pile vide, ce que NeoForge refuse. L'autel était par ailleurs incraftable, sa recette désignant un objet inexistant.
  • Les vingt pièces d'armure Magirite étaient introuvables. Leurs recettes déclaraient un symbole S absent du motif ; Minecraft rejette ce cas et les vingt recettes étaient silencieusement écartées au chargement.

1.0.0 — première publication

Progression comportementale

  • 38 statistiques qui montent en jouant, chacune reliée au jeu par un effet direct
  • 44 traits passifs débloqués par seuils
  • Plus de 100 évolutions sur six étages, dont 15 hybrides, 10 légendaires et 10 secrètes
  • Arbre chargé depuis des fichiers de données : un pack peut en ajouter sans recompiler
  • Évolutions mutuellement exclusives — s'engager dans une voie en ferme une autre
  • Anti-farm : les actions répétées au même endroit rapportent moins

Mana et capacités

  • Réserve de mana sous la barre de vie, avec régénération liée aux statistiques
  • 24 capacités actives, passives et à bascule, assignables à six touches
  • Les capacités montent en niveau à l'usage
  • Vol, Méditation, Glouton, Boule de feu, Distorsion temporelle, Recul de masse

Magirite

  • 5 minerais magiques répartis sur les trois dimensions
  • Équipement complet par palier : armure, épée, arc, quatre outils
  • Baguette et grimoire, alimentés au mana seul
  • Focus de mana, lampes et blocs décoratifs
  • Autel de renforcement : transfère les niveaux d'un équipement à un autre

Le monde réagit

  • Mobs adaptés au style de combat du joueur, entre 1 et 5 % seulement
  • Élites porteuses d'affixes cumulables, mieux récompensées
  • Nemesis personnel qui apprend, évolue et revient

Confort

  • Sac magique déblocable, jusqu'à 45 emplacements
  • Boutons de tri et de transfert dans l'inventaire et les coffres
  • Équipement incassable qui gagne des niveaux
  • Abattage d'arbre complet
  • Interface à onglets, HUD, notifications

Technique

  • Français et anglais complets, 685 clés
  • 89 options de configuration
  • Compatible multijoueur, progression par joueur
  • Suite de tests automatisés (gradlew runGameTestServer)

This mod has no additional files