Sku v43.7 - notes de version

Aperçu

Changements

Corrections

Rotation : plus rapide, plus précise, auto-étalonnée

Simple : « Se tourner vers la balise » (T) et les deux autres commandes de rotation ont été retravaillées à partir de mesures en jeu. Trois choses changent nettement. D'abord : les grandes rotations arrivent en un appui. Jusqu'ici un appui faisait au mieux environ 88 degrés, quelle que soit la distance à parcourir - un bogue passé inaperçu depuis la v43.2. Ensuite : la rotation est plus rapide, un demi-tour ne prend plus qu'un bon dixième de seconde. Enfin : si vous êtes déjà aligné à 3 degrés près, un nouvel appui ne fait plus rien. Avant, chaque appui tournait d'au moins 5 degrés, on oscillait donc autour du ping de la balise sans jamais se stabiliser. Dans l'eau, cela évite aussi des à-coups de plongée inutiles.

Sku apprend votre machine au passage : après chaque rotation, il mesure de combien le personnage a réellement tourné et calcule la suivante d'après cela. À fréquence d'images élevée, Sku tourne plus vite de lui-même ; à fréquence basse, plus lentement mais précisément. Après la mise à jour, les premières rotations sont des étapes d'apprentissage et peuvent manquer la cible. Les très grandes rotations proches de 180 degrés arrivent à environ 5 degrés près ; de temps en temps un second appui affine. Un appui pendant une rotation en cours est ignoré comme avant.

Technique : GameWorldObjects:TurnToWorldPosition (SkuCore/gameWorldObjects.lua). Mesuré le 2026-09-21 : cameraYawMoveSpeed n'a plus d'effet au-delà de 360 - des valeurs plus hautes ne tournent pas plus vite (376, 453 et 731 ont tous donné ~88 degrés en 0,25 s). La règle max(360, angle/0,25) de la v43.2 plafonnait donc en silence chaque appui à ~88 degrés. La vitesse supplémentaire ne vient que de l'argument de

MoveViewLeftStart/MoveViewRightStart, qui multiplie la CVar (technique de WowVision).

Deux rapports : rapport 1 = CVar seule jusqu'à 360 deg/s, rapport 2 = CVar 360 fois un facteur jusqu'à 1440 deg/s. Modèle par rapport : tourné = k * vitesse voulue * (durée du minuteur + L) ; k par la médiane dès la première mesure, puis à partir de 8 mesures aux durées variées une droite d'ajustement pour k et L. Vitesse selon la fréquence d'images :

