Toutes les pages de formats ↓
Tutoriels et références

Pièges courants du modding et de l'analyse des formats

Source : coreprime/kbot @ 0ab97bf · Modifier sur GitHub

Un aide-mémoire d'une page qui rassemble les pièges les plus fréquents, disséminés dans les documents de formats de kbot. Si vous butez sur un bug qui n'a aucun sens, commencez ici. Chaque point renvoie à l'explication détaillée sur la page du format concerné.

Tip

Vous cherchez pourquoi « mon mod ne se charge pas » ? La règle du point-virgule des TDF (#tdf--fbi--ota, premier point) explique à elle seule plus de signalements de « casse silencieuse » que tous les autres pièges réunis.


HPI / UFO / CCX / GP3

  • Les fichiers libres à la racine de l'installation l'emportent sur toutes les archives. Déposez units/MYUNIT.fbi sur le disque, et le moteur le préfère à tout ce que contient totala1.hpi. Le schéma de superposition de hpi.md montre toute la pile de priorités.
  • Entre archives, la première montée l'emporte, et seuls dix *.hpi sont montés. TA 3.1c monte rev31.gp3, puis les *.ccx, les *.ufo et les dix premiers *.hpi qui s'ouvrent, chaque groupe dans l'ordre ASCII des noms en majuscules. Un mod livré sous le nom zz_mod.hpi passe après toutes les archives d'origine et, sur une installation qui contient déjà dix *.hpi triés avant lui, n'est monté que par l'examen du disque (le CD du jeu), en dessous de tout le reste. Livrez vos mods en .ufo.
  • Les pointeurs HPI v1 sont absolus par rapport au début du fichier, pas au début du répertoire. Ne soustrayez rien. L'astuce de l'analyseur de référence consiste à allouer un tampon de DirectorySize octets et à y déchiffrer le répertoire à l'offset Start, pour que les pointeurs indexent directement le tampon. Voir Arborescence du répertoire.
  • La graine du chiffrement HPI v1 avance avec la position dans le fichier. Impossible de déchiffrer un tampon isolément : il faut savoir de quel offset absolu du fichier il provient. Voir Dériver la clé de chiffrement.
  • Si DecryptKey == 0, n'appliquez pas du tout le chiffrement XOR. Certaines archives faites maison sont livrées en clair ; appliquer quand même le chiffrement brouille ce qui était déjà lisible.
  • La somme de contrôle des chunks SQSH est calculée sur les octets chiffrés. Vérifiez-la avant de déchiffrer. Voir Chunks compressés (SQSH).
  • TA: Kingdoms utilise le HPI v2 (Version == 0x00020000), avec une autre disposition : pas de XOR, un seul chunk SQSH par fichier. Lisez la section TA: Kingdoms — HPI v2 avant d'essayer l'analyseur v1 sur une archive de TAK.
  • Les sauvegardes à marqueur BANK sont une tout autre affaire : elles reprennent l'enveloppe HPI, mais leur contenu est un état de jeu sérialisé, pas un système de fichiers. kbot ne les décode pas.
  • Le .gp3 exige le patch rev3.1. C'est toujours du HPI à l'intérieur, mais un TA non patché refuse de le monter.

TDF / FBI / OTA

  • Chaque valeur doit se terminer par ;. Un point-virgule manquant fusionne silencieusement des valeurs d'une ligne à l'autre et produit des caractéristiques complètement fausses. C'est la cause n° 1 des « mon unité a des PV bizarres / pas de description / un mauvais coût ».
  • Les clés sont insensibles à la casse, les valeurs non. Side=arm fonctionne pour la plupart des recherches, mais fait échouer tout code de mod qui compare Side par égalité de chaînes.
  • Les valeurs de liste sont séparées par des espaces (Category=COMMANDER MOBILE WEAPON), pas par des virgules. L'exception est le numplayers=2,4,6,8,10 des OTA, qui utilise des virgules.
  • Les booléens sont les entiers 1/0, pas true/false. Le moteur n'accepte que la forme entière.
  • Pour un mod, ne modifiez jamais sidedata.tdf pour ajouter des unités. Utilisez plutôt une inscription [MENUENTRY] dans download/<UNITNAME>.tdf, le mécanisme qu'utilise Core Contingency. Voir TDF : [MENUENTRY] et le tutoriel de modding.
  • Bmcode=0 cache une unité du menu de construction, même si tout le reste est valide. Vous voulez presque toujours Bmcode=1.
  • Une unité qui ne figure dans le menu d'aucun constructeur ne peut pas être construite, même si son FBI est valide par ailleurs. C'est le bug le plus courant du type « ma nouvelle unité existe mais n'est pas constructible ». Voir l'étape 5 du tutoriel de modding.
  • La profondeur d'imbrication des sections relève de la convention, pas de la spécification. Certains outils supposent 2 niveaux ; les TDF d'armes en ont 3 ([WEAPON][DAMAGE][category]).

TNT / SCT — terrain des cartes

  • Width et Height d'un TNT sont en cases d'attributs de 16 px, ni en tuiles ni en pixels. Divisez par 2 pour le nombre de tuiles ; multipliez par 16 pour les dimensions en pixels. Voir l'en-tête TNT.
  • SeaLevel == 0 ne signifie PAS « pas d'eau » : cela signifie que la plus petite valeur possible est au seuil, donc que rien n'est sous l'eau. Utilisez SeaLevel = 1 pour les cartes vraiment sèches.
  • Les mots d'éléments d'un TNT ne placent un élément de décor qu'en dessous du nombre d'entrées de la table des éléments. 0xFFFC est vide ; 0xFFFE (Lava Run, AC02), 0xFFFD et tout autre mot égal ou supérieur à la taille de la table ne placent rien, et la case reste constructible.
  • Le remplissage de la minicarte d'un TNT utilise l'index de palette 0x64, et la zone de la carte est dimensionnée d'après la carte (grand côté de 252, proportions de la carte visible), et non trouvée en cherchant le remplissage. Le jeu ne lit la minicarte stockée que si le bit 0 du mot d'en-tête en 0x2c est à un. Voir TNT.
  • Le .tnt de TA: Kingdoms utilise IDVersion == 0x4000 au lieu du 0x2000 de TA (TA lit aussi une ancienne disposition 0x1020). kbot tnt image produit n'importe quoi sur les TNT de TAK ; le décodeur de tuiles est propre à TA. Voir Cartes TA:K.
  • Les sections SCT doivent avoir des dimensions multiples de 4 dans les deux sens pour se charger dans TAE. Le format sur disque autorise d'autres tailles, mais l'éditeur les rejette avec « section misaligned ».
  • Le SCT V2 a des cases de hauteur de 8 octets, le V3 de 4 octets. kbot accepte les deux ; les mods construits avec l'éditeur ne voient que du V3.

3DO — modèles

  • L'axe vertical est Y, pas Z. Importer un 3DO dans un moteur où Z est vertical (Blender, Unreal moderne) sans échanger les axes laisse chaque unité couchée sur le flanc.
  • Les primitives sans texture sont invisibles sauf si IsColored != 0 : le pseudo-code visible = (texture != "") || (IsColored != 0) couvre les deux cas. C'est le bug de rendu 3DO le plus courant.
  • OffsetToSelectionPrim n'a de sens que sur l'objet racine ; les objets enfants doivent le mettre à -1 (0xFFFFFFFF).
  • L'échelle en virgule fixe est de 1 / 65536. Un sommet écrit 0x00010000 = 1,0 unité du monde ; les 16 bits de poids faible sont la partie fractionnaire.
  • Les sommets sont locaux à l'objet, pas globaux. Deux objets peuvent avoir des tableaux de sommets identiques : c'est de la géométrie en miroir, pas des données partagées.

COB / BOS — scripts

  • L'opcode call-script est 0x10062000, PAS 0x10063000 comme l'affirment certains documents antérieurs à la 3.1. Les vieux décompilateurs qui utilisent 0x10063000 produisent n'importe quoi — voir la référence des opcodes.
  • Les numéros de pièces dans les opcodes sont des index dans la table des noms de pièces, pas des chaînes. Le COB porte les noms dans un pool de chaînes ; à l'exécution, on utilise des index pour la rapidité.
  • SET_SIGNAL_MASK ne fait que déclarer les signaux qui concernent le script : il ne tue rien. C'est l'envoi de signal X qui arrête les scripts dont le masque contient X. La règle de lint signal-never-signalled repère les scripts qui définissent un masque que personne ne signale jamais.
  • Le Scriptor de Cavedog remplace CURRENT_SPEED par le littéral 29, ce qui casse les scripts de type MoveWatcher après un aller-retour. Le décompilateur de kbot rétablit le nom symbolique ; si vous devez faire l'aller-retour par Scriptor, mettez des parenthèses : (get CURRENT_SPEED) > 5.
  • Les offsets de saut sont des offsets en octets relatifs à OffsetToScriptCode, pas à l'instruction courante. JUMP 0x4C signifie « sauter à OffsetToScriptCode + 0x4C ».
  • Les numéros de ports de GET_UNIT_VALUE diffèrent entre TA et TA:K. Le catalogue de TA (le décompilateur de kbot nomme les ports 1–20) est documenté dans l'annexe B.

GAF — animations de sprites

  • Une séquence ne boucle que si l'octet de poids faible de son mot +2 est positionné ; à 0, elle se joue une fois puis s'arrête. Toutes les séquences d'origine stockent 1 : un outil qui écrit zéro fige donc les éléments de décor animés.
  • Les frames de textures/*.gaf et anims/vismasks.gaf doivent être brutes. Le jeu les lit comme de simples tableaux de pixels.
  • Certaines séquences sont livrées avec des durées de frame à 0 ; le jeu affiche alors la frame pendant un tick. Ne les « corrigez » pas avec une valeur par défaut.
  • L'index de palette 0 n'est pas transparent en soi. Seules la clé d'une frame brute et les plages sautées d'une frame compressée le sont.
  • Les lignes de pixels compressées peuvent être plus courtes que Width. Le jeu continue de lire dans les octets suivants ; kbot complète la ligne avec des pixels transparents et émet un avertissement. Aucun fichier d'origine ne contient de telles lignes.
  • Les origines des calques sont des points chauds : chaque calque d'une frame composite est placé de sorte que son origine tombe sur celle de la frame.
  • anims/terrain.gaf et anims/vismasks.gaf ont Version == 0 dans leur en-tête. Le jeu ignore le mot de version.
  • Le .taf de TA: Kingdoms existe en deux variantes. Un .taf à palette EST un GAF — même format sur disque, sauf que TAK prend la palette dans un .pcx propre au camp plutôt que dans la palette globale de TA. Un .taf truecolor reprend le même conteneur mais stocke des pixels ARGB 16 bits et n'a besoin d'aucune palette. C'est l'octet de format de la frame (0/1 = à palette, 4/5 = truecolor), et non l'extension, qui fait foi — voir TAF / TSF.

TAF / TSF — animations truecolor

  • L'extension .taf est ambiguë : à palette (à lire comme un GAF) ou truecolor (à lire avec kbot taf). Vérifiez toujours l'octet de format de la frame, jamais le nom de fichier, même si la plupart des fichiers truecolor de TAK portent par convention un suffixe _4444 / _1555.
  • L'export GIF perd de l'information. Le GIF ne contient qu'un détourage sur 1 bit et 255 couleurs : l'alpha progressif de l'ARGB4444 devient des bords nets. Utilisez l'APNG (kbot taf export --format apng) pour garder le vrai canal alpha.
  • Le champ de nom de la frame et l'octet de flag 0x0B peuvent contenir des déchets. Conservez-les tels quels pour un aller-retour exact à l'octet près ; ne les normalisez pas.
  • Un Delay / Duration de 0 est valide : comme dans le GAF, une frame de zéro tick est pilotée par les événements (les fonds de menus statiques l'utilisent). Ne le « corrigez » pas.

PCX — images

  • TA ignore BytesPerLine. Les lecteurs standard laissent de côté le remplissage quand BytesPerLine > Width ; TA 3.1c décode exactement Width octets par ligne, si bien que les fichiers avec remplissage sont décalés dans le jeu. Écrivez BytesPerLine == Width, et vérifiez avec kbot pcx describe.
  • TA ne charge que la version 5, et décode chaque fichier comme des données 8 bits sur un seul plan.
  • Les octets littéraux dont les deux bits de poids fort sont à un doivent être échappés en RLE. Un octet nu de valeur 0xC0–0xFF est interdit comme littéral ; émettez-le sous forme de plage de longueur 1 (0xC1, 0xFF pour un seul 0xFF). Une erreur sur ce point désynchronise le décodage au bout d'une ligne.
  • Le jeu prend les 768 derniers octets comme palette, avec ou sans le marqueur 0x0C ; les lecteurs standard ont besoin du marqueur.

PAL / ALP / LHT / SHD — palettes et tables de correspondance

  • Le 4e octet de chaque entrée n'est PAS de l'alpha. C'est un octet de remplissage inutilisé, que Cavedog a toujours mis à 0x00. Les outils de palette open source qui le traitent comme de l'alpha refusent d'afficher la palette (alpha=0 → tout transparent).
  • L'index 0 est noir, pas transparent. Le terrain, les minicartes et les fonds le dessinent opaque ; les sprites choisissent leur propre clé de transparence.
  • Un palette.pal vide ou absent est remplacé par palette.pcx (ses 768 derniers octets) ; un .pal de plus de 1 024 octets est lu jusqu'à l'octet 1 024.
  • .alp / .lht / .shd ne sont PAS des palettes RVB : .alp est une table de 256×256 et .shd / .lht des tables de 32×256 d'index de palette, et le jeu ignore (et reconstruit) une table de toute autre taille. Les afficher avec kbot pal describe donne n'importe quoi ; utilisez plutôt kbot pal lookup.
  • La palette de TA contient 13 triplets RVB en double. Si votre éditeur dédoublonne à l'import (certains le font), vous perdez des entrées et la palette passe silencieusement à 243 entrées.

FNT — polices bitmap

  • Offsets[c] == 0 signifie « pas de glyphe », pas « glyphe à l'offset 0 ». L'offset 0 tombe au milieu de l'en-tête : Cavedog réutilise zéro comme sentinelle.
  • L'ordre des bits commence par le bit de poids fort (MSB) dans chaque octet. Le bit de poids faible en premier est plus courant dans les polices bitmap modernes ; ne présumez de rien.
  • Le flux de bits est continu d'une ligne à l'autre : aucun remplissage à la fin de chaque ligne de balayage.

Profils d'IA

  • Les fichiers d'IA de TA: Kingdoms n'ont pas de directives plan, seulement des lignes weight/limit nues. L'analyseur de kbot ouvre un plan default implicite ; les lecteurs doivent tolérer l'absence du bloc. Voir TA:K — profils sans plan.
  • Aucune validation nulle part. Noms d'unités mal orthographiés, valeurs de poids cassées, lignes hors d'un plan : tout est ignoré en silence. Le premier signe d'un profil cassé, c'est que « l'IA se comporte bizarrement », sans aucun message dans le journal.
  • Les alias de catégorie (PLANT, LEVEL3) n'« existent » que si au moins une unité les déclare dans Category=. Écrivez LEVL3 par erreur et la directive ne fait rien, en silence.

Sons

  • Un WAV manquant donne du silence, pas une erreur. Écrivez par erreur select1=cmsdel1 (lettres interverties) et le moteur ne joue rien — pas de journal, pas de son de repli.
  • L'extension .wav est implicite dans les valeurs TDF : ne l'écrivez jamais. select1=cmdsel1.wav devient sounds/cmdsel1.wav.wav et ne trouve rien.

Particularités de TA: Kingdoms

  • TAK exige -disablecavedogverification comme argument de ligne de commande pour charger la plupart des fichiers moddés. Sans lui, le moteur rejette tout fichier dont l'empreinte ne figure pas sur sa liste d'autorisation.
  • TAK a 8 codes de camp dans ses données, pas 4 : ARA / TAR / VER / ZON pour les quatre camps jouables, plus CRE (Creon, Iron Plague), MON (monstres), LIF (faune), NPC (personnages de campagne). Le filtrage des listes d'unités doit tous les gérer.
  • Les armes de TAK se trouvent en ligne dans chaque FBI, sous forme de sous-sections [WEAPON1]–[WEAPON3], et non dans un répertoire weapons/*.tdf séparé.
  • Les menus de construction de TAK sont linéaires, pas en 2×3. Chaque constructeur a un répertoire canbuild/<builder>/<unit>.tdf avec un unique bloc [Menu] { Priority = N; }.

Voir aussi