Skip to content

Anatomie d'un BodyConfig

BodyConfig est l'unique objet que vous passez à useBody. Plutôt qu'une interface plate, c'est une union discriminée sur type ('planetary' | 'star'), composée par intersection de 4 sous-profiles orthogonaux. Cette page sert de carte mentale : que met-on, où, et pourquoi.

ts
type PlanetConfig = PlanetIdentity & PlanetPhysics & BodyNoiseProfile & PlanetVisualProfile
type StarConfig   = StarIdentity   & StarPhysics   & BodyNoiseProfile
type BodyConfig   = PlanetConfig | StarConfig

Pour la motivation conceptuelle (pourquoi une union discriminée, sim vs render, déterminisme), voir Concepts fondamentaux.


1. Identity — qui est ce corps ?

Champs minimaux pour identifier le corps. Le name est la graine déterministe : deux corps avec le même name produisent les mêmes tuiles, le même relief, la même variation visuelle.

ChampTypeBranchesRôle
type'planetary' | 'star'les deuxDiscriminant — narrowing TypeScript
namestringles deuxSeed déterministe pour toute génération procédurale
surfaceLook?'terrain' | 'bands' | 'metallic'planetArchétype visuel — pilote palette + matériau + shader
spectralType'O' | 'B' | 'A' | 'F' | 'G' | 'K' | 'M'starClassification Morgan-Keenan — pilote toutes les dérivations stellaires (palette, granulation, godrays)

Référence : PlanetIdentity, StarIdentity.

2. Physics — géométrie, rotation, structure radiale

Cœur physique partagé + extensions planet-only. La lib est agnostique du climat : aucun champ de température n'est lu, le caller pousse les conséquences (couleur d'océan, état liquide…) via les profiles visuels.

Cœur partagé (BodyPhysicsCore)

ChampTypeDéfautRôle
radiusnumberrequisRayon visuel (world units). Pilote aussi le nombre de bandes de terrain.
rotationSpeednumberrequisAuto-rotation (rad/s).
axialTiltnumberrequisInclinaison axiale (radians).
mass?numberdérivéMasse en masses terrestres.
coreRadiusRatio?number0.55Ratio noyau/silhouette. Override > dérivation gasMassFraction > défaut.

Planet-only (PlanetPhysics)

ChampTypeDéfautRôle
atmosphereThickness?[0, 1]par surfaceLookFraction radiale réservée à la coquille atmo. 0 = pas d'atmo.
atmosphereOpacity?[0, 1]par surfaceLookOpacité du halo en vue shader.
gasMassFraction?[0, 1]Fraction massique d'enveloppe gazeuse — dérive coreRadiusRatio quand omis.
liquidState?'liquid' | 'frozen' | 'none''none'Phase de surface. 'liquid' monte une coquille animée ; 'frozen' est caller-owned.
liquidCoverage?[0, 1]0.5Proportion de tuiles sous le niveau liquide à la naissance du corps.

