Sprites jouables · l'étude expliquée pas à pas

La guerrière HD, pas à pas

Dans Baldur's Gate II, le joueur choisit les couleurs de son personnage : l'image du héros n'est donc pas une image finie, mais un coloriage numéroté que le jeu remplit en direct. Comment lui donner la finesse d'une image HD sans casser ce coloriage ? Trois intelligences artificielles ont enquêté, se sont relues et corrigées. Voici leur étude finale, expliquée pour tout lecteur curieux, sans rien retirer de la technique.

  • 3 IA · 4 temps2 études, 2 relectures croisées, 1 synthèse, 1 relecture finale
  • 774 BAMfichiers d'animation recensés · 870 objets (ITM)
  • 628 BAMpérimètre utile identifié dans l’étude
  • 12variantes de recoloriage testées
  • −18 % / −23 %résultats historiques E3b/E5 · Q8 contre Q0
  • x2 + BOXchoix retenu après les essais en jeu
Moteur vérifié au binaire Code runtime relu Mesures hors jeu reproduites Q3m testé en jeu · K6 retenu Guide définitif : GUIDE_DEFINITIF_SPRITES_HD_BG2EE.md
De l’étude à la réalisation. Les explications et comparateurs des 29–30 septembre restent en place. Les ajouts datés présentent la suite : Q3m K6, lecteur V6, choix x2 + BOX, paperdolls et extension aux autres familles. 78 animations Character produites et installées ; validation visuelle limitée aux périmètres explicitement acceptés. La production, l’installation, la QA et la release restent des états distincts.
00 · Le point de départ

Un coloriage, pas une image

Avant la méthode et les chiffres : de quoi parle-t-on, pourquoi est-ce difficile, et qu'a-t-on trouvé ? Le reste de la page détaille ce résumé.

Le jeu. Baldur's Gate II : Enhanced Edition (BG2EE) est un jeu de rôle vu de dessus. Ses personnages sont de petites images animées, les sprites : la guerrière étudiée ici mesure une soixantaine de pixels de haut. Sur un écran d'aujourd'hui, chacun de ces pixels devient un carré bien visible. BG2 HD Visual Project les redessine plus finement, avec deux fois (x2) ou quatre fois (x4) plus de pixels dans chaque direction, sans changer leur taille à l'écran.

La difficulté. Dans ce jeu, le joueur choisit les couleurs de son personnage (cheveux, peau, deux couleurs de vêtements) et chaque pièce d’équipement apporte les siennes. Chaque pixel du sprite porte un numéro qui veut dire « tel matériau, telle nuance ». Le BAM contient aussi une palette, mais, pour ces personnages recolorables, les couleurs affichées sont réalisées par le moteur au moment du dessin. C’est un coloriage numéroté, que le jeu remplit à chaque image avec les teintes du moment. Avantage : une seule image sert toutes les guerrières. Contrainte : chaque gamme native n’a que 12 nuances, du plus clair au plus sombre.

Pourquoi un bel agrandissement ne suffit pas. Un réseau de neurones sait agrandir joliment une image : il invente des volumes et des dégradés continus. Mais ce qu'il rend est une image finie, peinte pour un seul jeu de couleurs. Pour qu'elle reste recolorable, il faut la reconvertir en coloriage numéroté, et c'est là que tout se joue. Douze nuances suffisaient pour un petit sprite ; en HD, elles découpent les dégradés en bandes, et un choix de numéros parfait sous un jeu de couleurs laisse des liserés sous un autre.

L'objectif de l'étude. Trouver comment donner aux sprites le modelé d'un agrandissement HD tout en laissant le jeu les colorier lui-même, quelles que soient les couleurs choisies par le joueur, et fixer une recette assez précise pour être programmée.

