Le champ de vent

Une tornade ne pousse pas l'air au hasard. Ce qui souffle autour du joueur et ce qui arrache un bloc du sol viennent de la même formule, un vortex de Rankine modifié, qui porte ensuite chaque débris en vol. Le modèle ajoute ce qu'un manuel laisse de côté : un courant qui converge vers l'axe près du sol, un anneau ascendant au mur du cœur, une colonne descendante une fois la tornade assez violente pour se creuser, et la translation de tout le système, qui rend un flanc du passage bien pire que l'autre. Le cas particulier du sol, là où l'air n'a nulle part où aller sauf vers le haut, est traité à part en fin de page.

Une formule, pas une grille

Le champ ne s'appuie sur aucune grille précalculée : chaque tornade recalcule sa vitesse de vent à l'endroit exact où on la lui demande, que ce soit soixante fois par seconde pour un joueur ou une seule fois pour un bloc testé par la destruction. Au-delà de huit fois le rayon du cœur, la valeur rendue est exactement zéro, sans dégradé résiduel : pour la plus petite tornade, une EF0 au rayon de six blocs, le vent s'arrête net à quarante-huit blocs de l'axe. Cette coupure nette est ce qui permet d'additionner les champs de plusieurs tornades actives sans qu'aucune ne vienne souffler jusqu'à l'autre bout de la carte.

Deux fois la même équation

Pour un joueur debout dans l'herbe ou un bloc testé par la destruction, ces formules tournent en Java, sur le processeur, à chaque fois. Pour les débris, qui peuvent se compter par centaines autour d'une même tornade, la même équation existe une seconde fois, écrite comme un noyau OpenCL, préférée dès qu'une carte graphique est disponible. Passer useGpu à false revient sur le processeur pour de bon ; le remettre à true ne force rien d'autre qu'un nouvel essai, sans erreur ni redémarrage si aucune carte ne répond, et sans seuil minimal : même une poignée de débris tente la carte si elle est là. Le journal du serveur indique lequel des deux chemins a tourné, et la commande de diagnostic sépare les deux compteurs : tant de morceaux calculés sur la carte, le reste sur le processeur.

Sans carte compatible, ou la carte coupée par réglage, l'advection retombe sur le chemin processeur : un bassin de threads dont le nombre suit un réglage général du serveur, calé par défaut sur tous les cœurs sauf deux. Un serveur sans carte graphique ne perd donc rien à la justesse du résultat, seulement de la marge sur le nombre de débris qu'il peut porter à la fois, puisque c'est la même arithmétique des deux côtés, comparée noyau contre noyau pendant le développement plutôt que crue sur parole.

Les deux chemins sont construits pour rester d'accord au chiffre près plutôt que simplement proches : le noyau raffine lui-même sa division et sa racine carrée en double précision, parce que le pilote de certaines cartes ne les rend qu'à huit chiffres justes, de quoi faire diverger un vortex après quelques secondes de vol. Un joueur qui compare une tornade avec et sans carte graphique ne devrait rien voir de différent, à part le nombre de morceaux que le ciel arrive encore à porter à la fois.

Un rayon qui suit la force du vent

Le rayon du cœur, celui qui fixe l'échelle de tout le reste du champ, dépend de la force du vent plutôt que d'être choisi à la main pour chaque tornade : six blocs au plancher de l'échelle, puis un agrandissement gouverné par un exposant réglable, radiusGrowthExponent, à 1,5 par défaut. C'est ce même rayon qui fixe la largeur de l'entonnoir que le joueur voit se former au-dessus, détaillée du côté du rendu à l'écran.

Les déplacements verticaux

Le tirage en altitude : au-dessus du sol, le vent vertical dessine un anneau ascendant calé sur le mur du cœur, qui suit son propre calcul plutôt que le vent tangentiel dans une simple règle de trois. Une tornade faible n'est qu'un tube qui monte tout du long. Passé le seuil d'une EF2, une colonne descendante commence à se creuser au centre, et au seuil d'une EF4 elle a pris toute son ampleur : le cœur devient un anneau creux avec un puits d'air en son milieu, ce qui est aussi ce qui le fait éclater en vortex satellites plutôt que de rester un tube unique. En dessous du seuil d'EF2, cette colonne n'existe pas du tout. Le tirage vertical culmine, à la crête de l'anneau, à : six dixièmes du vent de pointe de la tornade, une proportion fixe, gravée dans le calcul plutôt que dans un fichier de configuration.

Le courant de coin : au ras du sol, l'air qui converge vers l'axe finit par heurter le mur du cœur sans plus aucune place devant lui, et n'a d'autre issue que de tourner vers le haut. C'est dans cette couche, épaisse d'une fraction seulement du rayon du cœur, que le vent vertical est le plus rapide de toute la tornade, bien avant le sommet de l'anneau ascendant. Un modèle qui ignorerait ce courant de coin laisserait un débris posé dans l'herbe pendant que l'entonnoir entier lui passe dessus sans jamais le soulever.

Le cas particulier du sol

Avant même de faire tourner quoi que ce soit, le champ tient compte d'une chose fixée pour tout l'orage : la hauteur du nuage de base, cloudBaseAltitude, cent quatre-vingt-trois blocs par défaut et réglable dans le fichier de configuration. Cette valeur est absolue, pas mesurée depuis le sol local : c'est la même altitude pour tout l'orage, terrain qui monte ou qui descend sous elle. Sans ce choix, une tornade posée sur une colline pousserait son mur nuageux à travers la couche que le ciel est déjà en train de dessiner au-dessus, l'un des rares défauts qu'aucun angle de caméra ne cache.