la dispersion de l'arrêt vaut une demi-trame fois la vitesse, on autorise 3 degrés ou 6 pour cent de l'angle ; jamais plus lent qu'angle/0,25 s ; ralenti quand le minuteur serait plus court que 2 trames. Si le facteur ne multiplie pas sur un client, Sku abandonne définitivement le rapport 2. Mesures par compte dans SkuOptions.db.global.SkuCore.turnCal. Le verrou contre les appuis suivants couvre désormais aussi l'attente de mesure (un appui dans cet intervalle calculait avec l'ancienne orientation). Chaque rotation écrit une ligne « TurnCal » dans le journal de débogage. /skuturn affiche l'état, /skuturn reset efface les mesures, /skuturn legacy revient à l'ancien comportement. Construit, testé puis retiré : une correction dans le même appui - la caméra a de l'élan et continue de glisser après l'arrêt, une commande dans ce glissement coûtait jusqu'à 35 degrés.

Nage et vol : le verrou d'inclinaison s'active aussi en combat

Simple : Le verrou d'inclinaison automatique, qui vous maintient à l'horizontale en nageant et en volant, attendait jusqu'ici la fin du combat. En entrant dans l'eau en combattant, vous restiez sans protection pendant ce temps, et chaque rotation vers la balise vous enfonçait davantage. Le verrou s'active maintenant immédiatement. La touche Ctrl+Maj+N fonctionne désormais aussi en combat.

Technique : Les tests InCombatLockdown dans SkuCore:TogglePitchLock et dans le tick automatique (SkuCore/Core.lua) reposaient sur l'hypothèse non vérifiée que pitchlimit est protégé en combat. C'est une commande de console, modifiable en combat (testé le 2026-09-21). Dans le journal de ce jour-là, 6 secondes avec trois rotations non protégées séparaient le début de la nage et le verrou.

Infobulle des objets d'ensemble : le type d'armure était lu deux fois

Simple : Si un objet fait partie de l'un de vos ensembles d'équipement enregistrés, Sku insère la ligne « Appartient à l'ensemble » dans l'infobulle. Sur ces objets précisément, le type d'armure s'entendait ensuite deux fois, par exemple « Lié, Tissu, Tête, Tissu ». Le premier « Tissu » était un reste qui n'avait rien à faire là. Il n'arrive plus qu'une fois, après l'emplacement : « Lié, Tête, Tissu ». Sur les armes, il en allait de même pour le type d'arme et la vitesse. Les objets hors ensemble n'étaient pas touchés.

Technique : tInsertSetLineAtTop (SkuCore/equipmentSets.lua) décale d'un cran vers le bas toutes les lignes de l'infobulle à partir de la ligne 2. La colonne de droite n'était écrite que si la ligne source en avait une. La ligne que « Tête | Tissu » quittait recevait « Lié » à gauche et gardait son ancien « Tissu » à droite. TooltipLines_helper lit chaque région FontString séparément, d'où le reste audible. La colonne de droite est maintenant toujours écrite : renseignée et affichée, ou vidée et masquée ; de même pour la ligne 2. Le défaut était dans le code depuis la v42.00 et n'est apparu qu'avec des ensembles enregistrés.

Synthèse vocale : des lignes remplacées étaient prononcées plus tard (vraies voix Windows)

Simple : Cela ne concerne que les joueurs qui font parler Sku avec une vraie voix Windows, pas avec le pont NVDA. Là, une ligne que Sku avait remplacée depuis longtemps pouvait rester coincée dans le jeu et être prononcée bien plus tard : en tapant vite un filtre dans un menu, on entendait « g r » ou « g r e i f » seulement après « Menu fermé ». En maintenant la flèche, on entendait deux ou trois entrées sautées après la dernière. Et les lignes de discussion arrivées pendant le défilement venaient jusqu'à 70 secondes trop tard et dans le désordre. Dans un journal envoyé par un joueur, cela faisait 24 annonces sur 524 en une demi-heure. C'est corrigé : ce que Sku a remplacé ou annulé reste muet. Les règles sur ce qui peut interrompre quoi ne changent pas. Le mélange reste aussi : quand une annonce importante s'insère dans une série de lignes en attente (discussion, messages d'état), elle est prononcée d'abord, puis la série continue, la plus ancienne d'abord. Seul ce qui a alors plus de 30 secondes est abandonné.

Technique : Libs/SkuVoice-1.0. C_VoiceChat.StopSpeakingText n'arrête que l'énoncé EN COURS de lecture. Il n'atteint pas un énoncé transmis mais pas encore démarré, et tout ce qui est transmis pendant qu'un autre énoncé est encore dans le client y est mis en attente et ne démarre qu'au prochain PLAYBACK_FINISHED naturel - quel que soit le nombre d'arrêts entre-temps. Nouveau : une porte commune (mClientGate) pour TOUTES les transmissions. Sku ne donne au client qu'UN énoncé à la fois ; la ligne suivante attend dans la file de Sku le FINISHED/FAILED de l'identifiant correspondant, là où queuereset, EndScope et CancelBttsOutput peuvent encore l'atteindre. Comme les lignes attendent désormais dans Sku, la règle du queuereset que le client fournissait par hasard a dû être énoncée : une ligne d'écrasement en attente est dépassée et supprimée (mSkuVoiceQueueBTTS_Overwrite) ; une ligne en attente sans queuereset est placée derrière la nouvelle ligne d'écrasement tant qu'elle a moins de tBttsKeptMaxAge (30 s). Les cinq points d'arrêt passent

par BttsStop : si l'énoncé dans le client n'a pas démarré, l'arrêt est noté et délivré 0,1 s après son STARTED, depuis OnUpdate - jamais depuis le gestionnaire STARTED lui-même : un StopSpeakingText émis de là a bloqué toute la synthèse vocale du client jusqu'au redémarrage lors des tests (l'ancienne fenêtre d'élimination faisait cela). Cela remplace la fenêtre d'élimination de la v43.5 (la même idée avec une