Pourquoi « 0x6110 » ? C'est le numéro que le jeu donne à l'animation « femme humaine guerrière » (écrit en hexadécimal, d'où le « 0x »). Elle sert de cas d'école : ce qui vaut pour elle vaudra pour les 78 animations de personnages construites sur le même principe.

Avant, après

Couleurs du personnage
Image d’originePrototype E3b
La guerrière telle que le jeu la contient, agrandie sans retouche La même guerrière, rendu HD visé par l'étude

Faites glisser la séparation. À gauche, l’image d’origine, agrandie sans retouche. À droite, le prototype Q3m x4 de l’expérience E3b : aperçu hors jeu conservé pour expliquer l’étude. Ce n’est pas le nouveau rendu K6 x2. Corps en plates, casque, bouclier et épée, au repos, face au sud. La planche K6 et la vidéo en jeu complètent cette comparaison.

Guerrière d'origine, palette REF : armure sombre, détails rouges et bleus
Palette REF30 · 47 · 57 · 12 · 39 · 21 · 3
Guerrière d'origine, palette B : armure gris acier
Palette B21 · 57 · 47 · 8 · 66 · 30 · 0
Guerrière d'origine, palette D : armure bleue bordée d'or
Palette D67 · 68 · 47 · 84 · 25 · 57 · 2
Guerrière d'origine, palette E : armure bleu vif
Palette E30 · 47 · 57 · 12 · 39 · 68 · 3
Un seul et même fichier, quatre jeux de couleurs. Seuls changent les sept numéros de gamme indiqués sous chaque image, dans l'ordre : métal, couleur mineure, couleur majeure, peau, cuir, armure, cheveux. Ce sont quatre des palettes utilisées par l'étude. Aperçu hors jeu : la même palette est appliquée ici aux quatre couches (corps, casque, bouclier, épée).
La réponse, en une phrase. Garder le coloriage numéroté, mais permettre à chaque pixel de se placer entre deux nuances voisines, par huitièmes, en choisissant cette position pour qu'elle reste juste sous plusieurs jeux de couleurs à la fois ; le module du projet, déjà branché dans le jeu, fera le mélange au moment d'afficher.Nom de code de la méthode : Q3m. Nom du nouveau format de fichier : registre V6. Statut : lecteur implémenté, Q3m testé en jeu ; production Character x2 installée.
Trouvaille 1

La limite vient du jeu

Le fichier d'image pourrait désigner 256 couleurs. C'est le moteur qui n'en prépare que 12 par matériau, et il les recalcule à chaque image : impossible d'en ajouter sans toucher au jeu entier.

Trouvaille 2

Le réseau dépend des couleurs

Montrez-lui la même guerrière avec d'autres couleurs : il ne dessine plus les mêmes ombres, et 20 à 44 % des numéros changent. Une recette réglée sous un seul jeu de couleurs ne peut pas convenir à tous.

Trouvaille 3

Des huitièmes suffisent

Avec 8 positions entre deux nuances, une gamme passe de 12 à 89 teintes possibles. L'écart au dessin du réseau recule de 14 % sur des couleurs nouvelles, et le « grouillement » du corps en animation tombe de 14,1 % à 5,7 %.

Trouvaille 4

Rien n'est joué sans le jeu

Les premiers chiffres ont été obtenus hors jeu, face à une cible produite par un réseau. Les essais suivants ont montré Q3m dans le jeu et conduit au choix x2 + BOX. Une mesure de fidélité ne décide toujours pas de ce qui est beau : l’appréciation visuelle reste celle de l’auteur du projet, sur le périmètre testé.

Pour lire cette page

Trois cartes par section

Le but, la recherche, la trouvaille : de quoi saisir chaque étape sans tout lire. Les lignes « En clair » reformulent les passages techniques.

Pour lire cette page

Des étiquettes de preuve

confirmé mesuré ouvert retenu rejeté
Chaque affirmation dit d'où elle tient sa certitude. L'échelle est expliquée à la section 02.

Pour lire cette page

La technique reste entière

Adresses, formules et noms de fichiers figurent en petits caractères ; les mots du métier renvoient au lexique. Les sections 01 à 17 portent les mêmes numéros que la présentation technique.

01 · La méthode d'enquête

Trois IA, quatre temps

L'étude n'a pas été écrite d'un jet par un seul modèle. Elle a été menée comme une expertise contradictoire : deux enquêteurs qui ne se parlent pas, puis qui se relisent ; un troisième qui fusionne ; une dernière vérification sur pièces.

Le but

Obtenir une étude à laquelle on peut se fier sans la croire sur parole : chaque affirmation importante doit avoir été trouvée deux fois, ou vérifiée par un autre que son auteur.

La recherche

La même consigne donnée à deux modèles de deux éditeurs différents, chacun dans son outil, sur les mêmes fichiers du jeu et du projet. Puis relectures croisées, synthèse par un troisième modèle, relecture finale.

La trouvaille

Sans se lire, les deux enquêteurs arrivent à la même architecture : c'est le signal le plus fort du dossier. Et chaque relecture a trouvé des erreurs, dont une faute de calcul qui faussait une mesure.

Enquêteur A · relecteur final

Claude Opus 5.5

Travaille dans l'outil Claude Code, avec accès aux fichiers du jeu et au code du projet. Une des deux études de départ, une relecture croisée, puis la relecture finale.

Dans le dossier : fichiers « Claude », « ClaudeCode ».
Enquêteur B

GPT 6-Astra

Travaille dans l'outil Codex, avec les mêmes accès. L'autre étude de départ, puis sa relecture croisée, intitulée « comparaison critique ».

Dans le dossier : fichiers « Codex ».
Synthétiseur

5.6 SOL

N'a écrit aucune des deux études. Son rôle : les fusionner en une seule, en gardant le meilleur de chacune.

Dans le dossier : « guide ultime », rangé sous l'étiquette « synthèse Codex ».
Chef d'orchestre

L'auteur du projet

Donne la consigne, transmet les études d'un modèle à l'autre au bon moment, et reste seul juge de ce qui est beau en jeu. Aucun modèle n'a lu l'autre avant d'y être autorisé.

Temps 1Deux recherches parallèles, même consigne, aucun échange
Claude Opus 5.5

Étude indépendante

Trois expériences, dix façons de recolorier comparées. Propose les sous-nuances réglées sur plusieurs palettes.

GPT 6-Astra

Étude indépendante

Lit le programme du jeu, recense tous les fichiers, calcule quatre agrandissements. Montre que le réseau dépend des couleurs.

Temps 2Relectures croisées, puis mise à jour de sa propre étude
Claude Opus 5.5

Revue croisée

Relit tout le dossier d'Astra, rejoue ses méthodes sur les images d'Astra (expérience E5), accepte six corrections.

GPT 6-Astra

Comparaison critique

Relance l'expérience d'Opus, retrouve ses chiffres, puis y découvre une erreur de signe. Corrige aussi l'une de ses propres affirmations.

Temps 3Synthèse
5.6 SOL

Étude fusionnée, dite « guide ultime »

Écarte les doublons, classe chaque affirmation par niveau de preuve, combine le meilleur des deux études en un seul plan de production.

Temps 4Relecture finale
Claude Opus 5.5

Vérification sur pièces et derniers essais

Repart du programme du jeu, du code et des données pour revérifier chaque affirmation qui pèse sur une décision. Neuf corrections de plus, format de fichier spécifié au bit près.

RésultatCe que présente cette page
Étude finale

Guide définitif

Le document de référence pour la suite du développement. Les études intermédiaires restent intactes, avec leurs erreurs listées à la section 13.

Pourquoi le temps 1

Deux enquêtes séparées

Si deux enquêteurs qui ne se sont pas concertés trouvent la même chose, ce n'est sans doute pas un hasard. S'ils divergent, on sait où regarder.

Pourquoi le temps 2

Se relire l'un l'autre

On voit mieux les erreurs des autres que les siennes. Et il ne s'agissait pas seulement de relire : chacun a relancé les calculs de l'autre.

Pourquoi le temps 3

Un troisième pour fusionner

Un auteur défend son travail. Confier la synthèse à un modèle qui n'a écrit aucune des deux études évite qu'un avis l'emporte par habitude.

Pourquoi le temps 4

Revenir aux pièces

Une synthèse peut recopier une erreur de bonne foi. La dernière relecture ne part pas des études, mais du jeu lui-même.

Le détail, en sept étapes, dans l'ordre réel du travail

  1. Temps 1Deux recherches parallèles. Même consigne, mêmes fichiers, aucun échange.
  2. 0129/09 · 19:46
    Claude Opus 5.5

    Étude indépendante

    Trois expériences. E1 : mesurer les 256 gammes de couleurs du jeu, pour savoir à quel point leurs 12 nuances sont espacées. E2 : compter quels numéros de couleur sont réellement utilisés, sur 65 composants de la guerrière. E3 : le banc d'essai, avec 4 couches (corps, casque, bouclier, épée), deux animations (repos et marche), 5 palettes et 10 méthodes de palettisation.

    Propose la sous-nuance fractionnaire ajustée sur plusieurs palettes, avec mélange aux frontières (méthode Q8), et un repli qui n'exige pas de nouveau DLL (méthode Q6).
  3. 0229/09 · 20:08
    Claude Opus 5.5

    Erratum E3b

    Une correction que le modèle s'applique à lui-même. L'animation de repos échantillonnée ne contenait que 4 poses distinctes sur 12 images : les mêmes images se répétaient, ce qui diluait la mesure du scintillement. L'expérience est refaite sous le nom E3b : 20 changements de pose, 120 occurrences d'image.

    Classement des méthodes inchangé ; chiffres temporels revus ; deux conclusions retirées (le tramage Bayer « pire partout », le scintillement « −50 % »).
  4. 0329/09 · 19:52–20:10
    GPT 6-Astra

    Étude indépendante

    Une approche d'enquêteur : désassemblage de BaldurReal.exe, le programme du jeu, pour lire ce qu'il fait réellement ; inventaire complet de ses archives (KEY/BIFF) ; quatre agrandissements réellement calculés sur 60 frames ; sensibilité du réseau à la palette qu'on lui montre ; essais de tramage ; interpolation réglée sous une seule palette.

    Le moteur lit MPALETTE, pas RANGES12 ; 774 BAM, 870 ITM, 628 BAM utiles ; refaire le calcul du réseau sous une autre palette change 20 à 44 % des indices.
  5. Temps 2Relectures croisées. Chacun reçoit l'étude de l'autre, la vérifie, puis met à jour son propre travail.
  6. 0429/09 · 20:26
    Claude Opus 5.5

    Revue croisée + E5

    Lecture complète du dossier d'Astra, puis un match retour : les méthodes d'Opus sont rejouées sur le corpus et les palettes d'Astra (expérience E5), et la méthode d'Astra est exécutée avec sa propre fonction de quantification, sans y toucher.

    Sur palettes non utilisées pour le réglage : Q8 −23 % face au pipeline actuel, −20 % face à l'interpolation d'Astra. Six corrections acceptées.
  7. 0529/09 · 20:30
    GPT 6-Astra

    Comparaison critique

    Astra relance l'expérience E3b d'Opus et retrouve ses chiffres à l'identique (écart 0). Il audite ensuite le traitement des frontières, vérifie l'arrondi réel à 3 bits et relit les passages utiles du code du runtime.

    Trouve une erreur de signe dans l'alignement temporel ; 3 bits ≈ sans perte ; 13,3 % des frontières touchent plus de 2 canaux ; Q6 possible sans changer le rendu.
  8. Temps 3Synthèse. Les deux études mises à jour sont confiées à un modèle qui n'a écrit ni l'une ni l'autre.
  9. 0629/09 · 21:16
    5.6 SOL

    Synthèse « guide ultime »

    Fusion des deux dossiers. Avant d'écrire, SOL inventorie tout : 5 102 fichiers, dont 1 709 contenus réellement différents une fois les copies écartées. Il pose une échelle de preuve et un plan de production en phases.

    Ordre Q6 → Q3m → Q8 ; x2 livré, x4 après preuve ; aucun tramage.
  10. Temps 4Relecture finale. L'étude de SOL revient à Opus 5.5, qui repart des fichiers du jeu.
  11. 0730/09
    Claude Opus 5.5

    Relecture finale

    Revérification au binaire, au code runtime et aux fichiers de données de chaque affirmation qui pèse sur une décision. Derniers contrôles ajoutés : à quel point les palettes de validation ressemblent à celles du réglage, et quelle part du gain revient à chaque ingrédient.

    9 nouvelles corrections (Catmull-Rom existe, palettes « inédites » partiellement vues, Q3m porte 77 % du gain…) ; format V6 spécifié au bit ; guide définitif.
Le bilan des relectures croisées

Les deux modèles étaient arrivés, séparément, à la même architecture : garder les sept gammes de 12 nuances, et faire mélanger deux nuances voisines par le module du projet. Ils se complétaient sur le reste. Astra était le plus rigoureux sur l'enquête : il a lu lui-même le programme du jeu, trouvé le bon fichier de couleurs et trié les fichiers réellement utiles. Opus était allé plus loin sur la méthode : le réglage sur plusieurs palettes et le traitement des frontières, qu'Astra décrivait sans les avoir testés, étaient programmés et mesurés. Les deux relectures le disent dans les mêmes termes.

Opus 5.5, dans sa revue croisée« Deux recherches indépendantes qui convergent, c'est le signal le plus fort de ce dossier. »
GPT 6-Astra, dans sa comparaison critique« La meilleure base de développement est donc : faits moteur/inventaire Codex + expériences d'encodage Claude + corrections et protocole commun. »

Sur les images et dans les noms de fichiers du dossier, « Claude » désigne le travail de Claude Opus 5.5 et « Codex » celui de GPT 6-Astra (Codex est l'outil dans lequel il travaillait). La synthèse de 5.6 SOL y porte le nom de « guide ultime ».

Suite du développement · 30 septembre–4 octobre

La même architecture, désormais réalisée

La suite a transformé la recette en code : choix K6 après dix palettes de validation disjointes, lecteur V6 Python/C++, premiers essais Q3m en jeu, puis décision x2 + BOX le 2 octobre. La production a ensuite couvert les 78 animations Character et les paperdolls normaux de 6110. L’extension V7 traite les autres profils de créatures avec des partenaires de couleur adaptés.

Les quatre temps racontés plus haut décrivent l’enquête initiale. Ces nouvelles étapes complètent cette histoire ; elles ne changent ni les anciennes mesures ni les avis signés à leur date.

Les mesures historiques ci-dessous restent celles de l’étude. Le bloc ajouté en fin de section décrit les décisions et réalisations ultérieures.
02 · L'essentiel

Ce qui est établi, mesuré ou ouvert

Chaque affirmation porte son niveau de preuve. Une mesure hors jeu n'est jamais une validation en jeu.

Le but

Séparer ce que l'on sait de ce que l'on espère. Une étude écrite par des IA peut sonner juste et se tromper : l'étiquette dit d'où vient chaque certitude.

La recherche

Chaque conclusion a été classée selon sa preuve : lue dans le jeu ou dans le code, mesurée sur un échantillon, constatée en jeu, ou simplement proposée.

La trouvaille

L’étude initiale distinguait deux faits confirmés, deux résultats mesurés, deux questions ouvertes et un format retenu. Depuis, les validations K6, le lecteur et le choix d’affichage ont avancé. Les sections suivantes gardent l’explication initiale et ajoutent les réalisations à leur date.

Confirmé

Lu dans le programme du jeu, ses fichiers ou le code du projet. N'importe qui peut le revérifier, sans jugement visuel.

Mesuré

Chiffré hors jeu, sur l'échantillon décrit. Ne vaut que pour cet échantillon et cette façon de mesurer.

Observé en jeu

Constat daté de l'auteur du projet, sur une scène précise. Ni contrôle qualité complet, ni version publiée.

Retenu · candidat

Choix de conception, avec son état précisé : candidat à programmer, implémenté, ou décidé après essai. Une méthode retenue ne signifie pas que tous ses assets ont été validés.

Ouvert

La preuve manque. Aucune décision de production ne peut s'appuyer dessus.

Rejeté

Piste écartée. Le texte précise si elle a été testée puis rejetée, ou abandonnée avant implémentation.

Confirmé

La limite des 12 nuances ne vient pas du BAM (256 indices) mais du moteur : chaque gamme est une ligne de 12 couleurs de MPALETTE.BMP, et les indices 88 à 255 sont des moyennes entières des nuances 2 à 9 de deux gammes. Tout est recalculé à chaque image : le corps n'a aucune couleur fixe libre.En clairLe fichier du sprite pourrait désigner 256 couleurs ; c'est le jeu qui n'en prépare que 12 par matériau, plus des mélanges de deux matériaux. Et comme il recalcule tout en permanence, on ne peut pas « réserver » une case pour une couleur à soi.

Confirmé

Le DLL du projet capture déjà la palette réalisée de chaque couche (corps, arme, main gauche, casque) et reconstruit la texture HD sur le processeur. C'est là qu'il faut agir : stocker une position continue dans la gamme et laisser le DLL mélanger deux nuances voisines.En clairLe projet a déjà un module branché dans le jeu (un fichier DLL). Il récupère les couleurs exactes que le jeu vient de calculer pour chaque élément du personnage, et fabrique l'image HD avec. Il suffit de lui apprendre à mélanger deux nuances voisines.

Mesuré

Q3m (prototype E3b ajusté sur plusieurs palettes) réduit l'écart au modèle de 14 % sur les palettes de validation ; Q8 (Q3m + frontières) de 18 %. Q3m porte à lui seul 77 % du gain. Sur le corpus d'Astra, Q8 fait −23 %.En clair« L'écart au modèle » est la différence entre ce que le réseau de neurones a dessiné et ce que l'on parvient à restituer avec les couleurs du jeu. Les sous-nuances la réduisent de 14 %, et c'est cette idée simple, pas le raffinement des frontières, qui fait l'essentiel du progrès.

Mesuré

Scintillement du corps (alignement corrigé) : 14,1 % → 5,7 % avec Q3m, 4,8 % avec Q8. La diffusion d'erreur double le scintillement ; le tramage n'est pas retenu.En clairD'une image à l'autre d'une animation, des pixels censés rester identiques changent de couleur : la surface « grouille ». Les sous-nuances divisent ce défaut par deux et demi.

Mesuré

Les validations E3b partageaient 1 à 6 canaux sur 7 avec le réglage : seule D était quasi indépendante, avec des gains maintenus (−15,5 % et −25 %). Ce constat avait motivé dix palettes entièrement nouvelles. Le contrôle P1 a depuis réalisé cette séparation, par numéro et par rampe RGB au même canal ; les résultats K6 figurent en section 12.En clairTester d’autres couleurs ne suffit pas si elles ressemblent trop aux couleurs de réglage. Les dix nouvelles palettes ont été construites pour éviter ce recouvrement.

Décidé

x2 + BOX retenu. L’essai Q0 du 26 septembre avait trouvé le x4 légèrement meilleur, pour +58 % de registre. Les comparaisons Q3m et les essais de réduction suivants ont conduit à conserver le x2. Le résultat paraît plus naturel, avec une légère présence du pixel art ; le x4 peut donner un lissage plus « plastique ». Ces appréciations concernent des essais différents, datés.

Implémenté

Registre V6 implémenté. Indice I, fraction F par huitièmes, dépendances palette et contrat de décodage. Le V6 livré n’a aucun plan frontière B ni compactage des fractions à 3 bits : I et F sont des plans u8. Sans F, les pixels reconstruits sont identiques à V5 ; les fichiers et en-têtes restent différents.

État au 4 octobre

Ce qui est désormais acquis

Mesuré : K6 améliore chacune des dix palettes de validation, à x2 et x4. Implémenté : V6, dépendances exactes et reconstruction CPU. Décidé : x2 + BOX pour les essais Q3m Character ; Nearest pour la voie UI. Produit et installé : 78 animations Character. Accepté : les essais explicitement validés et les 81 BAM de paperdolls normaux de 6110.

Q8 contraint n’a pas été implémenté : la piste a été écartée le 2 octobre. Cela ne transforme pas son ancien prototype mesuré en un essai négatif. Les nouveaux profils V7 et les essais de contour V8 ont leurs propres états.

03 · Le moteur

Comment le jeu colorie la guerrière

Première question : que fait exactement le jeu quand il colorie un personnage ? La réponse n'a pas été cherchée dans une documentation, mais lue dans le programme lui-même.

Le but

Connaître la règle du jeu, au sens propre. Pour que le sprite HD réagisse comme l'original aux couleurs, aux sorts et à l'éclairage, il faut savoir comment le moteur fabrique ses 256 couleurs.

La recherche

Désassemblage du programme (lecture de ses instructions machine), recherche des fichiers qu'il ouvre, relecture du code du module du projet. Astra a désassemblé le programme lui-même, Opus partait d'un audit antérieur du projet ; la relecture finale a revérifié les adresses.

La trouvaille

Sept « pots de peinture » de 12 nuances, plus 21 mélanges de deux pots calculés par simple moyenne. Aucune case libre sur le corps. Et le module du projet récupère déjà ces 256 couleurs au bon moment.

Image mentale

Un coloriage numéroté où les numéros 4 à 15 veulent dire « métal, du plus clair au plus sombre », 16 à 27 « couleur mineure », et ainsi de suite. Avant chaque image, le jeu remplit sept rangées de 12 pots avec les teintes choisies, puis prépare 21 rangées de 8 pots intermédiaires en mélangeant moitié-moitié deux rangées. Le dessin, lui, ne change jamais : seuls les pots changent.

Vérifié sur BaldurReal.exe 2.7.3.0 (SHA-256 b51093a4…) : la chaîne MPALETTE y figure une fois, RANGES12 jamais. Les deux fichiers sont identiques octet pour octet, ce qui explique que les essais hors jeu, faits avec l'un ou l'autre, restent justes.

  1. 1La fiche du personnage fixe sept couleurs. Métal, couleur mineure, couleur majeure, peau, cuir, armure, cheveux. Le joueur en choisit quatre (cheveux, peau, majeure, mineure) ; le reste vient de la classe et des objets.Fichier CRE : 7 couleurs.
  2. 2Les objets portés imposent les leurs. Une armure de plates, par exemple, règle l'armure, le cuir et le métal du corps. Chaque objet dit quelle couche il recolore et quelle gamme il change.Objets (ITM) : opcode 7, param2 = 0xPR — P : 0 corps, 1 arme, 2 bouclier / main gauche, 3 casque ; R : gamme 0 à 6. Ex. PLAT01 : armure 27, cuir 23, métal 30.
  3. 3Le jeu va chercher chaque gamme dans son nuancier. MPALETTE.BMP est une image de 256 lignes de 12 couleurs. Pour chacune des sept gammes, le jeu recopie la ligne demandée dans la palette du personnage.SetRange (RVA 0x4221C0) copie une ligne de MPALETTE vers les indices 4+12r … 15+12r.
  4. 4Il applique les effets du moment. Teinte d'un sort, lumière, gris de la pause, pétrification, lueur d'une arme magique : tout cela modifie les 84 nuances (7 gammes × 12).Realize applique teinte, lumière, gris de pause, pétrification, lueurs aux 84 nuances.
  5. 5Il calcule les mélanges. Pour chacune des 21 paires possibles de gammes (métal et peau, cuir et armure…), il fabrique 8 couleurs intermédiaires : la moyenne, arrondie à l'entier inférieur, des nuances 2 à 9 des deux gammes. Elles servent aux pixels à cheval sur deux matériaux.Les 21 paires (RVA 0x421F7B) : P[88+8k+j] = (A[j+2] + B[j+2]) >> 1, octet par octet — ni lumière linéaire, ni OKLab.
  6. 6Quatre numéros ont un rôle à part. Le 0 est transparent, le 1 est l'ombre portée (un noir semi-transparent), les 2 et 3 sont des noirs réservés.0 transparent (forcé à 0 par le DLL), 1 ombre à alpha partiel, 2–3 noirs réservés (2 = marqueur des frames 1×1).
  7. 7Le module du projet prend le relais. Juste après ce calcul, il copie les 256 couleurs de chaque couche, fabrique l'image HD de la couche avec ces couleurs, empile les couches dans le même ordre que le jeu, puis lui rend une seule image à afficher.Le DLL IEE capture P[256] par cellule au retour de Realize, reconstruit chaque couche en x2/x4, compose dans l'ordre natif (tout pixel non nul écrase), puis le jeu dessine une texture.

Explorateur de palette réelle

À vous de jouer : l’explorateur reproduit les couleurs RGB de la palette neutre à partir de MPALETTE.BMP et de la formule du moteur. Choisissez une palette de l’étude, tapez un numéro de ligne ou cliquez dans le nuancier : les mélanges suivent. Survolez ou touchez une case pour savoir ce qu’elle représente. Les effets, l’éclairage et le rangement natif des octets ne sont pas simulés ici ; dans le jeu, le module capture la palette effectivement réalisée.

Le nuancier du jeu · 256 gammes en colonnes, 12 nuances chacune, du clair (haut) au sombre (bas)
Un clic dans le nuancier change la gamme…
Palettes de l'étude
Survolez une case.
7 gammes × 12 nuances · indices 4 à 87
Les 256 indices
21 paires × 8 · indices 88 à 255

Les palettes : REF est la référence du pipeline de production ; B et C ont servi au réglage des méthodes ; D et E à leur validation ; « contrast » et « pale » sont les profils de GPT 6-Astra ; « Défaut guerrière » donne les couleurs d'origine d'une guerrière humaine dans le jeu.

Couleurs fixes

Aucune sur le corps

Peut-on réserver une couleur qui ne bouge jamais ? Sur le corps, non : toutes les cases suivent un choix de couleur. Sur un équipement, oui en théorie : cinq lignes du nuancier sont d'une seule teinte. Si un objet n'utilise pas l'un de ses canaux, son fichier peut y fixer l'une de ces lignes. Mais il faudrait modifier des fichiers d'objets partagés.

Pour l'équipement seulement : les lignes 74 blanc, 75 noir, 76–78 rouge, vert, bleu sont constantes (revérifié). Un canal réellement inutilisé peut y être fixé par l'ITM. Option intrusive, hors premier prototype.
Ce que la capture couvre

Effets de palette : oui

En copiant les couleurs après le calcul du jeu, le module hérite de tout ce qui passe par la palette. Ce que le jeu applique après coup, en revanche, lui échappe et devra être testé en jeu.

Couverts : choix du joueur, objets, RANDCOLR résolu (couleurs tirées au hasard), effets de palette et mélanges recalculés. Pas couverts : teinte post-palette, invisibilité, flou, sélection, occlusion. À tester séparément.
Faux oracles

Near Infinity, GemRB

Deux outils de référence de la communauté, un éditeur de fichiers et un moteur libre, ne colorient pas exactement comme le jeu. Excellents pour l'inventaire et les cycles, jamais comme étalon de pixels.

Near Infinity échantillonne les mélanges sur les nuances 0,1,3,4,6,7,9,10 ; GemRB copie des sous-gammes.
04 · Le vrai goulot

Pourquoi 12 nuances ne suffisent pas en HD

Douze nuances par matériau, c'est un escalier de douze marches pour aller du clair au sombre. Sur un petit sprite, on ne voit pas les marches. En HD, quand le réseau dessine une pente douce, il faut l'arrondir à la marche la plus proche : le dégradé devient des bandes.

Le but

Comprendre d'où viennent les bandes et les aplats qui apparaissent quand on ramène une image HD aux couleurs du jeu.

La recherche

Opus a mesuré l'écart de couleur entre nuances voisines dans les 256 gammes du jeu (expérience E1). Astra a testé ce que donnerait un nuancier aux marches régulières.

La trouvaille

Entre deux nuances voisines, l'écart vaut deux à cinq fois ce que l'œil distingue, et les marches sont très inégales. Le problème n'est pas de mal choisir la marche : il n'y a pas assez de marches.

Les mesures. Pas médian entre deux nuances voisines : 0,055 en OKLab, une échelle de couleurs calée sur la perception, soit deux à cinq seuils de perception. Les pas sont très irréguliers : dans le métal 30, trois fois plus grands dans les clairs (0,10 à 0,13) que dans les sombres (0,03 à 0,05). Dans une gamme type, la plus grande marche est 2,8 fois plus haute que la plus petite ; dans une gamme sur dix, plus de 9 fois. Invisibles en x1, ces marches deviennent des bandes quand ReboutCX produit un dégradé continu.

Un même dégradé, quatre façons de le rendre

La gamme affichée est celle choisie dans l’explorateur de la section 03. Première bande : le dégradé continu que dessine le réseau. Deuxième : les 12 marches natives. Troisième : la solution fractionnaire, huit positions par marche. Quatrième : le tramage, qui alterne deux nuances en damier pour simuler l’intermédiaire.

Entre deux nuances : le huitième

C'est toute l'idée de l'étude, en un curseur. Le fichier HD n'enregistre plus seulement « nuance n° I », mais « nuance n° I, avancée de F huitièmes vers la suivante ». Le module du jeu fait le mélange avec les couleurs du moment : aucune couleur nouvelle n'est à choisir, le joueur garde ses 12 nuances.

Les huit positions entre ces deux nuances, puis la nuance suivante
Gammes vanilla et redistribution à écarts égaux
Essai de GPT 6-Astra (l'image porte son étiquette d'origine « Codex ») : pour sept gammes, la ligne du haut est celle du jeu, celle du bas la même gamme redistribuée à longueur d'arc égale, c'est-à-dire avec des marches de même hauteur. Le coefficient de variation, qui mesure l'irrégularité, passe de 0,15–0,47 à 0,013–0,027, mais 2 437 positions sur 3 072 changent (79,3 %, revérifié). Un diagnostic, pas une recette : la fraction comble déjà les grands pas sans toucher aux couleurs vanilla.

Ce que montre la démonstration. « 12 nuances » représente la limite native et la référence Q0 de l’étude. « Sous-nuances 1/8 » représente le V6 désormais implémenté : 89 positions par gamme (11 intervalles × 8, plus la dernière nuance), sans nouvelle couleur à choisir pour le joueur. Le Bayer imite le dégradé avec une trame. Les huit valeurs de F demandent logiquement 3 bits, mais le fichier courant les stocke dans des octets.

Lignes à part. Quelques lignes du nuancier ne vont pas sagement du clair au sombre, d'autres répètent la même couleur. Non monotones : 197, 198, 199, 204, 212, 213, 221, 253, 255. RGB répétés : 74–78, 222, 225. Ce sont des cas à interpréter, pas des erreurs à corriger en masse.

Décision. Ne jamais réécrire MPALETTE : le changement serait global, pour tous les personnages, objets et mods.

05 · Inventaire

Ce qu'il faut réellement produire

Deux comptages répondaient à deux questions : l'index du dépôt (656 BAM monde) et le stock vanilla complet recensé par GPT 6-Astra (774 BAM). Ils se réconcilient exactement, revérifiés sur le CSV.

Le but

Savoir combien de fichiers il faudra traiter pour une seule guerrière, et lesquels ne servent à rien, avant de lancer des heures de calcul.

La recherche

Astra a parcouru toutes les archives du jeu et listé chaque fichier d'animation et chaque objet compatible. Opus partait de l'index que le projet tient déjà. Les deux totaux différaient.

La trouvaille

Les deux comptes étaient justes : ils ne comptaient pas la même chose. 774 fichiers existent dans le jeu, 656 concernent le personnage dans le monde, 628 sont réellement utiles à une guerrière humaine.

En clair

Un personnage n'est pas une image, mais une pile de calques animés : le corps (qui change selon l'armure portée), l'arme, le bouclier ou la seconde arme, le casque. Chaque calque a ses fichiers d'animation, les BAM, un par type d'action (marcher, frapper, lancer un sort…). Chaque BAM contient des cycles, c'est-à-dire une animation vue sous un angle, eux-mêmes faits de frames, les images successives.

Corps

92 BAM

Quatre versions du corps, une par niveau d'armure, chacune en 23 fichiers d'action (4 × 23 = 92).

CHFB1 sans armure, CHFB2 cuir, CHFB3 mailles, CHFF4 plates (le préfixe change au niveau 4). 23 suffixes chacun.
Armes

166 + 72

166 fichiers pour l'arme tenue en main droite, 72 pour celle tenue en main gauche (combat à deux armes).

Main droite et main gauche (WQN…OA7/OA8/OA9/OG1). Overlays non scindés : leur G1 regroupe les états.
Boucliers

60 BAM

Douze familles de boucliers. Une treizième existe dans le jeu, mais aucun objet ne l'utilise.

Familles C0–C7, D1–D4. D0 (5 BAM) n'a aucun objet.
Casques

238 BAM

Les casques portables. Deux familles rangées parmi eux n'en sont pas : des attaques de créatures, et des ailes interdites aux humains.

H0–H5, J0–JC. H6 = attaques de créature (59 ITM), ZW = ailes interdites aux humains.
774 stock vanilla = 656 index du dépôt
              + 85 paperdolls (4 corps CHFF*INV, 81 WPN*INV/OIN)
              + 33 stock monde (D0 : 5, H3/H4 : 28)

656 index  = 628 utiles + 14 ZW + 14 H6

628 utiles = 92 corps + 166 armes + 72 main gauche
            + 60 boucliers + 238 casques

frames : 178 360 (index) · 185 335 (stock) · 153 422 > 1 px

Lecture : le jeu contient 774 fichiers pour cette guerrière. 85 sont des paperdolls, la grande figurine de l'écran d'inventaire, qui relève d'un chantier à part. 33 existent dans le jeu mais aucun objet ne les appelle. Restent les 656 de l'index du dépôt (178 360 frames), dont 14 fichiers d'ailes interdites aux humains et 14 attaques de créature : d'où 628 fichiers utiles. Beaucoup de frames sont des bouche-trous (voir plus bas) : sur les 185 335 du stock complet, 153 422 font plus d'un pixel.

SuffixeCyclesAction
G11 · G10–8 · 9–17marche · garde 1 main
G12 · G1318–26 · 27–35repos · garde 2 mains
G14 · G15 · G1636–62touché · mort · au sol
G17 · G18 · G1963–98repos · repos · sommeil/relevé
A1–A90–8attaques 1 main, 2 mains, deux armes, lancer
SA · SS · SX0–8arc · fronde · arbalète
CA0–714 variantes de sort

Le suffixe est la fin du nom de fichier : CHFF4 + G11 = corps en plates qui marche. Les cycles sont numérotés par direction : 9 directions par action, d'où les tranches de 9 (0–8, 9–17…).

Directions

9 + 7 miroirs

Le personnage regarde dans 16 directions. Neuf seulement sont dessinées ; les sept orientations vers l'est sont obtenues en retournant l'image comme dans un miroir. Une étude disait « 9 + 5 » : corrigé.

S à N stockées, sept orientations est obtenues par miroir. Pas « 9 + 5 ».
Placeholders

Frames 1×1, indice 2

Beaucoup de frames sont des bouche-trous d'un seul pixel noir. Le jeu compte dessus : on les garde telles quelles, on ne leur applique simplement pas l'agrandissement.

CHFB1G11 : 846 entrées, 90 frames réelles. Garder frame, lookup, centre, cycle ; ne sauter que l'inférence.
Partages

Router, pas remplacer

Les mêmes fichiers servent à plusieurs personnages. On ne remplace donc jamais un fichier du jeu : le module du projet sait déjà aiguiller, animation par animation, vers la bonne version HD.

CHFB1–3 sert 6 animations, WQN* 13. Le DLL route déjà par ID d'animation → memberships → composant.
05 · Complément visuel

Comment les équipements s’assemblent

Une guerrière équipée est composée de plusieurs images indépendantes. Le corps, l’arme, le bouclier et le casque n’ont ni la même taille ni forcément le même centre dans leur fichier. Ils se rejoignent grâce à leurs points d’ancrage, puis suivent les cycles et la direction prévus par le moteur.

Corps · xBR x2
Corps
Arme · xBR x2
Arme
Bouclier · xBR x2
Bouclier
Casque · xBR x2
Casque
Images réelles reprises de l’ancienne page sprite : exemples xBR x2 en fausses couleurs. Elles illustrent les composants, pas une pose synchronisée ni le nouveau rendu K6.
1 · Choisir le corpsSans armure, cuir, mailles ou plates : CHFB1, CHFB2, CHFB3 ou CHFF4. L’armure change le corps de base.
2 · Aligner les calquesLes centres natifs placent chaque image sur la même ancre. Des fichiers de tailles différentes peuvent ainsi s’emboîter.
3 · Respecter le moteurDirection, action, miroir et ordre des couches restent ceux du jeu. Une arme peut passer devant ou derrière le corps selon l’orientation.

Chaque couche est coloriée avec sa propre palette réalisée, puis composée. Le bouclier occupe la voie de la main gauche ; le combat à deux armes utilise cette voie pour une autre arme. Une couche absente reste absente. La mise à l’échelle conserve la géométrie et les ancrages natifs : la texture contient davantage de pixels, mais le personnage occupe la même place dans le monde.

Simulation hors jeu

Corps, casque, bouclier et arme séparés, centres natifs et assemblage synchronisé hors jeu
Simulation hors jeu · Quatre calques Q3m K6 x2 d’une même pose, alignés à partir de leurs centres natifs. Le casque peut avoir son repère hors de son rectangle. Palette neutre commune et ordre fixe pour cette démonstration ; les ordres dépendant de la direction, les effets et les occultations du moteur ne sont pas reproduits.
Explorer les calques, les poses et les couleurs

Origine du calque = référence commune − centre × zoom

Affichage pédagogique au zoom natif ×3 ; pixels du x2 agrandis sans interpolation. Trois poses réellement synchronisées sont disponibles. Les effets, l’éclairage et les occultations du moteur ne sont pas simulés.

Inventaire et production ne désignent pas le même périmètre. Les 628 BAM restent le sous-ensemble utile décrit plus haut. La production complète a couvert les 656 BAM de l’index, soit 178 360 frames. Pour l’interface, 81 BAM normaux ont été retenus et acceptés (4 corps + 77 équipements, 163 frames), parmi les 85 fichiers UI recensés à l’origine.

La figurine d’inventaire a sa propre voie

Aperçu préparatoire : paperdoll natif à gauche, Q3m x2 à droite
Aperçu préparatoire CHFF1INV : natif agrandi en Nearest à gauche, Q3m K6 x2 à droite, palette DEFAULT. Deux morceaux sont placés avec leurs centres natifs. L’alpha d’ombre 128 de cet aperçu est diagnostique ; cette image n’est pas une capture UI en jeu et ne porte pas la validation du lot final.

La production UI complète et sa validation sont postérieures à cet aperçu. Elles concernent les 81 BAM normaux de 6110 et conservent Nearest ; elles ne valident pas automatiquement les figurines des autres avatars.

Planches de recherche du 29 septembre, conservées. xBR reste un guide de structure pour Q3m ; ReboutCX produit les cibles de modelé. Le rendu livré est ensuite réencodé, et non la sortie RGB brute du modèle.
06 · Quatre agrandissements réels

xBR et ReboutCX, en x2 et en x4

GPT 6-Astra a calculé les quatre variantes sur 60 vraies frames : quatre corps, plus un cycle d'attaque complet (14 images) pour le corps, l'épée, le bouclier et le casque. Les planches sont agrandies à 8 pixels d'écran par pixel source.

Le but

Voir concrètement ce qu'apporte chaque technique d'agrandissement, et ce que l'on perd quand il faut revenir aux couleurs du jeu.

La recherche

Quatre versions réellement calculées (xBR x2, xBR x4, ReboutCX x2, ReboutCX x4), puis un test décisif : refaire le calcul du réseau avec d'autres couleurs, et compter ce qui change.

La trouvaille

Le réseau ne dessine pas les mêmes ombres selon les couleurs qu'on lui montre : 20 à 44 % des numéros changent. Une recette réglée sous une seule palette ne peut donc pas convenir à toutes.

Famille 1

xBR, un algorithme à règles

Il examine chaque pixel et ses voisins, et arrondit les escaliers des contours selon des règles fixes. Il ne crée aucune couleur : chaque pixel agrandi reprend le numéro d'un pixel d'origine. Même entrée, même résultat, à chaque fois.

xBR choisit la géométrie sur les couleurs « clown » (les fausses couleurs de travail du fichier) et transporte les indices.
Famille 2

ReboutCX, un réseau de neurones

Un programme entraîné à redessiner des images en quatre fois plus grand. Il ajoute du modelé : volumes, reflets, dégradés. Mais il reçoit et rend une image déjà coloriée, sans rien savoir des numéros, des matériaux ni de la transparence.

ReboutCX traite un aperçu recoloré et récupère l'alpha et les classes du guide xBR de même échelle.
Trois sources, trois rôles

Le fichier d'origine dit la structure

Cycles, ordre des images, points d'ancrage, bouche-trous : repris tels quels du BAM, jamais recalculés.

Trois sources, trois rôles

xBR dit le matériau

Transparence, ombre et classe (le matériau) de chaque pixel HD viennent de la version xBR de même taille, qui sert de guide.

Trois sources, trois rôles

ReboutCX dit le modelé

Le réseau fournit volumes et dégradés, et rien d'autre : jamais la transparence, jamais le matériau d'un pixel.

Élément
Vue
Planche de comparaison de GPT 6-Astra

Les vues « Inférence » n'existent que pour le corps sans armure, le corps en plates et le casque : ce sont les trois éléments du test de sensibilité ci-dessous.

xBR x2

Témoin exact

Couleurs source exactes, contours améliorés, marches restantes. Aucune nuance nouvelle. Voie acceptée en QA pour les personnages jouables (avec le filtre d'affichage Catmull-Rom).

xBR x4 direct

Témoin fin

Vrai xbr4x, pas deux passes x2. Courbes plus fines, mêmes couleurs : peu d'intérêt seul.

ReboutCX x2

Réseau x4 + BOX

Il n'existe pas de modèle x2 : le résultat x4 est réduit par moyenne de blocs (BOX), en valeurs à virgule, avant tout arrondi. Surfaces plus régulières, petits reflets parfois lissés.

ReboutCX x4

Master de recherche

La version de travail de référence. RRDBNet 64nf/23nb, 16,7 M paramètres, RGB sans alpha ni mémoire temporelle : il traite chaque image seule. Provenance et licence inconnues, à éclaircir avant toute diffusion.

Et si le joueur change de couleurs ?

Palette
Même image, recolorée sous une autre palette
Cycle d'attaque, vanilla et quatre upscales
Cycle d'attaque complet CHFB1A1, 100 ms par image (cadence choisie pour comparer, pas celle du jeu). Les couches d'équipement ont été évaluées séparément.

La découverte qui oriente tout. Recolorier les numéros marche, comme le montre la planche ci-dessus. Mais recolorier n'est pas redessiner. Refaire l'inférence ReboutCX sous une autre palette, au lieu de recolorer le résultat, change 31,99 % / 44,39 % des indices du corps, 20,26 % / 36,28 % de l'armure lourde, 30,91 % / 37,04 % du casque (profils « contrast » / « pale »). Le réseau n'ombre pas pareil selon les couleurs qu'il reçoit.

Conserver les classes garde la recoloration, mais pas un bon modelé sous toutes les couleurs. D'où l'ajustement multi-palettes : choisir les numéros pour qu'ils restent bons sous plusieurs jeux de couleurs à la fois.

Candidats limités à la frame source. La référence Q0 de cette étude n’autorisait que les nuances présentes dans l’image d’origine. Autoriser toute la classe ne gagnait que 5,9 % (x2) et 6,2 % (x4) d’erreur. Cette conclusion reste celle de cet essai : le goulot principal était la discrétisation à 12 niveaux. Le Q3m retenu explore ensuite les positions fractionnaires dans la classe autorisée, sous plusieurs palettes.

Pour les curieux : sur la machine du projet (RTX 5090), le réseau se chargeait en 3,3 s et agrandissait les 60 frames en x4 en 2,6 s ; xBR les traitait en 0,12 s (x2) et 0,14 s (x4). Une micro-mesure sur ce petit échantillon, pas un débit de production.

07 · Méthodes testées

Ramener le modèle vers une palette vivante

Toutes partent de la même sortie ReboutCX et des mêmes classes (guide xBR). Seule change la façon de revenir aux couleurs dynamiques. Verdicts après toutes les revues.

Le but

Trouver la meilleure façon de traduire l'image du réseau, faite de milliers de teintes, en numéros que le jeu sait recolorier.

La recherche

Dix façons de faire mises en concurrence sur les mêmes images, avec le même point de départ. Seule l'étape du retour à la palette change.

La trouvaille

Le tramage, le réglage sur une seule palette et le reclassement en HD sont écartés. Q3m est retenu et réalisé avec K6. Le prototype Q8 reste expliqué et visible dans l’étude ; sa variante contrainte Q8c a été écartée sans implémentation le 2 octobre.

Image mentale

Le réseau peint avec une infinité de tubes ; le jeu n'a que 12 crayons par matériau. Palettiser, c'est décider, pour chaque pixel, quel crayon imite le mieux la peinture. Les méthodes diffèrent sur trois points : quels crayons sont autorisés ; si l'on peut simuler un ton intermédiaire en alternant deux crayons (tramage) ou en les mélangeant vraiment (fraction) ; et sous combien de jeux de couleurs on vérifie que le choix reste bon.

CodeMéthodeStockeRuntimeVerdict final
xBRxBR direct, provenance d'indiceSans réseau de neurones : l'agrandissement à règles, qui garde les numéros d'origine.indiceactuelvoie acceptée · option
Q0Référence Q0 de l’étude : nuance la plus proche parmi celles de la frame x1, palette REFArrondir chaque pixel à une nuance présente dans l’image d’origine, en jugeant sous une seule palette.indiceactuelréférence historique
Q1Idem, toute la classePareil, mais les 12 nuances du matériau sont permises.indicemasque de dépendancesgain nul en validation
Q2Bayer 4×4 ancré au centre BAMTramage : alterner deux nuances selon un damier fixe pour simuler l'intermédiaire. Le damier est accroché au personnage pour ne pas glisser quand il bouge.indiceactuelrejeté par défaut
Q7Diffusion d'erreur dans la gammeAutre tramage : l'erreur d'arrondi d'un pixel est reportée sur ses voisins. Joli sur une image fixe, instable en animation.indiceactuelrejeté
Q6Un indice choisi sur K palettes à la foisToujours un seul numéro par pixel, mais choisi pour être le moins mauvais sous plusieurs palettes.indiceV6 sans fractionétape optionnelle
Q3Fraction ajustée sur REF seule (= interpolation d'Astra)Sous-nuances : chaque pixel se place entre deux nuances voisines, mais la position est réglée sous une seule palette. Astra avait eu la même idée de son côté.indice + fractionV6surapprend la palette
Q3mFraction 3 bits ajustée sur K palettesSous-nuances par huitièmes, réglées pour rester justes sous plusieurs palettes. La méthode retenue.indice + fractionV6retenu · K6 implémenté
Q5Q3m + classe réestimée en HDQ3m, en laissant le réseau redécider du matériau de certains pixels.indice + fractionV6aucun gain hors réglage
Q8Q3m + mélange pondéré de deux classes aux frontièresQ3m, plus un mélange dosé de deux matériaux pour les pixels situés à leur frontière.+ plan frontièreprototype hors jeuQ8c écarté sans implémentation

« Stocke » : les informations nécessaires par pixel. Les voies indiquées « actuel » sont celles du runtime au moment de l’étude ; le V6 est maintenant implémenté. K vaut 3 dans E3b (REF, B, C), puis 6 dans le choix P1. Le prototype E3b a été calculé avec des fractions 4 bits ; la vérification 3 bits et le V6 par huitièmes sont distincts. Ablation : retirer un ingrédient pour mesurer son apport.

Étude des 29–30 septembre : images, chiffres et protocole d’origine conservés. Les mentions Q0 « actuel » désignent la référence de cette étude. Les nouveaux résultats K6 sont présentés séparément en section 12.
08 · Comparateur E3b

Glisser, comparer

Composite corps en plates CHFF4 + casque HELM01 + bouclier ISHLD03 + épée BDSW1H06, face sud. Réglage sur REF, B, C ; D et E n'ont servi à aucun réglage (E ne diffère de REF que par l'armure).

Le but

Juger sur pièce. Les chiffres disent ce qui est proche du dessin du réseau ; seuls les yeux disent ce qui est beau.

La recherche

Les images de l'expérience E3b : la guerrière complète, au repos et en marche, rendue par chaque méthode sous quatre jeux de couleurs.

La trouvaille

Sous la palette de réglage, tout se ressemble. Sous une autre, la méthode actuelle laisse des liserés clairs autour des plaques d'armure ; Q3m et Q8 les effacent.

Mode d'emploi : choisissez une méthode à gauche, une à droite, puis faites glisser la séparation. Changez de palette pour voir ce qui se passe quand le joueur choisit d'autres couleurs. « Jeu d'origine » montre l'image de départ, agrandie sans retouche.

Palette
Pose
Variante de gauche Variante de droite
  • Q0 de l’étude sous B, D et E : liserés clairs ou orangés autour des plaques du torse et des jambières. Les mélanges 88–255 choisis sous REF deviennent voyants sous une autre palette.PourquoiAux frontières entre deux matériaux, la méthode actuelle choisit volontiers une couleur « mélange ». Sous la palette de réglage, ce mélange tombe pile sur la bonne teinte. Si le joueur change l'un des deux matériaux, le mélange change aussi et ne ressemble plus au dessin du réseau.
  • Q3m garde des volumes lisses ; Q8 fait disparaître presque tous les liserés. C'est la variante la plus proche de la sortie du modèle.
  • Bayer : trame régulière sur les grandes plaques. Diffusion : grain qui change d'une image à l'autre.
  • La sortie brute du modèle est recalculée pour chaque palette : une cible, jamais atteignable en jeu, où une seule version des indices sert toutes les couleurs du joueur.
  • Le jeu d'origine rappelle le point de départ : mêmes numéros, mêmes couleurs, quatre fois moins de pixels dans chaque direction. Tuile ajoutée pour cette page, sans aucun calcul d'IA.
Palette
Pose
Planche des variantes
Ligne 1 : xBR x2, xBR x4, ReboutCX x2 de l’étude, ReboutCX x4 de l’étude, Bayer x4. Ligne 2 : Q6 x4, Q8 x2, Q3 x4, Q8 x4, sortie brute du modèle. L'ordre des couches de l'aperçu est approximatif. Sur l'image, « RCX » abrège ReboutCX, « frac+bord » signifie fraction + frontières, « GT » (ground truth) désigne la sortie du modèle.
Détail du torse
Étude des 29–30 septembre : images, chiffres et protocole d’origine conservés. Les mentions Q0 « actuel » désignent la référence de cette étude. Les nouveaux résultats K6 sont présentés séparément en section 12.
09 · Validation croisée E5

Les méthodes d'Opus sur le terrain d'Astra

Cycle d'attaque complet (14 images) de CHFB1A1, WQNS0A1, WQNC0A1, WQNJ6A1. Validation sur D et les profils d'Astra « contrast » et « pale ». L'interpolation d'Astra est exécutée avec sa propre fonction, importée en lecture seule.

Le but

Départager les deux études sans avantage du terrain : une méthode peut briller sur les images choisies par son auteur et décevoir ailleurs.

La recherche

Pendant sa relecture croisée, Opus rejoue ses méthodes sur les images et les palettes d'Astra (un coup d'épée complet, quatre couches), et fait tourner la méthode d'Astra avec le code d'Astra, sans y toucher.

La trouvaille

Les deux modèles avaient eu la même idée de départ, avec les mêmes résultats. Ce qui fait la différence, c'est le réglage sur plusieurs palettes : −23 % d'écart face à la méthode actuelle, −20 % face à l'interpolation d'Astra.

Palette
Corps CHFB1A1 image 6, six variantes

Q3 et l'interpolation d'Astra sont la même idée : une fraction réglée sous une seule palette. Mêmes chiffres (47,2 et 47,0), excellents sous leur palette, faibles ailleurs.

Q8 : −23 % face au pipeline actuel, −20 % face à Astra ; sur D seule, 58,1 → 43,6.

sRGB ou lumière linéaire pour interpoler : 37,8 contre 38,1. Aucune différence utile : le runtime interpolera en octets sRGB, plus simple et exact au bit.En clairIl y a deux façons de mélanger deux couleurs : moyenner directement les nombres stockés (sRGB), ou les convertir d'abord en quantité de lumière (« linéaire »), plus juste physiquement. Ici, aucune différence visible : on garde la plus simple, qui donne en plus exactement le même résultat sur toutes les machines.

Limite : E5 ne contient pas Q3m, donc aucune ablation des frontières sur ce corpus.

Interpolation d'Astra réglée sur une palette, rendue sous trois palettes
Figure de GPT 6-Astra : interpolation réglée sous une seule palette, rendue sous trois. Sous « contrast » et « pale », des liserés gris et verts restent aux frontières des gammes : c'est ce que corrige l'ajustement multi-palettes.
Étude des 29–30 septembre : images, chiffres et protocole d’origine conservés. Les mentions Q0 « actuel » désignent la référence de cette étude. Les nouveaux résultats K6 sont présentés séparément en section 12.
10 · Stabilité temporelle

En mouvement, et une erreur de signe

Une image fixe peut être superbe et l'animation pénible : si des pixels changent de nuance sans raison d'une image à l'autre, la surface « grouille ». C'est aussi dans cette mesure que la relecture croisée a trouvé l'erreur la plus instructive de l'étude.

Le but

Mesurer le grouillement, car c'est en mouvement que le joueur voit son personnage.

La recherche

Superposer deux images successives d'une animation, repérer les pixels que le réseau dessine presque à l'identique, et compter ceux dont la couleur restituée saute quand même.

La trouvaille

Avec les sous-nuances, le grouillement du corps tombe de 14,1 % à 5,7 % (4,8 % avec Q8). La diffusion d'erreur le double. Et la mesure elle-même contenait une erreur, trouvée par l'autre modèle.

L'erreur de signe, racontée

Pour comparer deux images d'une animation, il faut d'abord les superposer correctement. Chaque image a son point d'ancrage, et ce point n'est pas au même endroit d'une image à l'autre. Le script d'Opus calculait le décalage dans le mauvais sens : un simple signe inversé. Tant que l'ancre ne bougeait pas, aucune conséquence ; dès qu'elle bougeait, on comparait des pixels qui ne se correspondaient pas. Or elle bougeait souvent : sur les 19 transitions du repos, 9 fois pour le corps, 15 pour le casque, 10 pour le bouclier et 19 pour l'arme.

GPT 6-Astra l'a trouvé en refaisant les calculs, l'a prouvé par un test artificiel (une même image recadrée), puis a tout recalculé. La relecture finale a retrouvé la même erreur dans l'expérience E5.

Astra a trouvé que l'alignement des images comparait des positions différentes dès que l'ancre bougeait : ox = (centre_b − centre_a) × échelle au lieu de (centre_a − centre_b). Test synthétique : 5 comparaisons fausses sur 5 avant, 0 sur 6 après. Les chiffres ci-dessous sont recalculés.
Cycle de repos, quatre méthodes
Repos, 20 changements de pose, palette B, x4. De gauche à droite : Q0 de l’étude, Bayer, diffusion d'erreur, Q8. Regardez les grandes plaques : c'est là que le grain apparaît ou non.

Part des pixels immobiles (cible Δ < 0,01) dont la sortie change de plus de 0,02. Toujours publier l'agrégation : sur les 4 couches non pondérées, Q8 fait 13,6 → 10,0 % ; pondéré par pixels, 13,2 → 4,9 %.En clairUn pixel est « immobile » quand le réseau le dessine presque pareil sur les deux images ; il « scintille » si la couleur finale change quand même. Selon qu'on donne le même poids aux quatre couches ou qu'on pèse chacune par son nombre de pixels (le corps compte alors bien plus que le casque), Q8 passe de 13,6 à 10,0 %, ou de 13,2 à 4,9 %. Les deux sont vrais ; il faut toujours dire lequel on cite.

Pourquoi ça grouille

Décision nuance par nuance

Quand le modèle hésite entre deux nuances, une variation infime bascule des pixels entiers. Avec la fraction, la même hésitation ne coûte qu'un huitième de nuance.

Tramage

Bayer : non par défaut

Erreur pixel +6 à +10 %, trame visible. Après flou σ 0,5 (une image légèrement floutée, comme l'œil à distance), il fait mieux qu'aucun tramage (0,0125 contre 0,0139), mais l'interpolation fait mieux encore (0,0114). Bruit renouvelé à chaque image : interdit.

Limites

Pas de suivi de surface

Pixels alignés par ancre, ombre incluse, boucles et durées ignorées : si le bras bouge, la mesure ne le suit pas. L'attaque E5 a trop peu de pixels immobiles pour conclure. Il faut un flot restreint aux classes, c'est-à-dire suivre le mouvement de chaque matériau.

Cycle réel, stratégies de tramage
GPT 6-Astra, cycle réel de 14 images : changements d'indice 7,61 % avec un damier Bayer fixe, 8,23 % sans tramage, 32,65 % avec un bruit renouvelé à chaque image.
Même image répétée, bruit variable
GPT 6-Astra, même image répétée 14 fois : avec le damier Bayer fixe, 0 changement ; avec un bruit renouvelé, 30,06 % des pixels bougent alors que rien ne bouge.
Complément P1 · 30 septembre

La mesure temporelle a aussi été élargie

Sur les dix palettes de validation, en pondérant les pixels recolorables et en comparant les poses distinctes avec le raccord de boucle, le taux de changements Q0 → Q3m K6 passe de 20,28 à 8,36 % en x2 et de 21,66 à 9,40 % en x4. L’agrégation non pondérée donne d’autres valeurs : 29,63 → 23,91 % et 29,07 → 24,01 %.

Ces mesures complètent les anciens graphiques ; leurs masques et agrégations diffèrent. L’alignement utilise toujours les ancrages, sans flot optique : le suivi des surfaces en mouvement et le timing réel en secondes ne sont pas démontrés par ce chiffre.

11 · Affichage

x2 ou x4 à l'écran

Le jeu garde la géométrie d’origine et affiche la texture à la taille du zoom. Au moment de l’étude, le runtime utilisait Nearest, Linear ou Catmull-Rom, sans mipmaps. Les essais suivants ont ajouté BOX et testé les mipmaps x4. Le choix Q3m retenu pour Character est x2 + BOX ; les simulations et l’essai Q0 plus anciens restent présentés ci-dessous.

Le but

Décider combien de pixels livrer. Quatre fois plus fin n'a d'intérêt que si l'écran peut le montrer.

La recherche

Une simulation de l’affichage à plusieurs zooms, puis l’essai Q0 du 26 septembre. La suite comprend les vidéos Q3m x2/x4 du 1er octobre et les essais BOX/mipmaps au zoom réellement utilisé.

La trouvaille

Le choix final des essais Q3m est x2 + BOX. Le x4 peut lisser les contours davantage, mais son rendu paraît plus « plastique ». Le x2 conserve une présence du pixel art plus naturelle. BOX a été préféré aux mipmaps lors du dézoom et le x2 réduit le travail de composition et le volume transféré.

En clair

Le sprite HD n'est pas affiché plus grand : il occupe la même place à l'écran, avec plus de pixels dedans. Selon le zoom choisi par le joueur, l'écran a parfois moins de pixels à offrir que l'image n'en contient, et il faut la réduire. Deux façons de faire : le plus proche voisin, qui prend un seul pixel de l'image pour chaque pixel d'écran, au risque d'en sauter (crénelage) ; ou la réduction d'aire, qui fait la moyenne des pixels couverts. Les mipmaps sont des copies réduites d'avance, où la carte graphique pioche selon la taille affichée.

Dans la simulation historique, Nearest prend un texel, Linear et Catmull-Rom reconstruisent localement l’image. Le filtre BOX ajouté ensuite mesure la surface de texture couverte par un pixel d’écran et en fait la moyenne. Il conserve le plus proche voisin quand la texture est agrandie. Les mipmaps x4 constituent un autre mode essayé, avec réduction trilineaire et agrandissement Nearest.

Chaque vignette montre à gauche le plus proche voisin, à droite une réduction d'aire. Le nombre mesure l'écart entre les deux : plus il est petit, moins le plus proche voisin abîme l'image.

Lecture corrigée. L'écart entre les deux méthodes ne désavantage le x4 qu'au zoom entier 2, où le x2 est exact par construction : chaque pixel x2 tombe alors pile sur un pixel d'écran. À 1,0, 1,3 et 3,0, le x4 crénelle moins que le x2. L'affirmation « x4 utile seulement dès zoom 3 » est retirée.

En jeu, le 26/09 : x4 ReboutCX sur tout 0x6110, en plus proche voisin, jugé « légèrement meilleur que x2 », 59,1–60 FPS, p95 16,8–17,3 ms (95 % des images calculées en moins de 17,3 millisecondes : aucune perte de fluidité), puis restauré en x2.

Essai x4 du 26/09x2x4
Indices non compressés947,6 Mo3 790,4 Mo
Registre compressé195,9 Mo309,6 Mo
Rapport—×1,58
Appréciationréférencelégèrement meilleur

Écart entre plus proche voisin et réduction d'aire pour toutes les combinaisons simulées, zooms 1,0 à 3,0 (plus petit = moins de crénelage). Au zoom 2,0, le x2 vaut 0 par construction ; à tous les autres zooms, le x4 fait mieux que le x2 pour chaque méthode.

x2 conservé pour la production Q3m ; BOX retenu pour l’affichage monde Character. Le x4 reste une échelle de recherche et de comparaison. Le tableau du 26 septembre décrit Q0 : son +58 % ne représente pas la taille de tous les nouveaux registres Q3m.Catmull-Rom conserve son ancienne validation xBR du 11 septembre. Le choix Q3m ultérieur est une décision distincte.
11 · Nouveaux essais · 1–2 octobre

BOX, mipmaps et Catmull-Rom : trois façons de filtrer

Au dézoom, plusieurs texels — les pixels de la texture — peuvent tenir dans un seul pixel d’écran. En choisir un seul peut faire disparaître une ligne fine ou la faire clignoter. Le filtrage détermine comment ces texels contribuent à la couleur affichée.

BOX

Moyenne des texels sous la surface couverte, pondérée par la portion de chacun. Au grossissement : Nearest.

Moyenne des texels sous la surface couverte, pondérée par la portion de chacun. Au grossissement : Nearest.

Mipmaps

Pyramide de textures : original, moitié, quart… Le GPU mélange les niveaux selon la réduction.

Pyramide de textures : original, moitié, quart… Le GPU mélange les niveaux selon la réduction.

Catmull-Rom

Interpolation cubique locale sur 4 × 4 voisins. Ce voisinage fixe ne moyenne pas toute une grande empreinte de réduction.

Interpolation cubique locale sur 4 × 4 voisins. Ce voisinage fixe ne moyenne pas toute une grande empreinte de réduction.

Schémas de principe, pas des captures comparatives. Les carrés représentent des texels ; la forme dorée de BOX montre une surface couverte non alignée sur leur grille.

Transparence et bords. BOX et les mipmaps essayés calculent les couleurs en alpha prémultiplié : les pixels transparents ne doivent pas apporter leur noir au contour. RGB est pondéré par l’alpha, puis la couleur est reconstituée. Dans le shader BOX, le filtre reste local à la texture de base ; aucune pyramide n’est conservée.

Pourquoi les mipmaps coûtaient davantage ici. Le sprite est recolorié et recomposé pendant la partie. Les niveaux réduits de l’essai x4 devaient donc être régénérés après les uploads, avec leurs masques. Ce coût dépend de cette implémentation dynamique : les mipmaps restent très utiles pour des textures statiques.

Session mesuréeComposition CPU / frameTransfert RGBA de base
x2 + BOX0.148 ms11.082 MB/s
x4 + BOX0.280 ms44.269 MB/s
x4 + mipmaps4.258 ms—

Courtes sessions indépendantes sur la scène Character étudiée, autour de 60 FPS ; mouvements et parcours de zoom non strictement identiques. L’upload est inclus dans la composition : les temps ne s’additionnent pas. Le trafic de base n’est pas une mesure de mémoire GPU ; aucun gain global de FPS n’en est déduit.

Résultat visuel. BOX a été préféré aux mipmaps à mesure que la caméra dézoome. Le choix retenu le 2 octobre est x2 + BOX, sans mipmaps : rendu jugé plus agréable et coût inférieur dans ces essais. Les paperdolls restent en Nearest, car leur affichage UI utilise une voie distincte. Les expérimentations ultérieures sur des monstres peuvent employer un autre filtre sans modifier cette décision Character.

Catmull-Rom testé. Ce filtre existait déjà et avait été accepté pour xBR. Pour le choix Q3m présenté ici, son lissage n’a pas paru aussi convaincant que BOX. Il reconstruit localement une image ; il ne remplace pas une moyenne de toute la surface couverte au fort dézoom. Aucun défaut précis ne lui est attribué sans comparaison contrôlée.

Simulation hors jeu

Simulation de Nearest, BOX, mipmaps et Catmull-Rom sur une même pose, avec loupes du casque
Simulation hors jeu · Même pose, texture x4, position et zoom pour Nearest, BOX, mipmaps et Catmull-Rom. Les loupes agrandissent les pixels déjà affichés. Les mipmaps sont modélisés sur CPU par des moyennes d’aire RGBA8 prémultipliées ; le noyau du pilote OpenGL et les temps GPU ne sont pas reproduits. Le choix Character acquis reste x2 + BOX.
Comparer les filtres ou les textures x2 / x4

BOX et Catmull-Rom suivent les formules du shader, couche par couche, avec alpha prémultiplié. La pyramide mipmap est un modèle CPU par moyennes d’aire RGBA8 : le noyau du pilote OpenGL n’est pas reproduit. Les marges transparentes sont supposées isolées. Les différences de précision GPU, de FPS et d’occlusion ne sont pas représentées.

La comparaison x2 / x4 utilise les véritables textures conservées, sans inventer de détail. Elle complète la vidéo déjà validée : le ressenti plus naturel du x2 et l’aspect parfois plastique du x4 restent des appréciations visuelles, pas des mesures calculées ici.

11 · Captures réelles · 1er octobre

Comparer x2 et x4 en mouvement

Le lecteur HTML déjà produit est intégré ci-dessous, avec ses deux MP4 originaux, sans réencodage supplémentaire. Faites glisser la séparation, ralentissez la lecture ou avancez image par image. Le zoom personnage ×3 agrandit la capture : il ne crée pas de détail.

Ouvrir le lecteur seul

Les vidéos sont en 2560 × 1440 à environ 59,94 images/s. L’alignement initial avance le x4 de dix images, soit 0,167 s, sur le guerrier sélectionné ; d’autres acteurs peuvent avoir des phases différentes. L’extrait commun dure environ 5,39 s et montre l’attente, pas toutes les actions ni tous les effets.

Pourquoi le x2 reste retenu. Le x4 peut lisser davantage certains contours, mais ce lissage peut donner aux sprites un aspect plus « plastique ». L’agrandissement ne peut pas retrouver avec certitude les détails absents de l’image d’origine. Le x2 conserve un rendu plus naturel et une légère présence du pixel art, jugée plus agréable à l’œil. Les essais x4 ont servi à comparer ; le x2 a été conservé comme échelle de production.

Détail du shader BOX : moyenne sur l’empreinte couverte en minification, Nearest en magnification. Le chemin actuel borne l’empreinte à 16 texels par axe ; au-delà, il revient à Nearest. Les essais de zoom P4 restent dans cette plage.

Étude des 29–30 septembre : images, chiffres et protocole d’origine conservés. Les mentions Q0 « actuel » désignent la référence de cette étude. Les nouveaux résultats K6 sont présentés séparément en section 12.
12 · Mesures E3b

Les chiffres

4 couches, repos sud (20 poses) et marche sud (10), 5 palettes. Écart = ΔE OKLab moyen ×1000 par rapport à la sortie du modèle sous la même palette. Plus court = mieux. Fidélité à une cible générée, pas beauté perçue.

Le but

Mettre un nombre sur chaque méthode, pour comparer autrement qu'à l'œil, et savoir si elle tient encore quand les couleurs changent.

La recherche

120 images (4 couches × 30 poses), 5 palettes, 10 méthodes, deux tailles. Trois palettes servent à régler les méthodes, deux à les vérifier.

La trouvaille

Q3m réduit l'écart de 14,1 % sur les palettes de validation, Q8 de 18,4 %. Les sous-nuances réglées sur plusieurs palettes font 77 % du chemin ; les frontières ajoutent environ 5 %.

Comment lire · 1

L'écart

Pour chaque pixel, la distance entre la couleur que le réseau avait dessinée et celle que le jeu affichera, mesurée en OKLab. On fait la moyenne et on multiplie par 1000 pour éviter les zéros : 40 signifie 0,040, une différence que l'œil peut percevoir. Plus la barre est courte, mieux c'est.

Comment lire · 2

Réglage et validation

Comme un élève qui révise sur des annales, une méthode peut apprendre par cœur les palettes qui ont servi à la régler (REF, B, C). On la juge donc aussi sur des palettes mises de côté (D et E). Excellente au réglage et médiocre en validation, elle a surappris.

Comment lire · 3

La limite

On mesure la fidélité au dessin du réseau, pas la beauté. Si le réseau dessine mal, lui être fidèle n'est pas une qualité. D'où l'importance de l'essai en jeu.

Les sept numéros sont, dans l'ordre : métal, mineure, majeure, peau, cuir, armure, cheveux. La dernière colonne vient d'un contrôle ajouté pendant la relecture finale : elle compte les canaux identiques à ceux d'une palette de réglage. Plus elle est haute, moins la validation est dépaysante.

Q0 · étude de septembreRetenuÉtapeRejetéAutres
Décomposition. Sur la validation x4, Q0 50,4 → Q3m 43,3 → Q8 41,1. La fraction multi-palettes apporte 77 % du gain, la frontière environ 5 %. Sur D seule : 68 %. D'où l'ordre : Q3m d'abord, Q8 seulement si son gain propre se voit.Q6 améliore la validation (−8,6 %) mais dégrade la palette de production REF de +22,6 % : un numéro de compromis entre trois palettes coûte sur celle qui était jusque-là seule à compter.

Taille historique : échantillon zlib, sans plan frontière Q8, masque ni métadonnées. Le prototype E3b utilisait des fractions 4 bits ; un test séparé a montré la faible perte du passage à 3 bits. Ces tailles ne représentent pas les fichiers V6 actuels. D partage 1 canal sur 7 avec le réglage, E en partage 6. Les mesures XPRESS_HUFF de P1 sont ajoutées ci-dessous, avec leur propre périmètre.

12 · Nouveaux résultats P1 · 30 septembre

K6 : six palettes de réglage, dix validations distinctes

Le réglage retenu donne le même poids à REF, DEFAULT et quatre rotations de couleurs. Les dix palettes VAL01–VAL10 ne partagent au même canal ni numéro de gamme ni rampe RGB identique avec l’union de ces six palettes. LEGACY_D et LEGACY_E restent des diagnostics historiques et ne décident pas du choix de K.

Corpus : 180 occurrences, 144 frames BAM distinctes, quatre couches et les quatre corps d’armure ; 18 palettes ont produit 2 592 cibles. Le score est la moyenne des dix erreurs OKLab, pondérées par les pixels recolorables, face au dessin généré par ReboutCX.

Méthodex2 ΔE ×1000Gain x2x4 ΔE ×1000Gain x4
Q033,305—35,552—
Q6 K628,72913,74 %30,63613,83 %
Q3m K326,24321,20 %28,53019,75 %
Q3m K424,94025,12 %27,22023,44 %
Q3m K624,28527,08 %26,52325,40 %

x2 · erreur, plus court = mieux

Q033,305
Q3m K624,285

x4 · erreur, plus court = mieux

Q035,552
Q3m K626,523

Pourquoi K6. K3, K4 et K6 améliorent chacune des dix validations. K4 reste à +2,70 % du meilleur score x2 et +2,63 % à x4 ; le critère fixé était ≤ 2 %. K6 est donc retenu aux deux échelles. Cela ne promet pas une amélioration sous toute palette : REF seule recule de +6,10 % d’erreur en x2 et +11,59 % en x4, tandis que DEFAULT progresse de −30,43 % et −29,64 %.

Voir la planche réelle K6 x2
Planche P1 xBR, Q0, Q6 K6 et Q3m K6 sous six palettes
De gauche à droite : xBR, Q0, Q6 K6, Q3m K6. Lignes REF, DEFAULT, VAL01, VAL09, VAL10, LEGACY_D. Illustration hors jeu, ombre alpha 128 illustrative, agrandissement Nearest ×3 ; pas une capture en jeu.

Compression réellement mesurée. Avec XPRESS_HUFF, plans séparés et masque de 32 octets par frame, l’échantillon P1 passe de 173 704 à 343 620 octets en x2 (×1,98) et de 407 818 à 859 646 en x4 (×2,11). Le Q3m x4 est ici 2,50 fois plus lourd que le Q3m x2. Les en-têtes V6 et la table des représentants sont exclus : ce sont des tailles d’échantillon, pas celles du paquet final.

Pour mémoire, le zlib partiel de l’étude estimait environ ×1,98 en x2 et ×2,26 en x4 pour les méthodes fractionnaires, hors frontières et métadonnées. Cette ancienne estimation reste informative ; elle ne fixe aucun budget du V6. Les tailles XPRESS_HUFF ci-dessus utilisent un autre protocole.

13 · Corrections

Ce que chaque relecture a corrigé

Les études d'origine restent intactes. Les erreurs sont listées ici avec leur preuve ; aucune n'inverse l'architecture, plusieurs changent l'ordre ou la portée des décisions.

Le but

Montrer que le protocole sert à quelque chose. Une étude sans erreur trouvée n'est pas une étude sans erreur.

La recherche

Chaque relecture devait refaire, pas seulement relire : relancer les scripts, rouvrir le programme du jeu, recompter les fichiers.

La trouvaille

Seize corrections. Aucune ne renverse la solution ; plusieurs changent l'ordre des travaux ou la portée d'une conclusion. Personne n'y échappe : chaque modèle a été corrigé par un autre, et Opus aussi par lui-même.

AffirmationSourceCorrectionTrouvée par
Catmull-Rom « non implémenté »synthèse 5.6 SOLMode CatmullRom présent (shader 4×4 prémultiplié) ; QA xBR des personnages jouables acceptée avec ce filtre le 11/09Le filtre d'affichage existe bel et bien, et c'est même avec lui que l'auteur du projet a validé les personnages jouables en xBR.relecture finale
Palettes de validation « jamais vues »toutesE : 6/7 canaux communs avec l'entraînement, contrast 5/7, pale 4/7, D 1/7Elles ressemblaient beaucoup aux palettes de réglage ; seule D est vraiment nouvelle.relecture finale
Gain Q8 attribué aux frontièresprésentations77 % du gain vient de Q3m ; frontière ≈ 5 %L'essentiel du progrès vient des sous-nuances, pas du traitement des frontières.relecture finale
« x4 crénelle plus que x2 au zoom habituel »OpusVrai seulement au zoom 2 exact ; en jeu, x4 jugé légèrement meilleurrelecture finale
« ReboutCX accepté en jeu sur 0x6100 »revue croisée d'Opus2 compositions acceptées + 1 non-infériorité, préférence non tranchée ; xBR reste la voie acceptée à l'échelleSur le guerrier humain (0x6100), ReboutCX a été accepté pour deux compositions seulement (corps et équipement de Minsc, puis d'Anomen) ; une troisième a été jugée « non inférieure ».relecture finale
Fraction « q/7 »synthèse 5.6 SOLf/8 vers la nuance suivante, 89 positions, comme mesurérelecture finale
« La 2e arme garde la sémantique arme »synthèse 5.6 SOLNon démontré ; sans effet sur l'encodage (palette capturée par cellule) ; test en jeurelecture finale
« Étendre la clé de cache à la palette »OpusDéjà le cas (reboutcx_cache_p12.py:33-39)relecture finale
E5 temporelrevue croisée d'OpusMême erreur de signe que E3b (e5_cross.py:237)relecture finale
Le moteur lit RANGES12OpusMPALETTE ; fichiers identiquesGPT 6-Astra
Paperdolls WPM ; H6 et ZW à produireOpusWPN ; H6 = attaques, ZW interdit aux humainsGPT 6-Astra
Alignement temporelOpus, E3bSigne inversé ; corps Q0 → Q8 : 14,07 → 4,82 %GPT 6-Astra
Q8 « 3 bits » ; taille ×2–×2,3OpusMesuré en 4 bits (3 bits ≈ sans perte) ; taille = celle de Q3m sans frontièreGPT 6-Astra
« Plancher 0,04 infranchissable »OpusRésiduel de ces méthodes, pas une borne0,04, c'est l'erreur qui restait avec ces méthodes-là, pas une limite démontrée.GPT 6-Astra
Classes complètes : DLL obligatoire / aucun changementAstra / OpusRendu inchangé, mais le sens des dépendances change : masque explicite V6Chacun avait à moitié raison : l'image affichée ne change pas, mais le sens d'un champ du fichier change. D'où le masque de dépendances du format V6.croisé
Repos échantillonné (4 poses / 12)Opus, E3E3b : 20 changements de poseOpus lui-même
Corrections ajoutées · 4 octobre

Ce qui a changé depuis la présentation

  • « Méthode jamais vue en jeu » : essais Q3m réalisés ; périmètres de QA séparés.
  • « K encore à choisir » : K6 retenu après dix validations disjointes.
  • « V6 avec frontière optionnelle » : I/F et dépendances implémentés, sans frontière ni fraction compactée.
  • « Ni réduction ni mipmaps » : BOX ajouté, mipmaps x4 essayés ; x2 + BOX retenu.
  • « Monstres sans problème » : V7 adapte les partenaires aux profils fixes ou recolorables.
  • Les anciens graphiques E3b 4 bits restent historiques ; ils ne sont pas les mesures du V6 3 bits.
14 · Recette retenue

Un sprite HD qui reste une palette

Le master contient la géométrie, la classe de chaque pixel et une position continue dans sa gamme ; le moteur fournit les couleurs. Le joueur garde ses choix, les effets de palette suivent sans code spécifique.

Le but

Transformer les résultats en recette précise : quoi enregistrer dans le fichier HD, et comment le module du jeu doit le relire.

La recherche

Fusion des trois études, puis spécification au bit près pendant la relecture finale : le même calcul doit donner exactement le même résultat à la fabrication (en Python) et dans le jeu (en C++).

La trouvaille

Un V6 implémenté qui conserve l’idée de l’ancien format et ajoute la fraction et les dépendances explicites. Sans fraction, il reconstruit les mêmes pixels que V5. Le plan frontière imaginé pendant l’étude n’a pas été livré ; sa proposition est conservée plus bas comme explication historique.

La chaîne complète, du fichier d'origine à l'écran

  1. 1Le fichier d'origine (BAM). Il fournit la structure : numéros des pixels, cycles, ordre des images, points d'ancrage, bouche-trous.BAM V1 P8 (indices, cycles, lookup, centres) — vérité topologique.
  2. 2xBR, à la même taille que la version HD. Il dit, pour chaque pixel HD, s'il est transparent, ombre, et de quel matériau.xBR xN (même échelle) → alpha, ombre, classe par pixel — vérité sémantique.
  3. 3ReboutCX x4, sous plusieurs palettes. Le réseau dessine K versions de la même image, une par jeu de couleurs : ce sont les cibles.ReboutCX x4 RGB sous K palettes → cibles T_1..T_K — vérité de modelé, jamais de sémantique.
  4. 4L'encodeur multi-palettes. Pour chaque pixel, il choisit la nuance de base et la fraction qui collent le mieux aux K cibles à la fois, en calculant exactement ce que le jeu affichera.Encodeur multi-palettes, optimisé contre le décodeur exact.
  5. 5Le registre V6. Le fichier HD livré avec le mod.Plan I u8 + plan F u8 optionnel (valeurs 0..7) + dépendances et contrat de décodage. Aucun plan frontière.
  6. 6Dans le jeu, le module IEE. Il capture les 256 couleurs de chaque couche, prépare une table de 2 048 couleurs, colorie les pixels, empile les couches et rend l'image au jeu, à la taille d'origine.DLL IEE (CPU, compositeur existant) : P[256] capturée par couche après Realize → LUT 2 048 entrées → pixels → composition native → texture (géométrie x1).
// V6 implémenté : fractions par huitièmes
I         u8       indice de base
F         u8       0..7 ; absent ⇒ 0
dep_mask  256 bits entrées réellement lues
succ(i)   = voisin dans la même gamme ; fin ⇒ i
RGB       = (P[I]·(8−F) + P[succ(I)]·F + 4) >> 3
alpha     = alpha natif de P[I]
// aucun mélange entre classes dans ce V6
Plan I

La nuance de base

Un numéro de 0 à 255 par pixel, exactement comme aujourd'hui.

Plan F

Les huitièmes

De combien de huitièmes (0 à 7) le pixel avance vers la nuance suivante. Absent, il vaut 0 partout : c'est l'ancien format.

dep_mask

Les dépendances

La liste des cases de palette dont l'image a besoin. Si le décodage devait lire une case non déclarée, l'image est refusée plutôt qu'affichée fausse (fail-closed). La liste sert aussi à ne refaire le calcul que si une couleur utilisée a changé.

Ancienne piste B

Les frontières

Proposition historique : un second matériau (I2, F2) et un dosage W de 1 à 7 huitièmes sur les pixels de frontière. Ce plan n’existe pas dans le V6 livré. L’extension V7 utilise la lettre B pour un choix de partenaire, avec un autre sens.

La formule, lue à voix haute

lerp8 prend (8 − f) parts de la nuance de base et f parts de la suivante, puis divise par 8 ; « + 4 » arrondit au plus proche et « >> 3 » divise par 8. Avec f = 0, la nuance de base est inchangée. succ(i) reste dans la même gamme de 12 nuances ou le même mélange de 8 ; il ne franchit ni la fin ni les indices spéciaux. La LUT représente conceptuellement 256 × 8 = 2 048 couleurs. Le code prépare les couples I/F utilisés, pas nécessairement toutes les entrées à chaque image. Le mélangeur applique cette formule. La compatibilité V5 concerne les pixels reconstruits, pas l’identité des fichiers.

Encodeur

Recherche exhaustive

Pour chaque pixel, les 89 positions de sa gamme sont décodées sous les K palettes et comparées en OKLab. On garde ce que le runtime affichera vraiment.

Pas d'astuce : on essaie toutes les positions possibles et on garde la meilleure en moyenne sur les K palettes.
Palettes

K = 6

REF + défaut guerrière (30 91 93 12 23 93 2) + quatre rotations « carré latin », à poids égaux. Dix palettes de validation sans numéro ni rampe RGB identique au même canal avec l’union du réglage. K3 et K4 restent les variantes comparées avant le choix de K6.

« Carré latin » : des palettes construites pour que chaque matériau reçoive, d'une palette à l'autre, des teintes bien différentes, un clair et un sombre pour chacun.
x2

Réencoder

BOX des cibles x4 en flottant, puis encodage à x2 avec le guide xBR2. Jamais de réduction des plans déjà quantifiés.

On réduit le dessin du réseau, puis on refait tout le choix des nuances à cette taille. Réduire un fichier déjà converti en numéros n'aurait pas de sens : la moyenne de deux numéros n'est pas une couleur.
Frontières

Piste historique écartée

La proposition Q8c devait choisir la meilleure classe voisine (pas la première), utiliser au plus deux canaux et conserver un poids primaire ≥ 1/8. Elle devait être acceptée seulement après un gain net. Ces contraintes restent expliquées, mais Q8c a été écarté sans implémentation.

Le prototype prenait le premier voisin trouvé : 13,3 % de ses pixels frontière mêlaient plus de deux canaux, et 8,4 % perdaient tout à fait leur matériau principal.
ParamètreValeurPreuve
Ressource paletteMPALETTE.BMP, jamais modifiéeconfirmé
ModeléReboutCX x4 sous K6, sur chaque source et palette nécessairesL’ancienne estimation ≈ 282 000 calculs avec K3 venait du périmètre étudié, pas d’un comptage de la production K6. La déduplication et les caches évitent les calculs répétés ; les coûts actuels dépendent de l’union exacte des clés compatibles.mesuré
Sémantiqueguide xBR même échelle + provenance d'indiceconfirmé
EncodageQ3m, fraction 3 bitsmesuré
FrontièresQ8c écarté sans implémentation ; prototype historique conservéécarté
Interpolation runtimeoctets sRGB, arrondi définimesuré
Tramageaucunmesuré
Échellex2 conservé ; BOX pour le monde, Nearest pour l’UIdécidé
ReconstructionCPU dans creature_sprite_x2.cppReconstruction palette et composition sur CPU ; le filtrage d’affichage BOX emploie un shader distinct. Il ne s’agit pas d’une reconstruction complète des palettes sur GPU.implémenté
Alpha douxV8 optionnel, expérimentation distincte sur l’AnkhegLa voie acquise garde ses transparences natives et son ombre partielle. Spline Fit 1 rejeté ; alpha léger remplacé par le contour SDF V9 retenu sur l’Ankheg.étape précédente
Ancienne proposition : fractions et frontières
Ce bloc conserve la proposition de septembre, y compris la formule de frontière. Il décrit une piste de recherche, pas le lecteur V6 livré. « V5 exact » signifie les pixels, pas les octets du fichier.
// registre V6 = V5 + ajouts optionnels
plan I    u8      indice de base (identique V5)
plan F    0..7    fraction vers succ(I)   // absent ⇒ V5 exact
dep_mask  256 bits entrées de P lues  // fail-closed
plan B    option  (pixel, I2, F2, W 1..7) aux frontières

// décodage bit-exact, Python = C++
succ(i)      = i+1 dans la gamme ou la paire, sinon i
lerp8(a,b,f) = (a·(8−f) + b·f + 4) >> 3
pixel        = lerp8(P[I], P[succ(I)], F)
frontière    = (C(I,F)·W + C(I2,F2)·(8−W) + 4) >> 3
LUT          = 2 048 entrées par palette de couche
Après Character · 3–4 octobre

V7 : choisir des partenaires adaptés aux autres créatures

Dans une palette fixe, deux indices consécutifs ne sont pas forcément deux nuances d’une même rampe. V7 conserve l’idée Q3m et ses couleurs natives vivantes, mais choisit parmi quatre partenaires autorisés par le profil. La valeur (B << 3) | F indique le partenaire B et la fraction F par huitièmes, dans un octet. Ce B ne désigne pas le mélange de deux matériaux de l’ancien Q8.

Le pilote couvre 15 témoins de profils, soit 49 BAM et 11 586 frames sur les actions sélectionnées. Les familles complètes Ogre, Flying et Ankheg ont ensuite été produites et installées. Flying a été accepté ; Ogre et le Q3m original Ankheg n’ont pas de validation complète déduite de leur installation. Les 78 Character restent sur leur contrat V6 acquis.

Réutiliser les images identiques

Deux occurrences avec les mêmes pixels et le même contrat compatible partagent leur calcul, même si leurs centres ou leurs cycles diffèrent. Ces métadonnées restent propres à chaque occurrence. Hors Character, 699 374 frames sources ont été regroupées en 194 573 travaux source, évitant 504 801 répétitions physiques. Une même source sous deux contrats différents peut toutefois demander deux encodages.

V8 : essais séparés sur la transparence du contour

V8 ajoute un multiplicateur alpha optionnel sans recalculer les couleurs Q3m. L’essai Spline Fit 1 sur l’Ankheg a été rejeté en jeu pour des pixels isolés sur le contour. Un autre essai d’alpha léger a été installé le 4 octobre. Les marches restaient trop visibles : cet essai a ensuite été remplacé par le contour SDF V9 retenu ci-dessous. Ces expériences utilisent Catmull-Rom ; le défaut du candidat spline ne constitue pas à lui seul une preuve contre ce filtre.

Profils V7 et partenaires de couleur

Simulation hors jeu

Créatures V7 à palettes fixes ou recolorables et table réelle de quatre partenaires de couleur
Simulation hors jeu · Exemples du pilote V7 x2, avec la palette K6 #0 conservée. La table du Spectateur provient du témoin réel : B choisit un partenaire autorisé et F sa fraction, de 0 à 7 huitièmes. Les quinze témoins sont disponibles dans la galerie ; les tailles sont adaptées aux cartes et les QA restent propres à chaque candidat.
Galerie des 15 témoins et tables de partenaires

Rendus Q3m V7 x2 avec la palette K6 #0 de l’oracle conservé. Les grands témoins sont ajustés à leur carte ; les tailles relatives entre espèces ne se comparent pas ici. La wyverne assemble quatre parties, le dragon neuf. Les armes ou actions absentes du pilote ne sont pas ajoutées. Le Character montré ici est un témoin V7 ; les 78 Character acquis restent sur leur production V6.

La galerie montre des poses et des contrats, pas une validation globale des 15 familles. Les statuts de production et de QA restent ceux de chaque candidat.

V8 : essais de contour précédents

Simulation hors jeu

Contours de l’Ankheg original, spline et alpha léger sur fonds parchemin et pierre
Simulation hors jeu · Même frame MAKHG1 #11 pour le Q3m original, Spline Fit 1 et l’alpha léger. Les plans I/F, les couleurs RGB et la géométrie restent identiques pour cette frame ; seule la couverture alpha change. Le corps est montré sans sa couche de terre. Les loupes sans interpolation isolent le masque A ; elles ne reproduisent pas la combinaison Catmull-Rom de l’essai ingame. Spline Fit 1 a été rejeté ; l’alpha léger a été remplacé par le SDF V9 présenté ensuite.
Changer le fond et examiner le contour

Alpha affiché = alpha de la palette × masque A / 255

Le rectangle turquoise indique le même détail dans les trois images. La loupe utilise Nearest pour isoler le masque A ; elle ne reproduit pas la combinaison Catmull-Rom de l’essai ingame. Spline Fit 1 a été rejeté ; l’alpha léger a été remplacé par le SDF V9 présenté ensuite. Le choix du détail privilégie une zone réellement modifiée, identique pour les trois candidats.

V9 : un champ de distance pour des contours plus naturels

4 octobre · SDF retenu · simulation hors jeu

L’alpha léger rendait les pixels du bord moins opaques, mais les marches de la silhouette restaient visibles. La solution retenue pour l’Ankheg est un SDF — Signed Distance Field, ou champ de distance signé. Au lieu de stocker seulement « opaque ou transparent », il décrit la distance au bord : positive à l’intérieur, négative à l’extérieur, nulle sur le contour. Le jeu peut ainsi reconstruire ce bord à la taille réellement affichée.

1 · Décrire la forme

Le champ est lissé avec un déplacement borné à un texel x2. Les composantes et les trous sont conservés aux centres des texels : l’objectif est d’atténuer les marches sans effacer les pattes fines ni les fragments présents dans la source.

2 · Mesurer le pixel écran

Le shader teste 8 × 8 points dans la surface de texture couverte par chaque pixel écran. La proportion de points à l’intérieur donne la couverture du corps : par exemple, 32 points sur 64 donnent une opacité de 50 %. Cette surface dépend du zoom.

3 · Garder le matériau Q3m

Les mêmes plans I/F et la palette native fournissent les couleurs. Le matériau voisin est prolongé dans la marge transparente pour éviter un halo noir ; Catmull-Rom filtre ces couleurs sur 4 × 4 voisins. L’ombre noire native à alpha 127 reste calculée séparément.

Le x2 reste conservé. Aucun nouvel upscale neuronal, aucun nouvel encodage Q3m et aucun détail inventé : les plans source I/F, les centres et les cycles restent ceux de la production précédente. Les pixels interpolés à l’écran peuvent changer, puisque le bord et l’échantillonnage sont reconstruits autrement. L’ensemble Catmull-Rom + SDF de cet Ankheg répond à un autre problème que le filtrage Character : le choix x2 + BOX de ce dernier reste acquis.

Résultat visuel retenu le 4 octobre. Le contour SDF a reçu un retour visuel favorable et remplace l’essai d’alpha léger. Les passages temporaires en vanilla x1 observés lors de changements d’animation concernent le chargement des ressources et font l’objet d’un correctif séparé. L’amélioration décrite ici porte sur la silhouette ; aucun gain de FPS n’en est déduit.
Ankheg avant et après le contour SDF V9 : comparaison sur pierre et parchemin, loupes et schéma des 64 points de couverture
Simulation hors jeu · Même pose MAKHG1 #25, palette K6 #0, zoom natif ×3 et fonds personnalisés pour l’alpha léger et le SDF V9. Les loupes ×6 agrandissent les mêmes pixels déjà calculés. Le schéma illustre le champ de distance, les 64 points testés dans un pixel écran et la couverture obtenue. Le corps est montré seul : l’assemblage avec la terre, l’éclairage et les effets de sélection ne sont pas simulés.
Comparer le SDF selon la pose, le zoom et le fond

Ouvrir le comparateur pour calculer les deux rendus.

Modèle CPU des équations du shader, à partir des textures V9 quantifiées réellement produites ; alpha léger comparé avec le même filtre de couleur Catmull-Rom. Les couleurs sources I/F sont identiques ; leur prolongement et la méthode de contour diffèrent. Le rectangle indique la même zone dans les deux vues. La précision GPU et la stabilité du chargement ne sont pas reproduites.

Périmètre produit : 12 BAM / 516 frames ; 431 champs uniques et 85 réutilisations. SDF quantifié au pas de 1/16 texel x2, avec une marge de six texels. Au dézoom extrême, quand un pixel écran couvre plus de deux texels x2, le shader utilise une approximation smoothstep. En jeu, les distances du corps et de la terre sont réunies, en conservant l’ordre natif des couleurs.

Les diagnostics couleur du 3 octobre ont aussi comparé le x4 direct, SeedVR2, les fractions à 16 niveaux et quatre partenaires à huit niveaux. Ils restent des essais hors production ; le candidat 16 niveaux n’a pas été promu. Archives et comparatifs.

Voir un diagnostic réel des partenaires et des 16 niveaux
Spectateur : cinq traitements comparés hors jeu
Diagnostic Spectateur du 3 octobre : ancien x2, Q3m x2, Q3m x4, Q3m x4 à 16 niveaux, Q3m x4 à quatre partenaires et huit niveaux. Les en-têtes de l’image sont ceux de l’archive. Ce sont des aperçus hors jeu, pas une validation des nouveaux traitements.
15 · Plan

Du banc d'essai à la guerrière complète

Des dépendances techniques, pas un rituel. Chaque phase produit de nouvelles versions ; rien d'historique n'est réécrit ; aucune validation n'est déduite d'une installation.

Le but

Passer de « ça marche sur 120 images dans un script » à « ça marche dans le jeu, pour tout le personnage », sans brûler d'étape.

La recherche

Les trois études proposaient chacune un ordre de travail. La version finale classe les tâches selon ce dont chacune a besoin pour démarrer.

La trouvaille

Neuf phases, chacune avec sa condition de passage. La plus importante est P3 : montrer la méthode en jeu, sur une armure, un casque, un bouclier et une épée, avant toute production de masse.

PhaseTravailOn passe quandÉtat au 4 octobre
P0Oracles : lecteur BAM complet, réalisation MPALETTE, banc d'évaluation corrigé (signe, masques séparés, agrégations)Des outils de référence fiables : lire les fichiers, recalculer les couleurs comme le jeu, mesurer sans l'erreur de signe.réalisation exacte ; E3b reproduitRéalisé · oracles et banc corrigé
P1Inférence K palettes ; encodeur Q6 / Q3m ; 10 palettes disjointes ; K = 3/4/6Refaire l'expérience en grand et en propre, avec dix palettes de test vraiment nouvelles.Q3m bat Q0 sur chaque palette nouvelleRéalisé · K6, dix validations disjointes
P2DLL : lecteur V6, masque, plan F, LUT ; golden tests Python / C++Apprendre le nouveau format au module. « Golden tests » : des cas de référence dont le résultat est connu à l'octet près.pixels V6 sans fraction = pixels V5, pas fichiers identiquesImplémenté · 32 832 couples I/F de référence Python/C++
P3En jeu : CHFF4 + un casque, un bouclier, une épée, Q0 contre Q3mLe premier vrai test : l'ancienne et la nouvelle méthode côte à côte, dans le jeu.validation explicite de l'utilisateurValidé sur le périmètre du premier essai en jeu
P4Zoom réel ; x2 / x4 ; réduction d'aire ou mipmapsdécision datéeDécidé le 02/10 · x2 + BOX, sans mipmaps
P5Ablation Q3m ↔ Q8 contraintAvec et sans frontières, toutes choses égales par ailleurs : valent-elles leur complexité ?gain propre visible et mesuréÉcarté sans implémentation ni ablation Q8c
P60x6110 complet : 628 BAM, CHFF4 → CHFB1–3 → armes fréquentes → boucliers → casquesaucune frame manquante ; coûts mesurésProduit · 656 BAM / 178 360 frames de l’index
P7Paperdolls CHFF*INV, WPN*INV/OINmesures d'interface propresAccepté · 81 BAM normaux / 163 frames, UI Nearest
P8Les 78 animations Character, puis les autres profilsLa généralisation aux monstres demande des classes et partenaires adaptés ; voir l’extension V7. Une palette fixe n’élimine pas le problème du modelé.preuves par famille78 Character produits et installés ; QA limitée aux acquis
Mise en place QA

Commandes

C:MoveToArea("AR0700") puis C:CreateItem("PLAT01"), HELM01, ISHLD03, BDSW1H06, SW2H01, BOW01… Jeu et InfinityLoader fermés pour installer.

Commandes de la console du jeu : se rendre sur la Promenade de Waukeen (AR0700, de jour, sol clair), puis faire apparaître une armure de plates, un casque, un bouclier et des armes.
À voir en jeu

Recoloration et couches

Un canal à la fois ; deux guerrières aux couleurs opposées ; arme en main gauche recolorée par 0x1R puis 0x2R ; 9 directions + 7 miroirs.

Effets

Identiques au natif

Lueur pulsée de BDSW1H06, pause grise, invisibilité, pétrification, nuit, sélection, occlusion, 59–60 FPS.

Les conditions et observations QA du plan d’origine sont conservées. Leur présence dans cette page ne signifie pas que tous les effets, équipements et directions ont été validés pour les 78 animations. Les preuves d’installation ne valent pas décision visuelle ni intégration release.
Avis de Claude Opus 5.5 au 30 septembre, conservé avec ses conclusions et incertitudes de l’époque. Le complément ci-dessous donne les réponses apportées depuis.
16 · Position finale

L'avis du dernier relecteur

Claude Opus 5.5, après les deux relectures croisées, la synthèse de 5.6 SOL et la relecture finale.

En clair

Un avis signé, pas une preuve : celui du modèle qui a fait la dernière vérification. Il sépare ce qui est sûr, ce qui ne l'est pas, ce qu'il faut faire tout de suite et ce qu'il ne faut surtout pas faire.

Sûr

  • Le goulot est la discrétisation à 12 niveaux, pas le choix des candidats.
  • Le point d'action est le compositeur IEE existant : il a déjà la palette réelle de chaque couche.
  • Toute solution reste exprimée en indices de gamme, jamais en RGB figé (des couleurs peintes une fois pour toutes).
  • Une recette apprise sous une seule palette ne généralise pas.

Incertain

  • La tenue sur des palettes vraiment nouvelles : une seule l'est aujourd'hui.
  • Le gain propre des frontières, faible sur E3b.
  • Le coût réel du format sous XPRESS, la compression du module.
  • La plage de zoom et la valeur du x4.
  • Aucune mesure ne dit la beauté : tout se juge en jeu.

Déconseillé

  • Modifier MPALETTE ou égaliser les rampes.
  • Passer en BAM V2 ou en RGBA figé, c'est-à-dire en images déjà coloriées.
  • Adopter Q8 sans ablation, ou un tramage par défaut.
  • Lancer les 628 BAM avec une recette non validée en jeu.
Réponses apportées depuis

Les questions ouvertes ont avancé

Le banc corrigé et les dix palettes disjointes ont été réalisés ; K6 a été retenu. Le lecteur V6 est implémenté et vérifié contre les références Python. Q3m a été montré en jeu. La compression XPRESS_HUFF et le zoom réel ont été mesurés, puis le choix x2 + BOX a été enregistré. Q8c a été écarté sans ablation.

L’avis signé reste celui du 30 septembre. La beauté demeure un jugement visuel ; les extensions aux autres familles et les expériences de contour demandent leurs validations propres.

17 · Dossier

Contenu et sources

Les études d’origine restent dans sprite/Etudes_Sprite_codex_claude/. Les preuves de développement suivantes sont aussi dans les recherches de la famille 6110, docs/measurements/, les contrats pipeline/ et les décisions sprite/index/qa-decisions/. Les runs historiques conservent leur état daté ; les liens ci-dessous donnent la suite.

En clair

Tout le travail est conservé, y compris les versions qui contenaient des erreurs : c'est ce qui permet à chacun de refaire le chemin et de vérifier. Aucun fichier d'étude n'est réécrit ; une correction produit une nouvelle version. La présentation technique du 30 septembre remplace ainsi la présentation d'Opus du 29, et la présente page en est la version expliquée.

GUIDE_DEFINITIF_SPRITES_HD_BG2EE.md guide de développement, fait autorité PRESENTATION_ETUDE_SPRITES_HD_0x6110.html présentation technique PRESENTATION_PEDAGOGIQUE_SPRITES_HD_0x6110.html cette page, version expliquée PRESENTATION_PEDAGOGIQUE_SPRITES_HD_0x6110_EN.html version expliquée en anglais figures_pedagogie/ tuiles « jeu d'origine » de ces pages + script GUIDE_ULTIME_SPRITES_HD_BG2EE.md / .html synthèse 5.6 SOL, étiquetée « Codex » (historique) ClaudeCode_Guide_HD_0x6110_Femme_Humaine_Guerriere/ Claude Opus 5.5 GUIDE_ClaudeCode_HD_0x6110_palettes_dynamiques.md guide v1 PRESENTATION_ClaudeCode_0x6110.html présentation v1 + erratum (remplacée) REVUE_CROISEE_Codex_ClaudeCode_0x6110.html revue croisée + E5 donnees/ donnees_v2/ donnees_v3/ mesures E1–E3, E3b, E5 figures/ figures_v2/ figures_v3/ outils/ tuiles, planches, scripts CODEX_BG2EE_Femme_Humaine_Guerriere_2026-09-29/ GPT 6-Astra GUIDE_CODEX_BG2EE_FEMME_GUERRIERE.md guide d'Astra engine_research.md engine_disassembly_codex.txt preuves moteur inventory_research.md assets_inventory*.csv 774 BAM, 870 ITM upscale/ palette/ 4 upscales, 60 NPZ, tramage, gradients codex_palette_study_20260929/COMPARAISON_CODEX_CLAUDE_0x6110.md codex_palette_study_20260929/comparaison_claude_20260929/ signe temporel, 3 bits Identités BaldurReal.exe 2.7.3.0 b51093a49140b2b8…94217a14d57 MPALETTE = RANGES12 7a9a654d5cbc4cee…82000d5f829d66dd ReboutCX (poids) c36a14ddb51ae094…56d5b94bdedab05

Les « identités » sont des empreintes SHA-256 : une suite de caractères qui change dès qu'un seul octet du fichier change. Elles permettent de vérifier que l'on parle bien du même programme, du même nuancier et du même réseau.

Références ajoutées pour la mise à jour

Les fichiers de preuve ne sont pas réécrits pour suivre les nouveaux statuts. Par exemple, P1 peut encore dire « P2 à réaliser » : c’était son état au moment de l’expérience. Les nouvelles réalisations ont leurs propres références.

18 · Questions fréquentes

Pourquoi pas plus simple ?

Les raccourcis qui viennent à l'esprit, et pourquoi chacun a été écarté ou reporté. Réponses tirées des tableaux « pistes écartées » des guides.

Pourquoi ne pas livrer de belles images HD déjà en couleurs ?

Il en faudrait une par combinaison de couleurs, et le joueur en a des milliers. Une image peinte d'avance (RGBA figé, BAM V2) détruit la personnalisation et ne réagit plus aux sorts ni à l'éclairage, qui passent eux aussi par la palette.

RGBA précoloré unique / BAM V2-PVRZ : rejet. Couleurs RGB fixes littérales : rejet.

Pourquoi ne pas ajouter des nuances au nuancier du jeu ?

MPALETTE est commun à tout le jeu : le modifier changerait d'un coup tous les personnages, tous les objets et tous les mods. Et il n'y a pas de case libre sur le corps : les 252 numéros utiles suivent tous un choix de couleur.

Modifier MPALETTE / égaliser les rampes : rejet. Canal fixe corps : rejet. Patch de RealizeRange : rejet, V6 fait mieux sans patch binaire.

Pourquoi pas de tramage, comme sur les vieilles consoles ?

Testé. Le damier fixe se voit sur les grandes plaques et augmente l'erreur de 6 à 10 % ; la diffusion d'erreur double le scintillement ; un bruit renouvelé fait bouger 30 % des pixels d'une image pourtant immobile. Les sous-nuances font mieux, sans motif.

Bayer global : rejet par défaut. Diffusion d'erreur : rejet. Bruit temporel : interdit.

Pourquoi ne pas tout régler sur une seule palette ?

Parce que le réseau ombre différemment selon les couleurs. Réglée sous la seule palette de référence, une méthode y excelle (écart 16,3 contre 26,5 pour la méthode actuelle) mais ne gagne que 5 % sur les autres : c'est le surapprentissage. Or ce sont les joueurs qui choisissent leurs couleurs.

Q3 / interpolation mono-palette : rejet comme solution finale.

Pourquoi garder xBR si le réseau fait mieux ?

xBR reste net, déterministe et utile comme guide des indices, classes, transparences et contours. Sa validation historique est conservée. La voie de modelé retenue ensuite est Q3m K6 : le réseau fournit les cibles, puis les pixels sont réencodés pour rester recolorables. Les anciens choix Auto / Full xBR / Full ReboutCX décrivent un projet d’installateur, pas une interface publiée vérifiée ici.

Pourquoi ne pas tout calculer sur la carte graphique ?

La reconstruction des couleurs et la composition restent sur CPU, avec les palettes natives et les caches. BOX utilise bien un shader pour filtrer la texture à l’affichage. Ce filtrage est distinct d’une reconstruction complète des indices et palettes sur GPU, qui n’a pas été adoptée.

Shader complet immédiat : reporté. Second hook EEex : rejet, le point de capture IEE existe.

Pourquoi x2 par défaut si x4 est plus fin ?

Une texture x4 contient quatre fois plus de pixels qu’une texture x2. Dans les essais Q3m, le x2 a été conservé avec BOX : moins de travail de composition et de transfert, et un rendu jugé plus naturel. Le x4 peut mieux lisser certains contours, mais aussi donner un aspect « plastique » sans retrouver les détails absents de la source. Son intérêt reste visible dans les comparaisons, tandis que la préférence de production va au x2.

P4 : x2 + BOX retenu le 2 octobre.

Et si l'on montrait au réseau une image grise, sans couleurs ?

Piste ouverte : faire dessiner au réseau une « carte de nuances » indépendante des couleurs éviterait de le relancer pour chaque palette. Le risque : perdre les contrastes entre matériaux que la couleur lui signale. Pas encore testé ; à comparer à Q3m.

Carte de nuances grise : à tester.

Et les monstres ?

Une palette fixe ne garantit pas que ses indices voisins forment des dégradés utilisables. L’extension V7 choisit quatre partenaires adaptés au profil, tout en gardant les couleurs natives. Quinze profils ont un témoin ; Ogre, Flying et Ankheg ont une production complète installée, avec des états de QA séparés. Le V6 Character acquis reste conservé. Les essais d’alpha V8 sont un chantier distinct.

Profil palette et partenaires par famille ; aucune QA transférée automatiquement.

BOX à la fabrication et BOX à l’écran : est-ce la même étape ?

Le principe de moyenne est proche, mais les rôles diffèrent. À la fabrication, les cibles RGB x4 du réseau sont réduites en flottant avant l’encodage x2. À l’écran, le shader moyenne la texture déjà reconstruite selon la surface couverte par le pixel d’écran. Les indices I/F ne sont jamais réduits par moyenne.

Pourquoi les paperdolls gardent-ils Nearest ?

La figurine d’inventaire passe par un affichage UI distinct du monde. Son lot 6110 a été accepté en x2 avec Nearest, en gardant les centres, les lookups et l’ombre native. Le choix BOX du monde ne remplace pas ce réglage UI.

19 · Lexique

Les mots du métier

Dans le sens où cette page les emploie. Les mots soulignés en pointillé dans le texte renvoient ici.

Ablation
Expérience où l'on retire un ingrédient d'une méthode, toutes choses égales par ailleurs, pour mesurer ce qu'il apporte vraiment.
Alpha
La transparence d'un pixel. Dans les sprites du jeu, un pixel est soit opaque, soit transparent ; seule l'ombre est semi-transparente.
BAM
Le format des fichiers d'animation du jeu : des images (frames) rangées en cycles, avec une table de 256 numéros de couleur. Le nom du fichier dit la couche et l'action (CHFF4G11 : corps en plates, marche).
Bit, « 3 bits »
Un bit vaut 0 ou 1. Trois bits permettent 8 valeurs (0 à 7) : d'où les huitièmes de nuance.
Canal, gamme, rampe
Un canal est l'un des sept emplacements de couleur d'un personnage (métal, mineure, majeure, peau, cuir, armure, cheveux). La gamme, ou rampe, est la suite de 12 nuances du clair au sombre qui lui est affectée : une ligne de MPALETTE.
Classe
Le matériau d'un pixel : l'une des 7 gammes, l'un des 21 mélanges de deux gammes, ou l'un des quatre cas spéciaux (transparent, ombre, deux noirs réservés).
Couche, cellule
Corps, arme, bouclier ou main gauche, casque : dessinés séparément, chacun avec sa palette, puis empilés.
CRE, ITM
Fichiers du jeu décrivant une créature et un objet. Ils contiennent notamment les couleurs imposées.
Désassemblage
Traduire le programme du jeu, une suite d'instructions machine, en une forme lisible, pour savoir ce qu'il fait réellement. Les adresses notées RVA situent une routine dans le programme.
DLL, module, runtime IEE
Le module du projet (InfinityEngine-Enhancer), un fichier DLL chargé par le jeu qui fabrique l'image HD pendant la partie. « Runtime » : ce qui se passe pendant que le jeu tourne.
Fausses couleurs
La technique du coloriage numéroté (false color) : le fichier porte des numéros, le jeu fournit les couleurs. Les teintes de travail criardes stockées dans le fichier sont surnommées couleurs « clown ».
Frame, cycle
Une frame est une image d'animation ; un cycle, une animation complète vue sous un angle.
Indice
Le numéro, de 0 à 255, que porte chaque pixel du sprite.
Inférence
Un calcul du réseau de neurones sur une image.
Interpolation, fraction
Calcul d'une valeur intermédiaire entre deux valeurs connues. Ici, une couleur située à F huitièmes du chemin entre deux nuances voisines.
K
Nombre de palettes de réglage : K3 dans E3b, K3/K4/K6 comparés en P1 ; K6 retenu, avec dix palettes de validation disjointes.
LUT
Table de correspondance précalculée (look-up table). Au lieu de refaire un calcul pour chaque pixel, on le fait une fois pour toutes les valeurs possibles, puis on lit la table.
Mipmap
Copies réduites d’une texture (moitié, quart…), utilisées selon sa taille à l’écran. Le mode x4 essayé régénérait les niveaux après recomposition. Le choix Character x2 + BOX n’utilise pas de mipmaps.
MPALETTE.BMP
Le nuancier du jeu : 256 lignes de 12 couleurs. RANGES12.BMP en est une copie identique, mais le moteur ne lit que MPALETTE.
OKLab, ΔE
OKLab est une façon de noter les couleurs où la distance entre deux notes suit la différence perçue par l'œil. ΔE est cette distance. Un écart de l'ordre de 0,01 à 0,03 commence à se voir.
Opcode
Numéro d'effet dans les fichiers du jeu. L'opcode 7 change la couleur d'un canal.
Palette, palette réalisée
La table qui associe une couleur à chaque indice. La palette réalisée est celle que le jeu vient de calculer pour une couche, effets compris.
Palettisation, quantification
Convertir une image aux teintes libres (celle du réseau) en indices d'une palette limitée.
Paperdoll
Grande figurine de l’inventaire, avec ses propres BAM et sa voie UI. Le lot normal 6110 (81 BAM, 163 frames) a été accepté en x2 Nearest.
Plus proche voisin (nearest)
Affichage sans lissage : chaque pixel d'écran prend la couleur d'un seul pixel de l'image. Net, mais peut « sauter » des pixels quand on réduit (crénelage). C'est le réglage de base des contrôles qualité.
QA
Contrôle qualité (quality assurance) : ici, la vérification en jeu par l'auteur du projet. Aucune QA ne se déduit d'une mesure ou d'une installation.
ReboutCX
Le réseau de neurones d'agrandissement x4 utilisé par le projet (architecture RRDBNet, 16,7 millions de paramètres).
Registre V5, V6
Formats de stockage des sprites HD. V5 porte les indices ; V6 implémenté ajoute fractions et dépendances. I/F restent u8. Sans fraction, mêmes pixels V5, mais en-têtes différents. Les extensions V7/V8 ont des contrats distincts.
SHA-256
Une empreinte numérique : une suite de caractères calculée à partir d'un fichier, qui change dès qu'un seul octet change.
Sprite
Une image animée représentant un personnage, un monstre ou un objet dans un jeu en deux dimensions.
sRGB, lumière linéaire
sRGB est le codage habituel des couleurs sur écran ; la lumière linéaire le convertit en quantité de lumière réelle. Mélanger dans l'un ou l'autre donne des résultats légèrement différents.
Surapprentissage
Quand une méthode colle si bien à ses exemples de réglage qu'elle se trompe sur les autres.
Tramage (Bayer, diffusion d'erreur)
Simuler une teinte intermédiaire en alternant deux teintes voisines : selon un damier fixe (Bayer) ou en reportant l'erreur d'arrondi sur les pixels voisins (diffusion d'erreur).
Upscale x2, x4
Agrandissement d'une image : deux ou quatre fois plus de pixels dans chaque direction, soit 4 ou 16 fois plus de pixels au total.
Validation, réglage
Les palettes de réglage servent à ajuster une méthode ; les palettes de validation, mises de côté, servent à vérifier qu'elle marche aussi ailleurs.
Vanilla
Le jeu d'origine, tel qu'il est livré, sans mod.
xBR
Un algorithme classique d'agrandissement de pixel art, fait de règles sur les pixels voisins. Il n'invente aucune couleur.
XPRESS, zlib
Deux méthodes de compression de données. Le module du jeu utilise XPRESS ; les tailles de l'étude ont été estimées avec zlib, d'où leur caractère indicatif.
BOX
Moyenne de pixels sur une surface. Pendant la fabrication : réduction des cibles RGB avant encodage. À l’écran : moyenne des texels couverts, pondérée par l’aire et l’alpha.
Texel, minification
Un texel est un pixel de texture. La minification réduit cette texture à l’écran ; la magnification l’agrandit. Les filtres doivent tenir compte de ces deux situations.
Alpha prémultiplié
RGB multiplié par l’alpha pendant le filtrage, pour que les pixels invisibles n’ajoutent pas de noir aux bords.
V7, partenaire B
Quatre partenaires de couleur autorisés par profil, sélectionnés par B, et huit fractions F. Ce B n’est pas l’ancien plan frontière Q8.
V8, couverture A
Multiplicateur alpha optionnel pour un essai de contour ; couleurs Q3m conservées. Son installation ne vaut pas validation visuelle.
Déduplication
Réutilisation d’un calcul pour des pixels et un contrat identiques. Centres et cycles restent stockés par occurrence.