La hauteur normale de la colonne se mesure entre le sol et cette altitude de nuage, mais rien n'oblige une tornade à naître loin en dessous. Sur un sommet proche de cent quatre-vingts blocs, la marge restante peut descendre sous les quarante blocs qu'un entonnoir a besoin pour rester lisible : dans ce cas précis, la hauteur ne suit plus l'écart réel et retombe sur ce plancher, quitte à ce que le nuage de base et le sommet du tube se chevauchent légèrement plutôt que de dessiner une tornade tronquée à rien du tout.

Le vent qui pousse une entité et le vent qui arrache un bloc ne portent pas à la même distance. Une entité reste prise dans le champ jusqu'à huit fois le rayon du cœur, alors que la destruction s'arrête à deux fois et six dixièmes ce même rayon. Entre les deux, le sol peut trembler et pousser un joueur sans qu'un seul bloc autour de lui ne bouge : la portée de la casse reste volontairement la plus courte des deux, concentrée près du mur du cœur, là où le vent travaille vraiment.

Le balayage qui arrache les blocs n'explore pas tout le disque avant de recommencer : une fois que blockBudgetPerTick est épuisé pour ce tick, il s'arrête net et reprend au tick suivant exactement là où il en était, sans revenir en arrière ni perdre sa place. Sur une tornade jeune, dont le budget dépasse largement ce qu'un simple passage peut arracher, cela ne se remarque jamais ; sur une construction bien plus dense que la moyenne, la même zone peut demander plusieurs ticks de suite avant de céder complètement.

La poussée elle-même ne passe par aucun système vanilla de recul : la vitesse de la cible glisse vers celle du vent par un simple mélange plutôt que par une impulsion d'un coup. Les dégâts, eux, empruntent deux types propres au mod plutôt que d'en réutiliser un existant, vortexdread:wind et vortexdread:debris, chacun avec son propre message de mort. Un joueur en mode créatif ou spectateur reste hors de portée des deux, à toute vitesse de vent.

Ce calcul tourne à chaque tick, pour chaque tornade active, sur toute entité vivante comprise dans sa boîte d'influence. En dessous de huit mètres par seconde au point exact où se tient la cible, le vent n'est plus une force : c'est de la météo, et rien n'est appliqué du tout, ni vitesse ni dégâts. Cette limite basse évite qu'une brise résiduelle à la lisière du champ ne fasse trembler la caméra d'un joueur qui n'a même pas encore vu le nuage.

Une cible déjà prise dans le courant n'en sort pas dès que le vent faiblit un peu : c'est le franchissement d'un seuil de portage propre à chaque victime qui décide si la composante verticale du vent s'applique pour de vrai, ou si elle reste plafonnée à zéro, poussée seulement vers le bas ou de côté, jamais vers le haut. Ce que ce portage fait ensuite à la cible, dégâts compris, et ce qu'un débris inflige lui-même au passage, est le sujet de la page sur les débris. Un joueur en mode créatif reste la seule sortie sans condition, à toute vitesse.

Un effet secondaire tient à la façon dont le profil vertical est bâti par tranches de hauteur : le tirage est nul au ras du sol, s'installe sur les premiers pour cent de la colonne, puis s'assouplit encore légèrement en s'approchant du nuage. Un rez-de-chaussée et le sommet d'une tour bâtie sous la même tornade n'encaissent donc pas la même poussée verticale : ce sont les étages du milieu qui prennent le pire, pas le rez-de-chaussée ni la dernière dalle.

Réglages du champ de vent
RéglageEffetValeur par défaut
turbulenceAmplitude du bruit tourbillonnaire ajouté au champ propre, en fraction du vent local. À zéro, un champ parfaitement lisse, sans aucune strie sur le mur du cœur ; la valeur par défaut le fait déjà bouillonner.0,22
coreRadiusAtEf0Rayon du cœur d'une tornade au plancher de l'échelle, en blocs. Tout le reste du champ, du mur au rayon d'influence, se dimensionne à partir de cette seule valeur.6 blocs
radiusGrowthExponentVitesse à laquelle le cœur s'élargit quand le vent forcit. Une tornade plus violente est donc, en moyenne, une tornade à la fois plus rapide et plus large.1,5
travelSpeedVitesse de translation du système entier sur le terrain. S'additionne au vent tournant, ce qui rend un flanc du passage plus violent que l'autre.8 blocs/s
trackWanderAmplitude dont le cap de la tornade peut dériver d'un tick à l'autre. Une trajectoire réglée à zéro devient une ligne parfaitement droite, ce qui ne s'est jamais vu sur une vraie tornade.1,6 deg/s

Ces cinq réglages se retrouvent dans le fichier de configuration du serveur, aux côtés de ceux qui décident de la vie et de la forme de la tornade plutôt que de ses effets sur le monde, détaillés du côté de la configuration. Rien de tout cela n'est figé à la naissance de la tornade : chaque tick reconstruit le champ à partir de la valeur actuelle de turbulence ou de coreRadiusAtEf0, donc une tornade déjà en vol suit tout changement de ces valeurs dès qu'il prend effet, sans attendre qu'elle se dissipe et qu'une autre se forme.