Projets, cartes, niveaux, releases¶
Cette page répond à la question qu'on se repose toutes les semaines : qu'est-ce qui compile l'art d'un jeu, où vit quoi, et qu'est-ce qui part sur la console ?
Le vocabulaire, en une table¶
| Mot | Ce que c'est |
|---|---|
| Projet | le jeu en cours d'écriture : ses .lua (main.lua, toujours), ses .mask, ses sons |
| Bibliothèque | les sprites chargés tels quels, en vraies couleurs (RGB/RGBA) : un sprite seul, ou une ligne d'animation |
| Modèle | ce qu'un niveau place : une boîte de collision, une ancre, et des états (repos, marche, saut…), chacun sur un sprite de la bibliothèque avec sa cadence, sa boucle et son effet (alpha, contour, derrière le fond). Le joueur est un modèle, une torche aussi. Partagé par tous les niveaux du compte |
| Carte | le dessin : des calques de tuiles de 8×8, des tampons et des terrains, des décors posés sur les calques (grilles de tuiles à masque propre), et un calque de collision. Une carte ne place aucun objet et ne se compile pas seule |
| Niveau | une carte et ce qui s'y joue : les objets (des modèles posés au pixel), les réglages de compilation et un aperçu. C'est le niveau qui compile : les calques aplatis de sa carte deviennent le fond, les sprites de ses modèles sont quantifiés avec lui, en une seule palette. Plusieurs niveaux peuvent partager une carte |
| Attache | « ce projet embarque le niveau N » : ce que la compilation fait quand le projet est coché. Une référence, pas une copie |
| Groupe (côté console) | ce que la console voit d'un niveau : N.pal, N.atlas, ses PNG indexés, ses variantes N.<v>.pal, son fond N-fond.map + N-fond-tiles.png |
| Release | l'instantané publié : un dossier complet, les fichiers du projet plus les pièces de ses niveaux attachés, figé, identifié par l'empreinte de son manifeste |
Donc : un niveau de l'App = un groupe sur la console, du nom du niveau : gfx.background("niveau2-fond"), phy.anim_load("niveau2/torche_4"), gfx.id("niveau2/torche_4_0"). Ce nom suit la règle des groupes : minuscules, chiffres, souligné, pas de tiret (le tiret sépare le niveau de son fond). Le nom d'une carte n'arrive pas jusqu'à la console : seul celui du niveau.
Le firmware dit « le dossier du jeu » pour l'ensemble que gfx.bundle() compile d'un coup, tous les niveaux. C'est le même objet que la release ici.
Un jeu est un dossier plat¶
Un jeu est un dossier plat de .lua, de .mask, de sons et des pièces de ses niveaux, 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 console.
Il est identifié par (compte, nom) et jamais par le pseudo, qui se change.
Les octets s'adressent 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¶
- Les
.luaet.maskdans le projet. Compiler un niveau, projet coché, y écrit deux fichiers :<niveau>.mask, la géométrie de collision, une case par tuile, tirée du calque de collision de sa carte et des masques des décors qui y sont posés ; et<niveau>.lua, les données et les fabriques du niveau (dimensions, fond, modèles, objets,charger(),creer(),instancier(),decharger()), que le jeu charge parrequire("<niveau>"). Ce.luaporte un marqueur sur sa première ligne ; un.luadu même nom écrit à la main n'est jamais écrasé : la compilation le dit et passe. Le.maskn'a pas de marqueur : il est réécrit à chaque compilation. - Le fond vient de la carte. Les calques dessinés sont aplatis, quantifiés avec les sprites, puis retuilés pour la console (tuiles distinctes par fréquence, miroirs fusionnés, 704 au plus, regroupement par ressemblance au-delà). Il sort en deux pièces,
<niveau>-fond.mapet<niveau>-fond-tiles.png. La carte reste la source ; le.mapest un produit. - Un niveau compilé sur une carte plus ancienne est périmé. Retoucher une carte ne change rien aux jeux tant que ses niveaux ne sont pas recompilés ; l'atelier les marque recompile, et publier un jeu est refusé tant qu'un de ses niveaux est périmé, pour que le jeu et ses niveaux publiés montrent le même dessin.
- Une palette par niveau, calculée sur le fond et tous les sprites posés. Un pixel indexé n'a de sens que dans la palette qui l'a produit : c'est pourquoi un sprite n'est jamais quantifié seul, et pourquoi la console n'affiche les sprites que d'un groupe à la fois (une seule palette active). Un sprite n'entre dans un jeu que si un modèle qui le porte est posé dans un niveau, même invisible.
- Deux niveaux sur une carte font deux groupes. Chacun apporte sa palette et son fond, et les deux comptent dans les bornes de la console : partager une carte épargne du dessin, pas de la mémoire sur la console.
- Un effet est une propriété du bitmap. Additif, translucide, contour, derrière le fond : ce sont des rangées de palette. Ils se règlent par état de modèle, valent pour tous les niveaux, et un même sprite ne peut pas porter deux effets dans un niveau.
- Publier matérialise. Une release doit se poser telle quelle sur une carte micro-SD ; elle embarque donc les pièces des niveaux attachés. L'export
.zipdu brouillon fait de même. Le projet, lui, ne garde que la référence : recompiler un niveau change la prochaine publication, pas la précédente. - Ce qui sert ne se supprime pas. Un sprite qu'un niveau compilé pose, un modèle posé dans un niveau, une carte que des niveaux emploient, un niveau attaché à un projet : l'App refuse, car sinon un jeu cesserait de se charger loin de la cause. Retirez l'objet et recompilez ; supprimez ou déplacez d'abord les niveaux ; détachez le niveau du projet.
Les bornes de la console, comptées par projet¶
La console tient, par jeu, 12 palettes (niveaux + variantes), 16 fonds (un niveau en apporte un), 2 Mio de pièces graphiques, 1 024 sprites et 64 animations. Dans l'atelier, la fiche du projet (What the console allows) et le panneau Budget comptent les trois premières ; compiler un niveau refuse de l'attacher à un projet qu'il ferait déborder, et le dit. Les 64 animations se comptent par niveau chargé : ce sont les états des modèles qu'un niveau pose, et la compilation refuse un niveau qui en a plus ; M.decharger() les rend avant le niveau suivant.
Les noms, et leur borne¶
Un nom complet, <niveau>/<région> pour gfx.id(), <niveau>-fond pour gfx.background(), doit tenir dans les tampons de 48 octets de la console et du simulateur : 47 caractères au plus. La somme se vérifie à la compilation, avec un refus qui nomme le coupable. Chaque moitié garde sa propre règle (60 au plus), et aucune paire qui tient n'est interdite.
Licences et crédits¶
Tout ce qui entre dans l'atelier dit d'où il vient : un sprite, un son, une planche ou une image de décor importée dans une carte. Trois réponses : votre propre œuvre ; du CC0 venu d'ailleurs (domaine public ; un crédit est bienvenu) ; du CC BY 4.0 venu d'ailleurs, avec son crédit (l'auteur, et d'où ça vient), alors obligatoire. Un élément importé sans réponse est non déclaré : utilisable, mais rien de ce qui le contient ne se publie avant qu'il soit déclaré.
Une carte tient la liste de ses Sources : ce que ses imports ont apporté d'ailleurs. Ses tuiles se mélangent, alors le crédit suit la carte, pas chaque tuile. Une carte faite avant le suivi des sources est non revue tant que son auteur ne l'a pas revue.
Ce qui contient du CC BY se publie en CC BY, tous les crédits réunis, votre pseudo en tête : un niveau public, un jeu publié, qui porte alors un credits.txt à côté de ses fichiers. Sinon, vous choisissez CC0 ou CC BY. Publier demande toujours de cocher une case : un crédit faux fait retirer aussitôt ce qui est public, avec chaque niveau public et chaque jeu qui l'embarque ; les copies faites par d'autres sont signalées, pas effacées, jusqu'à ce que leur propriétaire corrige le crédit et lève le signalement.