Aller au contenu

Projets, bundles, releases

Cette page répond à la question qu'on se repose toutes les semaines : qu'est-ce qu'un bundle, où vit quoi, et qu'est-ce qui part sur la carte ?

Le vocabulaire, en une table

Mot Ce que c'est
Projet le jeu en cours d'écriture : ses .lua (main.lua, toujours) et ses .mask
Bibliothèque RAW les images chargées telles quelles, en vraies couleurs (RGB/RGBA) : tilesets, sprites, sprites animés
Bundle une série d'assets avec sa palette calculée sur l'ensemble, et ses variantes compatibles (mêmes index, autres couleurs : jour/nuit). C'est la seule forme indexée de l'art. Un jeu peut en avoir plusieurs
Attache « ce projet utilise le bundle B, vu par le jeu sous le nom G », une référence, pas une copie
Groupe (côté console) ce que la carte voit d'un bundle : G.pal, G.atlas, ses PNG indexés, ses variantes G.<v>.pal, ses fonds G-<f>.map + G-<f>-tiles.png
Release l'instantané publié : un dossier complet, les fichiers du projet plus les pièces de ses bundles attachés, figé, identifié par l'empreinte de son manifeste

Donc : un bundle de l'App = un groupe sur la console, et le « nom vu par le jeu » de l'attache est le nom du groupe : gfx.palette("G"), gfx.id("G/perso"). Ce nom suit la règle des groupes : minuscules, chiffres, souligné, pas de tiret (le tiret sépare un groupe de son fond).

Le firmware dit « le dossier du jeu » pour l'ensemble que gfx.bundle() compile d'un coup, tous les groupes. C'est le même objet que la release ici, et pas un bundle de l'App.

Un jeu est un dossier plat

Un jeu est un dossier plat de .lua, de .mask et des pièces de ses bundles, rien d'autre. Plat parce que require() l'est côté console : les mêmes règles des deux côtés, pour qu'un projet qui marche en ligne marche sur la carte.

Il est identifié par (compte, nom) et jamais par le pseudo, qui se change.

Les octets sont adressés par leur empreinte

Un fichier est rangé sous l'empreinte de son contenu, jamais sous un chemin de projet. Deux fichiers identiques, le cas normal dès le premier clone, partagent donc un seul objet : cloner un jeu ne copie aucun octet, seulement des lignes.

Ce qui va où, et pourquoi

  • .lua et .mask dans le projet. Le .mask est la géométrie de collision du niveau, dessinée à la main en ASCII : c'est du code, pas de l'art.
  • .map dans le bundle. La carte de tuiles d'un fond ne veut rien dire hors de son tileset ; les deux sont une pièce du groupe (G-<f>.map + G-<f>-tiles.png). Un .map arrivé avec un exemple importé est toléré comme fichier de projet.
  • Une seule palette par bundle, calculée sur tous ses assets. Un pixel indexé n'a de sens que dans la palette qui l'a produit : c'est pour cela qu'on ne quantifie jamais un asset seul, et que la console n'affiche à la fois que des sprites d'un même groupe (une seule palette active).
  • Publier matérialise. Une release doit se poser telle quelle sur une carte micro-SD ; elle embarque donc les pièces des bundles attachés, nommées comme le groupe. L'export .zip du brouillon fait pareil. Le projet, lui, ne garde que la référence : retoucher un bundle change la prochaine publication, pas la précédente.
  • Un asset employé par un bundle ne se supprime pas, un bundle attaché à un projet non plus. L'App le refuse, parce que sinon un jeu cesserait de se charger loin de la cause.

Les noms, et leur borne

Un nom complet, <groupe>/<région> pour gfx.id(), <groupe>-<fond> pour gfx.background(), tient dans les tampons de 48 octets de la console et du simulateur : 47 caractères au plus. Ce nom n'existe pas tant que le groupe (le nom vu par le jeu, choisi à l'attache) n'est pas choisi ; la somme se vérifie donc aux deux moments où elle peut naître, à l'attache, et au recalcul d'un bundle déjà attaché, avec un refus qui nomme le fautif. Chaque moitié garde sa règle propre (60 au plus), aucune paire qui tient n'est interdite.