Mapping et Hammer

Réduire la taille d’un BSP : ce qui alourdit une map et ce qui aide

Réduire la taille d’un BSP : quelles données prennent la place, comment mesurer, et ce qu’apportent lightmap scale, HDR, cubemaps, packing et bspzip -compress.

Un BSP devient presque toujours volumineux à cause de trois choses : les lightmaps, stockées en double lors d’une compilation HDR, le contenu packé dans le pakfile et les cubemaps HDR. Mesure d’abord quel bloc domine dans ta map. Ensuite, un lightmap scale plus élevé sur les grandes faces, un packing soigné et de petites cubemaps aident là où ça compte. La compression du BSP terminé est la dernière étape et ne remplace rien de tout cela.

Ce qui prend de la place dans un BSP

Un BSP se compose de blocs de données appelés lumps. Leur structure est expliquée dans Qu’est-ce qu’un fichier BSP ?. Seuls quelques-uns comptent pour la taille :

DonnéesOù elles se trouventDe quoi dépend la taille
Lightmapslump d’éclairage, avec le HDR un second de même taillesurface éclairée, lightmap scale, matériaux avec bump map
Contenu custompakfiletextures, modèles, sons
Cubemapspakfile, sous materials/maps/nombre d’entités env_cubemap et leur « Cubemap Size »
Éclairage des prop_staticpakfile, fichiers sp_*.vhvnombre et niveau de détail des props, uniquement avec -StaticPropLighting
Displacementsleurs propres lumps et lightmapsnombre et power des surfaces
Collision, géométrie, visibilitélumps restantsgénéralement petits

Deux des maps d’origine de GMod montrent à quel point le résultat varie (1 Mo = 1 000 000 octets) :

  • gm_construct fait 36,7 Mo. Sur ce total, 24,5 Mo sont des lightmaps : 12,3 Mo pour le LDR et exactement la même quantité une seconde fois pour le HDR. Le pakfile occupe 3,8 Mo, dont 2,1 Mo de cubemaps HDR et 1,4 Mo d’éclairage de props. Les données de collision atteignent 3,1 Mo, et les lumps des 110 displacements 0,8 Mo au total.
  • gm_flatgrass fait 47,4 Mo alors que la map est presque vide. 41,6 Mo correspondent au pakfile, dont 39,1 Mo se trouvent dans seulement huit cubemaps HDR.

Mesurer avant de couper

À la fin de son log, VRAD liste toutes les zones de données. Dans la colonne Memory, le nombre placé avant la barre oblique est la taille en octets. Les lignes qui comptent ressemblent à ceci (tirées d’une petite map de test) :

Object names       Objects/Maxobjs  Memory / Maxmem  Fullness
LDR lightdata         [variable]       36320/0        ( 0.0%)
HDR lightdata         [variable]       36320/0        ( 0.0%)
pakfile               [variable]       24864/0        ( 0.0%)
physics               [variable]        4178/4194304  ( 0.1%)

bspzip montre ce que contient le pakfile. La première commande liste seulement les noms. La seconde écrit le pakfile sous forme de fichier ZIP, que tu peux trier par taille dans un logiciel d’archivage :

bspzip -dir mymap.bsp
bspzip -extract mymap.bsp pakfile.zip

Pour un BSP uploadé, le Map Scanner affiche lui aussi la taille du fichier, le nombre de fichiers du pakfile et un extrait de ceux-ci.

Lightmaps : scale et HDR

Le lightmap scale indique combien d’unités couvre un échantillon de lumière (luxel). Chaque luxel occupe quatre octets et, d’après le wiki de Valve, les faces avec une bump map en stockent quatre fois plus. Si tu divises le scale par deux, le nombre de luxels est à peu près multiplié par quatre. Dans notre map de test à deux pièces, l’éclairage occupait environ 10 Ko avec un scale de 32, environ 36 Ko avec la valeur par défaut de 16 et environ 564 Ko avec un scale de 4.

  • Monte le scale à 32 ou 64 sur les grandes faces éclairées uniformément. Le prix à payer : des bords d’ombre plus doux et moins précis.
  • Ne le baisse que là où une ombre doit vraiment être nette.
  • Applique tools/toolsnodraw sur les faces que personne ne voit. VBSP les supprime, et leur lightmap disparaît avec elles.
  • Dans Hammer, le mode d’affichage 3D « 3D Lightmap Grid » montre la densité de luxels de chaque face.

Le deuxième grand levier est le HDR. VRAD connaît -ldr, -hdr et -both. Le texte d’aide du VRAD de GMod ne mentionne pas ces trois paramètres, mais le programme les accepte. Sans aucun d’eux, il ne calcule que le LDR. Avec -both, VRAD écrit un second lump d’éclairage de même taille, avec -StaticPropLighting un second fichier .vhv supplémentaire par prop, et tu génères les cubemaps deux fois. Une map uniquement LDR est donc nettement plus petite, mais renonce au HDR pour tous les joueurs. Ce compromis est décrit dans le guide de l’éclairage du Source Engine.

Pakfile : contenu et cubemaps

