Repository navigation
release: v2.3.2 — Classique en mobile, doublons invisibles, Discord à 39 voix - #222
Merged
Merged
Conversation
Les huit voix d'origine brisent le quatrième mur dans les jeux — Velvet Room et mascottes — et pouvaient donc s'adresser au joueur sans que ça sonne faux. Le casting s'ouvre au cast principal de P3, P4 et P5 : eux ne parlent pas AU joueur depuis l'extérieur, ils lui parlent comme à quelqu'un qui joue à côté d'eux. C'est ce registre qui est tenu, pas celui du narrateur omniscient. 29 voix ajoutées, 3 répliques chacune, en français et en anglais. Chaque voix s'appuie sur ce qui la rend reconnaissable plutôt que sur une humeur générique : le baseball de Junpei, les crises de rire de Yukiko, le chou d'Adachi, les vingt minutes que Yusuke passe à contempler sans répondre, le jardinage de Haru qui finit en menace polie. Joker et Koromaru ne parlent pas — ce sont des didascalies. 37 voix : pas un multiple de 7, la contrainte documentée en tête de fichier. Une voix revient tous les 37 jours, le cycle complet fait 111 jours, et chaque personnage parle environ 9 fois par an. Les 37 avatars ont été vérifiés un par un contre la production : Discord télécharge l'image lui-même, un chemin faux donnerait une pastille vide sans que rien ne le signale.
Je l'avais écrit en didascalies, au motif qu'il est un protagoniste muet. C'est une convention de jeu, pas une règle : il a des répliques dans P5, et rien ne justifiait de le priver de voix ici. Décision Hamza. Ses trois lignes tiennent le registre Phantom Thief — une cible qu'on repère, une réponse qu'on vole plutôt qu'on ne devine — et restent courtes, comme ses options de dialogue dans le jeu. Koromaru garde ses didascalies : c'est un chien.
Les deux protagonistes de Persona 3 ouvrent la section P3 — même année, même dortoir, deux façons de la raconter. C'est ce contraste qui porte leurs répliques : lui laconique et fataliste, elle enjouée et taquine. Comme pour Joker, ils parlent. Le protagoniste muet est une convention de jeu, pas une raison de les priver de voix ici. Kotone porte son portrait P5X, celui de sa mise à jour. 39 voix : toujours pas un multiple de 7 (reste 4). Cycle complet de 117 jours, chaque personnage parle environ 9 fois par an. Les 39 avatars revérifiés contre la production.
Le top 3 de la semaine gagne un encart illustré par joueur, et un podium des amitiés les plus fortes. Le mot d'accueil de Margaret tourne sur 7 phrases. Le piège est le stockage des portraits : un portrait recadré vit en base64 dans avatar_data, et Discord va chercher l'image à une adresse — il ne sait rien faire d'une data-URL. Seuls les portraits de galerie non recadrés laissent un chemin exploitable, soit 43 profils sur 328 en production. Le portrait est donc un bonus et jamais la structure : le podium reste entièrement lisible en texte, et l'encart illustré ne s'ajoute que pour ceux qui en ont un. Aucun encart vide, aucune image cassée. La résolution d'URL refuse tout ce qui n'est pas un fichier de la galerie — data-URL, URL externe, remontée de dossier, nom hors liste blanche. Ces valeurs viennent de la base, donc d'une saisie utilisateur passée par l'API. Les amitiés ne sont pas bornées à la semaine, contrairement aux victoires : une amitié se construit dans la durée, et sept jours ne diraient que qui a joué ensemble. Tri par XP comme la page Amitié, le rang plafonnant à 10. Les 7 phrases ne divisent pas 52 sans reste, sinon la même phrase retomberait sur la même semaine chaque année. Un test l'impose.
feat(discord): l'hebdomadaire montre les portraits et les amitiés
Retour de Hamza : le correctif de mise en page de la 2.3.1 « ne s'affiche pas pour les autres ». Ce n'est pas un problème de cache — la prod sert bien le bon CSS, sw.js est en v104 et le service worker est en network-first sur le CSS avec cache: reload. Le correctif était actif pour tout le monde ; il ne valait simplement que 46 px. Les 154 px restants venaient de .hint-giveup-row. C'est une rangée flex en flex-wrap: wrap, et Classique est le seul mode à y placer deux blocs — les cinq autres n'ont que le bloc Abandon, d'où l'absence du symptôme ailleurs. À 390 px chaque bloc fait 229 px, soit 478 px avec le gap pour 380 px disponibles : la rangée passait à la ligne et occupait 292 px au lieu de 136. Ce ne sont pas les images qui débordent (173 px) mais le padding 12px 20px de .link-wrapper, qui ajoute 40 px à chaque bloc. On le rogne et on descend l'image à 60 px : bloc à 176 px, deux blocs plus le gap tiennent jusqu'à 375 px de large. Gain mesuré : 170 px. Le champ de réponse passe de 894 à 724 px, ce qui place Classique devant Émoji. La cible tactile reste à 160×80 px. Il reste 129 px de scroll à 390×844, dus au gabarit commun aux six modes — aucun des six ne tient sur un écran de téléphone, et les toucher serait une refonte.
Un fil par jour sous l'annonce : aujourd'hui un score posté par un joueur se perd entre deux messages du bot, dans un fil il répond à quelque chose. Le type du salon est une dépendance invisible du cron. Un webhook ne peut pas poster dans un forum sans thread_name, ni dans un salon texte avec : Discord renvoie 400 dans les deux cas. Le jour de la conversion, un cron qui l'ignore s'arrête net et le rendez-vous devient muet — déjà vécu dix jours en septembre pour une autre raison. D'où un repli automatique dans les deux sens plutôt qu'un paramètre : on essaie la forme attendue et, sur un 400, on réessaie l'autre une fois. Le salon peut être converti ou reconverti sans toucher au code, et la constante DISCORD_DAILY_FORUM n'économise plus qu'un aller-retour. Quand le repli sert, un warning le dit dans les logs, sinon la constante resterait fausse en silence. 401, 404, 429 et 500 ne sont pas réessayés : ce ne sont pas des problèmes de type de salon, et réessayer ne ferait que doubler l'échec. Le weekly passe par le même helper, et c'est lui qui aurait cassé : DISCORD_WEEKLY_WEBHOOK est absent de la prod, donc le récap du dimanche part dans le salon du quotidien. Il ne suit la constante que s'il n'a pas de webhook à lui. Le commentaire de rotation du quotidien parlait encore de 8 voix et d'un cycle de 48 jours, faux depuis le passage à 39 (117 jours).
fix(classique): Indice et Abandon côte à côte sur mobile
# Conflicts: # PersonaDLE_Update_Documentation/PersonaDLE 2.3/DEV_CHANGELOG.md # ROADMAP.md # TODO.md
feat(discord): le quotidien peut vivre dans un salon forum
…mmandes
Rectification du changelog du jour. Il disait « convertir le salon en forum
(Modifier le salon → Type) » : ça n'existe pas. PATCH /channels/:id {"type":15}
répond 400 / 50035, « Value must be one of (0, 5) » — un salon texte ne devient
que texte ou annonces. Un forum se crée, donc nouveau salon, nouveau webhook,
nouvelle valeur en production, et perte de l'historique.
Décision de Hamza : le salon du quotidien reste, en lecture seule. Le code du
lot précédent n'est pas à défaire, il se replie tout seul sur un salon texte.
Vérifié en production qu'un webhook n'est pas soumis aux surcharges de
permission du salon, donc que le rendez-vous quotidien ne risque rien.
Ajoute aussi, §10, le renvoi vers l'index des commandes d'exploitation et deux
pièges qui ont déjà coûté du temps : crontab n'existe pas sur le mutualisé donc
un crontab -l vide ne prouve rien, et display_errors est éteint en CLI donc un
script qui plante n'affiche rien — une sortie vide n'est pas « aucun résultat ».
…mmandes docs: la conversion en salon forum est impossible, et un index des commandes
Hamza signale le bouton « Supprimer mon compte » en bas de la page profil sur
mobile. Il est dans les ⚙ Paramètres depuis le 2026-09-16 et celui de la page
n'est qu'un relais marqué hidden : il était simplement repeint.
[hidden] n'est display:none que dans la feuille du navigateur, donc n'importe
quelle règle d'auteur posant un display la bat — ici .btn-danger { display: flex }
dans la media query de cible tactile, sous 480 px. Et .hidden n'était défini
nulle part globalement : quatre fichiers l'avaient rustiné dans leur coin, et
leaderboard.css portait déjà un commentaire décrivant le piège.
Le même manque cachait un second bug que personne n'avait signalé : une pastille
de notification rouge et VIDE sur l'icône Amis de la barre du bas, sur les huit
pages et à toutes les largeurs, donc devant tous les joueurs.
D'où une règle unique dans global.css, avant tout le reste. Le !important est
assumé : c'est la seule façon de battre une règle d'auteur plus spécifique, et
c'est ce que font normalize.css et HTML5 Boilerplate pour la même raison.
Rayon d'action mesuré avant d'écrire la règle, page par page sur la production :
9 éléments concernés, et les 9 sont ces deux bugs. Après correction, zéro élément
fantôme et un nombre d'éléments interactifs identique partout — rien de légitime
ne disparaît. Vérifié aussi que les 13 endroits qui écrivent un display inline
n'utilisent pas .hidden, sinon le !important les aurait figés.
Le test E2E interdit la classe entière de bug plutôt que de nommer les deux
coupables : aucun élément portant .hidden ou [hidden] ne doit se peindre, sur
neuf pages et quatre largeurs.
fix(css): ce qui est marqué caché est enfin caché
CACHE_VERSION v104 → v105 : le CSS et le JS sont servis en network-first, donc la feuille corrigée arrivait déjà, mais les images et les sons sont en cache-first — et seuls les joueurs déjà venus sont concernés. Ligne 2.3.2 dans le README, et les trois correctifs visibles par un joueur ajoutés au changelog joueur, en FR et en EN : Indice et Abandon côte à côte en Classique, le bouton de suppression en double retiré du profil, la pastille de notification vide retirée de l'icône Amis. Aucune migration à jouer : la prod est déjà à la 055 et ce lot n'ajoute aucun fichier SQL. schema:check-prod passé avant le merge, aucune dérive.
chore(release): préparer la 2.3.2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release de ce qui s'est accumulé sur
developdepuis la 2.3.1.Contenu
Correctifs visibles par un joueur
[hidden]et.hiddenenfin honorés — deux éléments se peignaient alors qu'ils étaient marqués cachés : le bouton « Supprimer mon compte » en double en bas de la page profil (il n'appartient qu'aux ⚙ Paramètres), et une pastille de notification vide collée à l'icône Amis, sur les huit pages et à toutes les largeurs.Discord
Documentation — la conversion d'un salon texte en forum est impossible (Discord la refuse :
Value must be one of (0, 5)), et un index des commandes d'exploitation.Base de données
Aucune migration à jouer. La prod est déjà à la 055 et ce lot n'ajoute aucun
.sql.npm run schema:check-prod, exécuté depuis le webroot avant d'ouvrir cette PR :Cache
CACHE_VERSIONv104 → v105. Le CSS et le JS sont servis en network-first, donc la feuille corrigée arrivait de toute façon ; le bump couvre les images et les sons, en cache-first. Seuls les joueurs déjà venus sont concernés — c'est précisément le cas qu'un test ne voit jamais.Vérifications
hiddensur 9 pages × 4 largeurs.Hors périmètre de cette release
Les commandes
/statut,/annonce,/syncet le passage du salon du quotidien en lecture seule vivent dans le dépôtpersonadle-discordet sur le serveur maison — déjà déployés. Seuls les crons Discord sont hébergés ici.