Documentation → API

API locale de génération de skins

Un générateur compatible Starlight, servi depuis ce domaine, à partir des assets archivés. Fonctionne même si le service d'origine est hors ligne.

Principe

L'API compose les gabarits archivés dans l'ordre de superposition mesuré, applique les couleurs demandées, et renvoie un PNG 64×64 utilisable directement comme skin Minecraft. Aucune requête n'est faite vers Starlight : tout est calculé localement, sans dépendance externe — le codec PNG lui-même est écrit à la main.

18
groupes de layers
374
variantes
11
palettes
257
couleurs nommées

Les endpoints

RouteRéponse
GET /api/healthÉtat du service
GET /api/infoCatalogue complet : groupes, cosmétiques, palettes, ordre des layers
GET /api/create-skin/:base/:couleur/:morpho/?…image/png 64×64
GET /api/skin?…Idem, forme à plat

La première forme reprend volontairement la structure d'URL d'origine (/create-skin/:base_texture/:base_color/:skinType/) : basculer d'un service à l'autre ne demande que de changer le nom d'hôte et de préfixer par /api.

Débogage

Ajoutez &debug=1 pour obtenir, au lieu du PNG, la liste des layers réellement composés et les avertissements éventuels. Pratique pour comprendre pourquoi un cosmétique n'apparaît pas.

Paramètres

Pour chaque groupe, trois à quatre paramètres, nommés comme en amont :

<groupe>_texture             nom du cosmétique, ou "none"
<groupe>_color               couleur de la zone primaire
<groupe>_color_secondary     couleur de la zone secondaire
<groupe>_alignment           uniquement eyes (high|middle|low) et mouth (high|low)

Les groupes disponibles : base, makeup, gloves, mouth, socks, top, top_designs, bottom, footwear, middlewear, outerwear, facial_hair, hair_style, eyes, eyebrow, face_item, headwear, ears.

skin_type vaut wide ou slim. Seuls quatre groupes diffèrent réellement entre les deux morphologies ; pour les autres, la variante wide est réutilisée automatiquement.

Valeurs par défaut

Une couleur omise reprend la valeur par défaut du moteur d'origine, pas celle de l'autre zone. C'est important : les yeux ont une secondaire par défaut à white (le blanc de l'œil). Refléter la primaire y peindrait l'œil entier d'une seule couleur.

Couleurs

Hexadécimal

$rrggbb (encodé %24rrggbb dans une URL) ou #rrggbb.

La teinte est appliquée par la rampe multiplicative à 8 niveaux. C'est le mode le plus fidèle : écart maximal de 1/255.

Nom de palette

red, crimson, tan… selon la palette du cosmétique.

Ces couleurs ne passent pas par la rampe : chacune porte un nuancier dessiné à la main, capturé depuis le moteur d'origine.

La liste des palettes et de leurs couleurs est dans /api/info, sous la clé palettes. Chaque cosmétique indique sa palette via color_template.

Ordre de superposition

Le manifest d'origine ne contient aucun z-index. L'ordre a donc été mesuré : pour chaque paire de groupes qui se recouvrent, un rendu avec deux couleurs distinctes révèle lequel est dessiné au-dessus. 153 paires testées, zéro incohérence avec l'ordre total obtenu.

base → makeup → gloves → mouth → socks → top → top_designs → bottom
     → footwear → middlewear → outerwear → facial_hair → hair_style
     → eyes → eyebrow → face_item → headwear → ears

Il correspond à l'anatomie : le corps, puis ce qui se pose dessus, puis les vêtements du plus près au plus loin de la peau, puis le visage, puis ce qui se porte sur la tête.

Exemples

Une tenue simple

https://skins.coruitech.dev/api/create-skin/male/tan/wide/
  ?top_texture=basic&top_color=%243366cc
  &bottom_texture=jeans&bottom_color=%234682b4

Deux zones et un motif

