Sanctuary est un addon World of Warcraft qui protège les joueurs du harcèlement. Il bloque les invitations, les chuchotements, les duels, les échanges et les messages indésirables avant qu’ils ne s’affichent, sans fenêtre, sans message et sans son. Par défaut, seules les personnes que le joueur connaît peuvent le contacter. Je l’ai conçu parce que les outils du jeu ne suivent pas quelqu’un qui recrée des comptes pour continuer à harceler.
Le projet est né du problème bien réel d’une personne harcelée en jeu, et d’autres joueurs vivent la même chose. Un MMO est un jeu dans lequel on s’investit socialement. Beaucoup y cherchent un havre de paix, et le harcèlement en ligne peut les y suivre comme ailleurs.
Cet article décrit les choix de conception qui en découlent, les cas limites que Blizzard ne documente pas, et la façon dont j’ai testé un addon dont une partie du comportement n’existe qu’en jeu.
Ce que /ignore ne couvre pas
World of Warcraft propose /ignore. Depuis le patch 9.1.5, fin 2021, la
commande bloque tous les personnages du compte WoW de la personne ignorée :
changer de personnage ne suffit plus pour la contourner
(notes du patch 9.1.5).
Elle ne suit pas, en revanche, une personne qui crée un nouveau compte. Les
comptes gratuits rendent ce contournement facile, et une personne déterminée
peut recommencer à l’infini.
Des addons existent pour filtrer les chuchotements ou les invitations d’inconnus. À mes yeux, aucun ne couvrait l’ensemble des interactions dont on peut avoir besoin de se protéger.
Sanctuary part donc de la question inverse : qui a le droit de me joindre ? Dans le mode par défaut, seuls passent la guilde, les amis, le groupe ou le raid en cours et les noms autorisés à la main. Un compte recréé reste un inconnu, il ne passe pas.
Le filtrage se règle ensuite finement. Un second mode laisse passer tout le monde, sauf les noms bloqués. Les deux approches se combinent : la liste de blocage accepte des motifs, et un fragment de nom suffit à bloquer toute une famille de personnages. Un nom bloqué l’emporte sur tout, même sur la guilde ou le groupe. Chaque type d’interaction se règle à part :
- Invitations de groupe et de guilde
- Chuchotements des personnages du jeu
- Duels et échanges
- Messages en /dire et /crier, et émotes
- Spam des canaux publics
- Courrier des personnes filtrées
Bloquer avant que le joueur ne voie quoi que ce soit
Masquer une ligne de chat est la partie facile. Le jeu permet aux addons de filtrer les messages avant leur affichage, et Sanctuary décide à cet endroit si une ligne apparaît.
Une invitation est plus exigeante. Elle ouvre une fenêtre et joue un son. Pour un joueur bloqué, Sanctuary refuse l’invitation avec les fonctions du jeu lui-même, et la fenêtre ne devient jamais visible.
Le son m’a demandé le plus d’essais. La fenêtre le joue au moment où elle s’ouvre, et je ne voulais pas en laisser passer la moindre fraction, même une demi-seconde. La version actuelle coupe d’abord, décide ensuite. Sanctuary capture le son d’origine de la fenêtre et coupe les sons d’interface qu’elle déclenche. Si l’expéditeur est autorisé, l’addon rejoue lui-même ces sons. S’il ne l’est pas, rien n’est entendu.
Une coupure de son survit à un rechargement de l’interface. Sanctuary enregistre donc dans ses données sauvegardées qu’un son est coupé, et le rétablit au chargement suivant si le client a été rechargé entre-temps.
Deux réglages suivent la même prudence. Supprimer un courrier est la seule action irréversible de l’addon : elle ne s’active que si le joueur la choisit. Et le Journal, qui garde la trace de ce qui a été bloqué, masque par défaut le texte des messages. Il ne montre pas à une personne harcelée ce qu’on lui a envoyé tant qu’elle ne le demande pas.
Les restrictions de Midnight en instance
Le bug le plus difficile à isoler est apparu pendant le bêta-test. En donjon, des invitations de groupe ou des messages privés passaient parfois, alors que tout fonctionnait hors instance.
La cause tient à Midnight. Depuis le patch 12.0.0, le jeu restreint ce que les addons peuvent lire pendant les combats de boss, les clés Mythique+, les matchs JcJ et sur les cartes restreintes comme les donjons et les raids. Les messages concernés arrivent sous forme de « secret values » : un addon peut les stocker et les transmettre, mais ne peut ni les comparer ni les tester (warcraft.wiki.gg). En plein donjon, Sanctuary ne sait donc plus si une ligne vient d’un joueur, du jeu ou d’un autre addon.
Une décision fiable devenait impossible. J’ai ajouté un mode strict, expérimental et désactivé par défaut : quand le joueur est groupé ou en instance, Sanctuary masque dans le doute tout message système qu’il ne peut pas lire.
local function shouldSuppressSecretGroupInviteSystemMessage(msg)
if not isRestrictedValue(msg) then return false end
return (evaluateStrictSecretSuppression())
end
Ce mode a un prix : il masque aussi des messages système légitimes. Il reste donc une option, à activer seulement si des invitations indésirables passent encore en donjon, en raid ou en JcJ.
Une seule décision par message
Dans une version antérieure, chaque message de chat était jugé deux fois. Le filtre décidait si la ligne s’affichait, et le gestionnaire d’événements décidait ce qu’il fallait journaliser et compter. Les deux copies répétaient le même ordre de règles.
Au cours d’une même version, trois correctifs sont tombés sur la mauvaise copie. Le dernier a produit un bug visible : une note qu’un joueur s’envoyait à lui-même était avalée par le gestionnaire alors que le filtre la laissait passer.
Aujourd’hui, filtres et gestionnaires sont générés à partir d’une seule table, et chaque décision passe par une fonction par type d’interaction. Une nouvelle condition s’ajoute dans la décision, jamais chez ceux qui la consomment. L’interface, elle, ne décide rien : elle dessine. Le principe est courant en backend, une règle métier vit à un seul endroit. Ici, il permet aussi de tester les règles sans lancer le jeu.
Tester hors du jeu, puis dans le jeu
Un addon World of Warcraft est fragile. Il dépend d’une API qui évolue, d’interfaces qui se redessinent et de cas limites que personne ne documente. Chaque cas découvert pendant le développement devait donc rester couvert.
Le dépôt contient un harnais de tests d’environ 15 000 lignes de Lua. Il simule l’API du jeu, des fenêtres aux listes d’amis et de guilde en passant par la boîte aux lettres et les valeurs secrètes. Il charge l’addon dans l’ordre de son fichier TOC et déclenche les événements comme le ferait le client. Comme l’addon, il ne dépend d’aucune bibliothèque ni d’aucun framework.
$ lua5.4 tests/runtime_harness.lua
OK: 5867 assertions
Il tourne à chaque push. Une seconde vérification contrôle que l’addon reste lisible par Lua 5.1, la version qu’exécute le client.
Ce harnais ne voit ni le comportement réel en instance, ni les interactions avec les interfaces du jeu. Deux autres niveaux de test couvrent ce manque.
Le premier est l’IA. Nous convenions ensemble des tests à faire, puis l’IA, en computer use, les jouait directement dans WoW. Elle pouvait aussi exécuter du Lua dans le chat du jeu pour sonder l’état de l’addon, provoquer un cas précis ou repérer un bug. Elle prenait ainsi en charge les tests d’interaction les plus rébarbatifs.
Le second est le bêta-test. Un mode debug permet de copier le journal de l’addon pour le coller dans une issue GitHub, et rien n’est envoyé automatiquement. C’est avec ces logs et ces retours que j’ai pu isoler le problème des instances.
Sur un terrain sans documentation fiable, les tests hors jeu ne suffisent pas seuls. Ils gardent ce qui a été appris, et seuls les tests en jeu et les retours réels apprennent quelque chose de nouveau. Je garde les deux.
L’IA m’a aussi servi à itérer vite, à chercher de la documentation et des cas limites, et à travailler l’interface. Avec autant d’options, le plus difficile était de ne pas rendre l’addon indigeste. Déléguer une partie de l’exécution me laisse surtout la place de réfléchir à l’architecture et à la meilleure implémentation.
Du prototype à la 1.2.0
Sanctuary a commencé en avril 2026 sous forme de prototype. Il avait déjà une partie de ces bugs, une interface complètement différente et moins de fonctionnalités. La 1.0.0, publiée le 27 août 2026, est la première vraie version. La 1.1.0 a suivi le 3 septembre avec la gestion du courrier, puis la 1.2.0 le 27 septembre, en sept langues.
La publication est automatisée. Un tag de version lance les tests, puis empaquette l’addon et le publie sur GitHub et sur CurseForge. Poser ce tag reste une décision manuelle, et les notes de version sont écrites pour les joueurs plutôt que générées à partir des commits.
Les compromis assumés
Protéger par défaut coûte parfois un contact légitime. Un inconnu qui invite directement dans un groupe, par clic droit ou par commande, est bloqué comme les autres. Les groupes formés avec l’outil de recherche de groupe du jeu ne sont pas concernés. Une option accorde aussi la confiance aux membres d’un groupe après cinq minutes passées ensemble, sans jamais passer outre un nom bloqué.
Le mode strict échange un peu de visibilité contre la tranquillité, en
connaissance de cause. Sanctuary ne touche jamais aux contacts Battle.net, qui
se gèrent dans Battle.net, et il complète /ignore plutôt qu’il ne le remplace.
Sanctuary est disponible sur CurseForge, et son code est public sur GitHub.