Les invariants subtils (le 5 % minimum de bande sol, l'ordre de résolution coreRadiusRatio) sont détaillés dans Concepts fondamentaux §8.

Référence : PlanetPhysics, StarPhysics.

3. NoiseProfile — relief et continents

Profile fBm partagé planet/star (les étoiles passent en flatSurface = true au niveau stratégie, le bruit est généré mais aplati). Toutes les valeurs sont optionnelles.

ChampTypeDéfautRôle
noiseScale?number1.4Fréquence simplex de base.
noiseOctaves?number1Nombre d'octaves fBm sommées.
noisePersistence?(0, 1]0.5Décroissance d'amplitude par octave.
noiseLacunarity?number2Multiplicateur de fréquence par octave.
noisePower?number1Reshape `sign(n) *
noiseRidge?[0, 1]0Mix vers ridge-multifractal (crêtes pointues).
continentAmount?[0, 1]0Masque voronoï basse fréquence — produit des continents discrets vs moiré FBm pur.
continentScale?[1, 3]1Fréquence du masque continents — moins, plus gros.
reliefFlatness?[0, 1]0Bias post-quantisation vers la bande la plus haute. 1 = perfectement plat à radius.

Référence : BodyNoiseProfile. Voir aussi l'exemple Profil de bruit.

4. VisualProfile — palette et features décoratives (planet-only)

Tunables visuels inline sur le config. Les étoiles n'ont pas de visual profile : leur look est entièrement dérivé de spectralType.

ChampTypeRôle
liquidColor?ColorInputRequis si liquidState !== 'none' — la lib n'a pas de fallback chimique.
bandColors?{ colorA, colorB, colorC, colorD }Palette 4 stops pour gas giants — caller-owned (Jupiter, Neptune…).
terrainColorLow?ColorInputAncre basse de la rampe rocheuse (bande la plus courte).
terrainColorHigh?ColorInputAncre haute de la rampe rocheuse (bande la plus haute).
metallicBands?[MetallicBand, ×4]Palette 4 bandes pour corps métalliques (cratère → plaines → highlands → pics).
hasRings?booleanActive un système d'anneaux décoratif.

bandColors, metallicBands, terrainColor* sont ignorés quand vous passez un palette complet via les options de useBody (cf. Palettes & terrain). La lib ne fusionne pas — c'est tout ou rien, par design.

Référence : PlanetVisualProfile, MetallicBand.

Cracks et lava ne sont pas dans BodyConfig — leur intensité vit sur BodyVariation (crackIntensity, lavaIntensity, lavaColor). C'est intentionnel : ce sont des effets visuels décidés par le gameplay, pas des propriétés physiques.


Options de useBody(config, tileSize, options?)

Le second argument tileSize pilote la taille apparente des hexagones (subdivisions dérivées). Le troisième est un sac d'options orthogonales — la plupart sont des hooks d'intégration plutôt que des paramètres procéduraux.

OptionTypeQuand l'utiliser
sunLight?PointLight | DirectionalLight | nullQuasi-toujours. La lib lit la position monde à chaque tick() pour pousser la direction lumière dans les shaders (terminator, godrays, halo atmo). Partagez la même instance entre tous les corps d'un système.
palette?TerrainLevel[]Quand vous voulez classifier par biome / climat / faction et imposer chaque bande. Remplace entièrement la palette auto-générée — les ancres terrainColor* / bandColors / metallicBands du config sont alors ignorées.
variation?BodyVariationVous voulez pinner une identité visuelle (intensité fissures, lave, granulation…) plutôt que la dériver du name. Sinon, dérivée auto. Voir Variation visuelle.
quality?RenderQualityProfil de qualité (subdivisions atmo, coût des shaders). À passer si vous gérez plusieurs niveaux globaux.
graphicsUniforms?GraphicsUniformsPool d'uniformes graphiques partagé entre corps. Voir Graphics uniforms.
hoverChannel?HoverChannelCanal partagé hover/sélection. Utile quand plusieurs UI (panneau d'info, surbrillance) doivent suivre la même tuile.
hoverCursor?HoverCursorConfigCurseur de survol custom — style unique. Voir Curseur de survol.
hoverCursors?HoverCursorPresetsPlusieurs presets nommés, swappés à runtime (mode build vs combat, etc.).
defaultCursor?stringNom du preset initial quand hoverCursors est fourni.

Si vous ne savez pas par où commencer : sunLight suffit pour un rendu correct. Tout le reste est de l'intégration avancée.


Exemple — planète rocheuse minimale

ts
import type { PlanetConfig } from '@cedric-pouilleux/stellexjs/sim'
import { useBody } from '@cedric-pouilleux/stellexjs/core'

const config: PlanetConfig = {
  // identity
  type:          'planetary',
  name:          'Kepler-22b',
  surfaceLook:   'terrain',
  // physics
  radius:        12,
  rotationSpeed: 0.001,
  axialTilt:     0.4,
  liquidState:   'liquid',
  liquidCoverage: 0.6,
  // noise
  continentAmount: 0.7,
  // visual
  liquidColor:   '#1d6fa5',
  terrainColorLow:  '#3a5a2b',
  terrainColorHigh: '#d8d3c2',
}

const body = useBody(config, /* tileSize */ 0.5, { sunLight })

Exemple — étoile

ts
import type { StarConfig } from '@cedric-pouilleux/stellexjs/sim'

const sun: StarConfig = {
  type:          'star',
  name:          'Sol',
  spectralType:  'G',
  radius:        80,
  rotationSpeed: 0.0002,
  axialTilt:     0,
}

const body = useBody(sun, /* tileSize */ 2)

Aucune palette, aucune ancre de couleur : tout dérive de spectralType. Tenter d'assigner surfaceLook ou metallicBands ici provoque une erreur à la compilation — c'est le bénéfice principal de l'union discriminée.


Pour aller plus loin

Distribué sous la licence indiquée dans le dépôt.