https://skins.coruitech.dev/api/create-skin/none/white/wide/
  ?top_texture=chef_shirt&top_color=white&top_color_secondary=red
  &top_designs_texture=cake&top_designs_color=black

Un visage

https://skins.coruitech.dev/api/create-skin/male/tan/wide/
  ?eyes_texture=big_ol_eyes&eyes_color=green&eyes_alignment=middle
  &mouth_texture=basic&mouth_color=tan&mouth_alignment=high
  &eyebrow_texture=basic&eyebrow_color=brown

Lister ce qui existe

curl -s https://skins.coruitech.dev/api/info | jq '.groups.top.cosmetics[].name'
curl -s https://skins.coruitech.dev/api/info | jq '.palettes.default'

Fidélité mesurée

Chaque cas est composé localement, demandé en parallèle au service d'origine, et comparé pixel par pixel. Les 8 pixels de la bande de calibration sont comptés à part : ils sont une métadonnée du moteur amont, pas du contenu.

CasÉcart moyenÉcart maxAlpha
t-shirt + jean, couleurs hex0,11410
chef + motif, couleurs nommées0,00000
visage complet, couleurs nommées0,00000
corps + vêtements clairs1,273170
tenue empilée avec outerwear2,13625513

Deux cas sont identiques au bit près. Les deux derniers relèvent des limites décrites ci-dessous.

Limites connues

1. Occlusion entre vêtements superposés

Quand un outerwear est présent, le moteur d'origine supprime quelques pixels du top dans la couche overlay (y ≥ 32) — y compris là où l'outerwear ne dessine rien. Sur le cas testé : 13 pixels sur environ 860, soit 1,5 %.

Ce n'est pas une simple suppression en bloc : sur 16 pixels du top non recouverts, 13 disparaissent et 3 subsistent. Modéliser la règle exactement demanderait de capturer un masque d'occlusion par paire de layers. Non fait pour l'instant.

2. Compression de la rampe sur les couleurs claires

Au-delà d'environ 190 sur un canal, le niveau le plus clair (×1,348) dépasserait 255. Le moteur d'origine comprime alors toute la rampe au lieu de simplement plafonner. Sur $e0e0e0, le niveau le plus sombre vaut ×0,897 en amont contre ×0,823 en local — un écart de 17/255.

Aucun modèle testé (HSL, HSV, luma pondérée, multiplication en lumière linéaire) ne rend compte de cette compression. Les couleurs dont tous les canaux restent sous 190 ne sont pas concernées.

3. Modificateurs de coiffure non archivés

hair_texture, hair_pattern_texture et hair_extension_front/back_texture ne sont pas des layers indépendants : ils modifient le rendu de hair_style. Le premier change son ombrage, le deuxième repeint une zone, les extensions ajoutent de la géométrie.

Les archiver exhaustivement demanderait 29 × 7 × 6 × 4 × 8 ≈ 39 000 combinaisons. hair_style seul est donc supporté ; ces quatre groupes sont listés dans /api/info sous unsupported.

4. Nuanciers nommés partiellement observables

Certains niveaux d'ombrage ne sont visibles sur aucun cosmétique d'une palette donnée — et la bande de calibration, qui les révélerait, n'est émise que sur le chemin $hex. Les niveaux manquants sont interpolés linéairement entre les nuances observées. Les deux cas à couleurs nommées testés ressortent malgré tout exacts.

Déploiement

ÉlémentValeur
Servicestarlight-local.service (systemd, redémarrage automatique)
ProcessusNode 24, écoute sur 127.0.0.1:3110
ExpositionReverse proxy /api créé via l'API aaPanel
Dépendancesaucune — codec PNG écrit à la main
DurcissementProtectSystem=strict, NoNewPrivileges, utilisateur www

Le proxy apparaît dans l'onglet « Reverse proxy » du site dans aaPanel, exactement comme s'il avait été créé depuis l'interface.