durée estimée, câblée à deux endroits seulement) et la porte propre à l'écho de frappe.

Garde-fous : 0,5 s sans STARTED ouvre la porte (et envoie quand même un arrêt noté) ;

après trois transmissions sans aucun STARTED, la porte se désactive jusqu'au prochain.

Avec le pont NVDA, STARTED et FINISHED arrivent dans l'image de la transmission : la porte n'y est jamais fermée - comportement inchangé. Vérifié avec un modèle hors ligne du client (dev/rework-docs/voice-harness) : ancien code 27-33 énoncés en retard en 3 minutes de charge aléatoire, nouveau code 0 ; modèle du pont identique avant et après.

Dans le journal : "stop deferred (handover not started)", "deferred stop fires", "client gate ttl", "queuereset kept", "STALE-DROP".

Bogue induit, corrigé au passage : la touche « arrêter la sortie audio » (Ctrl+V) n'annulait plus que la ligne en cours, les lignes en attente continuaient - un appui par ligne. Avant, toute la rafale se trouvait déjà dans le client et l'unique arrêt touchait tout ; depuis la porte, les lignes attendent chez Sku, et StopOutputEmptyQueue ne vidait jamais cette file. StopOutputEmptyQueue(true, true) appelle maintenant CancelBttsOutput : lignes et caractères tapés en attente supprimés, puis l'arrêt. Les appelants avec (true, nil) restent tels quels - les lignes de chat en attente doivent y survivre. Scénario du banc d'essai « stopkey » : ancienne version quatre lignes audibles, nouvelle version une seule (coupée).

Menu : « Menu de la cible » était annoncé après le contenu

Simple : Quand le menu ne s'ouvre pas à sa racine mais directement à un endroit précis - ouverture d'un sac, d'un marchand ou d'une boîte aux lettres, Maj+F9 et Maj+F10, les touches de sélection rapide -, on entendait encore, après le contenu, le premier élément de la racine du menu, « Menu de la cible ». Par exemple « Sac 1, Menu de la cible ». C'est corrigé : vous n'entendez plus que l'endroit où vous arrivez. « Menu ouvert » n'est plus prononcé pour ces ouvertures ; il était de toute façon coupé aussitôt, et le son d'ouverture reste. L'ouverture normale du menu est inchangée : « menu ouvert », puis « Menu de la cible ».

Technique : SkuOptions:SlashFunc (SkuZOptions/Core.lua) ouvre un menu fermé via le OnClick de OnSkuOptionsMain puis parcourt le chemin. La branche d'ouverture prononçait « Menu ouvert » en overwrite et plaçait Menu[1].name derrière comme ligne en attente. L'annonce du parcours posait un queuereset, et depuis la porte client de cette version un queuereset conserve les lignes en attente sans overwrite derrière la nouvelle ligne

waiting line(s)"). Corrigé à la source plutôt que par suppression : avec un chemin (au moins deux champs), SlashFunc pose SkuOptions.tOpeningForPathWalk autour de l'appel d'ouverture, et la branche d'ouverture ne dit alors rien. Le drapeau est effacé juste après l'appel, même en cas d'erreur (pcall, erreur relancée). Si le chemin ne trouve rien et que le menu reste à la racine, SlashFunc rattrape l'annonce et écrit "menu:

path walk found nothing" dans le journal de débogage. Les étapes intermédiaires du chemin étaient déjà muettes auparavant.

Écho clavier avec une vraie voix Windows : la longue pause entre les lettres a disparu

Simple : Avec une vraie voix Windows (pas le pont NVDA), la saisie dans le chat laissait une pause d'une demi-seconde à une seconde après chaque lettre - environ une lettre par seconde, quelle que soit la vitesse de la voix. Une voix plus lente allongeait seulement la lettre, la pause restait la même. Cette pause a disparu, les lettres se suivent de près. Chaque lettre est toujours prononcée, y compris les lettres doublées, et plus aucune lettre ne suit après Échap. La même pause existait entre des lignes en attente l'une derrière l'autre (parties d'un texte de quête, plusieurs lignes de chat) ; elle s'y remarque à peine, mais elle est raccourcie elle aussi. Rien ne change avec le pont NVDA.