Ne packe que ce que la map utilise, et rien de ce que chaque joueur possède déjà avec le jeu. Les textures représentent presque toujours la plus grande part. La résolution, le format et la vérification de la liste sont traités dans packer du contenu custom dans un BSP.

Les cubemaps sont sous-estimées. buildcubemaps écrit une texture par env_cubemap dans le pakfile, et pour une map HDR un .hdr.vtf en plus. La version HDR stocke 16 bits par canal et, dans les deux maps d’origine, fait environ seize fois la taille de la version LDR compressée : environ 77 Ko en 32x32, mais 4,9 Mo en 256x256. Chaque cran du champ « Cubemap Size » multiplie la taille du fichier par quatre. Laisse donc la taille sur « Default » et ne l’augmente que pour quelques endroits précis dotés de grandes surfaces réfléchissantes. Plus d’infos sur les cubemaps dans corriger les reflets des cubemaps.

Ne touche pas à bspzip -deletecubemaps sur une map packée : d’après le wiki de Valve, la commande supprime tous les fichiers VTF du pakfile et pas seulement les cubemaps.

Compresser le BSP : bspzip -repack -compress

bspzip peut repacker un BSP terminé et le compresser en LZMA au passage. Le fichier reste un .bsp. D’après le wiki de Valve, le moteur de GMod charge ces maps, et le changelog de GMod de mars 2025 mentionne explicitement la décompression LZMA pour les fichiers BSP.

Le hic, c’est l’outil. Le bspzip de GMod cite l’option dans son texte d’aide, mais dans notre test (build du 3 septembre 2026, 32 et 64 bits), il s’est arrêté sur -repack -compress avec le code de sortie 1, sans aucune sortie, et a laissé le fichier inchangé. -repack seul fonctionnait. Pour GMod, le wiki de Valve renvoie donc au bspzip de Team Fortress 2. C’est avec lui que nous avons compressé des copies des deux maps d’origine :

MapOriginalBSP compressé en LZMAOriginal en .bz2
gm_construct36,7 Mo10,1 Mo12,4 Mo
gm_flatgrass47,4 Mo12,6 Mo13,9 Mo

Nous n’avons pas vérifié en jeu si GMod charge précisément ces fichiers sans erreur. Teste donc toi-même une map compressée sur le client et sur le serveur. Le wiki de Valve cite en outre trois restrictions, qui déterminent l’ordre :

  1. Packe d’abord tout le contenu. bspzip ne packe rien dans un BSP compressé, il te faudrait donc le décompresser de nouveau avec -repack sans -compress.
  2. Génère ensuite les cubemaps pour le LDR et le HDR. Sur une map compressée, buildcubemaps plante.
  3. Compresse en dernier et vérifie les sons. Pour les sons packés au format ADPCM, le wiki documente des erreurs de lecture, testées là-bas dans Team Fortress 2 et Counter-Strike: Source.

Pourquoi la taille compte pour les serveurs

Chaque joueur a besoin du BSP en local avant de rejoindre le serveur. Avec FastDL, le client demande d’abord une version .bz2, et avec le Workshop, l’addon est compressé à l’upload. La taille sur le disque n’est donc pas la taille du téléchargement. Les différentes voies sont détaillées dans FastDL ou Workshop.

Le tableau ci-dessus montre ce qui en découle : le BSP compressé en LZMA n’est que 9 à 19 % plus petit que le .bz2 de l’original, et emballer en plus un BSP compressé en .bz2 a changé la taille de moins de 1 % dans notre test. L’un des deux fichiers a même légèrement grossi. La compression économise donc surtout de l’espace disque sur le serveur et sur la machine du joueur, ainsi que du temps de téléchargement là où aucun .bz2 n’est disponible. Ce que tu économises sur les lightmaps, les cubemaps et les textures, en revanche, profite à toutes les voies et réduit aussi ce que le jeu doit charger en mémoire.

Questions fréquentes

Pourquoi ma map est-elle soudain beaucoup plus grosse après buildcubemaps ?

Les cubemaps sont écrites dans le pakfile sous forme de textures, en deux versions pour une map HDR. Des valeurs élevées de « Cubemap Size » et de nombreuses entités env_cubemap atteignent vite des dizaines de mégaoctets. Vérifie les tailles avec bspzip -extract.

Un BSP plus petit rend-il la map plus rapide en jeu ?

Pas directement. Le framerate dépend surtout de la quantité que le moteur dessine par image. Des lightmaps plus grossières et des textures plus petites économisent en revanche de la mémoire et du temps de chargement. Ce qui détermine le framerate est expliqué dans optimiser les performances d’une map GMod.

Existe-t-il une taille de fichier maximale pour un BSP ?

Nous ne pouvons pas confirmer de limite supérieure fixe pour l’ensemble du fichier dans GMod. Ce qui est limité, ce sont certaines zones de données, voir les limites des maps Source, et le téléchargement direct depuis le serveur de jeu. En pratique, c’est le temps d’attente des joueurs qui fixe la limite.

Puis-je encore modifier un BSP compressé par la suite ?

Oui, mais pas directement. Décompresse-le avec bspzip -repack sans -compress, fais la modification et compresse de nouveau. Une nouvelle compilation produit de toute façon un BSP neuf, non compressé.