Technique : Le client signale VOICE_CHAT_TTS_PLAYBACK_FINISHED de façon fixe 0,5 à 1 s APRÈS la fin du son (signet « End ») et ne démarre rien avant. Transmettre plus tôt n'aide pas (v43.5e : l'énoncé est seulement mis en attente et ne peut plus être annulé). Ce qui libère le client immédiatement, c'est un arrêt. Nouveau dans Libs/SkuVoice-1.0 : dès que « Start » puis « End » sont arrivés pour notre énoncé et que quelque chose attend (voie d'écho ou file), OnUpdate envoie un StopSpeakingText après tTailCutDelay (0,03 s) et transmet après tTailCutHold (0,06 s). Jamais depuis le gestionnaire de signets. Un « End » avant « Start » (arrive sur le premier énoncé après un arrêt) ne compte pas. Si rien n'attend, la ligne se termine d'elle-même comme avant. La coupe ne pose pas la marque du pont, bloque une fois le contournement « #queue > 1 » et vide elle-même l'entrée du garde anti-doublon (un énoncé arrêté ne signale pas FINISHED). Mesuré dans le modèle hors ligne : cycle par lettre 1,15 s -> 0,73 s. Pour essayer, session uniquement : /skudebug tts tail <delay> <hold>, /skudebug tts tail off. Dans le journal : « tail cut -> StopSpeakingText ».

La parole d'autres addons perturbait l'écho clavier

Simple : Si un autre addon (ou une commande /run) parlait via la synthèse vocale du jeu pendant que vous tapiez, une lettre pouvait encore suivre après « annulé », donc après la fermeture du champ de chat. Uniquement avec une vraie voix Windows. Corrigé : tant qu'une parole étrangère est en cours, Sku retient ses lettres et ses lignes de chat ; si vous fermez le champ, les lettres en attente sont abandonnées. Les annonces qui interrompent tout de toute façon (menu, « annulé », lignes prioritaires) interrompent aussi la parole étrangère immédiatement, comme avant.

Technique : La porte du client ne connaissait que les transmissions de Sku. Un énoncé étranger (capture : id 403, en attente, démarré 11 s plus tard sous le premier caractère tapé) laissait le caractère suivant sans STARTED, le TTL de 0,5 s l'abandonnait, un deuxième entrait dans le client et prenait le STARTED du premier pour le sien. Nouveau (mForeign, tMaxSeenId, tClientGateFreedAt) : un STARTED que personne n'attend, ou dont l'id est inférieur au plus élevé vu avant notre transmission, est étranger - jamais adopté comme notre id, et rien n'est transmis tant qu'il joue (plafond de silence 8 s ; nos propres arrêts y mettent fin). Sur le pont tous les id valent 0, « plus ancien » est donc strictement inférieur et ne s'y déclenche jamais. Dans l'image où l'un de nos énoncés signale FINISHED, rien n'est transmis : un énoncé étranger en attente démarre exactement sur ce FINISHED et doit être vu d'abord. Scénario du banc d'essai « foreign » : ancienne version quatre lettres après « annulé », nouvelle version aucune. Dans le journal : « BTTS foreign utterance », « BTTS foreign cleared ».

Coller dans un champ de saisie : « Collé » au lieu d'une suite de lettres

Simple : Si vous colliez du texte avec Ctrl+V dans la ligne de chat ou dans un champ de saisie de Sku, tout le texte collé était lu lettre par lettre. Sku dit maintenant une seule fois « Collé ». Lisez le contenu du champ comme d'habitude avec flèche haut ou flèche bas. La frappe normale est inchangée, même rapide. Si vous ne collez qu'un ou deux caractères, ils sont toujours prononcés comme des caractères.

Technique : Un collage livre le presse-papiers sous forme d'appels OnChar individuels, tous dans la même image. tSpeakTypedChar (SkuZOptions/Core.lua) compte les caractères par image (GetTime() est constant dans une image) : à partir du troisième, la suite compte comme un collage - CancelEcho supprime les caractères déjà en attente (aucun n'a encore été transmis dans cette image, la pompe tourne dans OnUpdate), puis un seul SpeakEcho(« Collé »), tout autre caractère de l'image est ignoré. Seuil 3, car deux frappes peuvent tomber dans une même image à faible fréquence d'images. Vaut pour AttachInputEcho (chat) et le champ de saisie de Sku. Dans le journal : « inputEcho paste erkannt ».