---
title: caravan of sidonia
canonical: "https://presque.cool/projects/caravan-of-sidonia/"
description: "Des montagnes procédurales en parallaxe, des étoiles filantes et de la radio ambient. Le successeur animé de Dune of Sidonia."
---

<div data-lang="fr">

## Le pitch

Caravan of Sidonia est un générateur de paysages aliens animés. Des chaînes de montagnes en parallaxe, des ciels générés, des étoiles filantes, de la radio ambient. On clique, un nouveau monde apparaît. On peut le partager via URL.

**Essayer** : [presque.cool/caravan-of-sidonia/](https://presque.cool/caravan-of-sidonia/)

<div class="quick-overview">
  <div class="overview-item">
    <span class="overview-label">Période</span>
    <span class="overview-value">Déc 2023 → Mars 2026</span>
  </div>
  <div class="overview-item">
    <span class="overview-label">Stack</span>
    <div class="tech-tags">
      <span class="tech-tag">Preact</span>
      <span class="tech-tag">TypeScript</span>
      <span class="tech-tag">Canvas API</span>
      <span class="tech-tag">PWA</span>
    </div>
  </div>
  <div class="overview-item">
    <span class="overview-label">Statut</span>
    <span class="overview-value accent">✓ En production</span>
  </div>
</div>

---

## Origine

Dune of Sidonia générait des paysages désertiques statiques. Le bilan de ce projet mentionnait déjà l'envie d'animer les dunes, de faire bouger les étoiles filantes. En décembre 2023, j'ai commencé à y répondre avec un nouveau projet plutôt qu'un patch sur l'ancien.

L'idée : passer de la carte postale au paysage vivant. Des montagnes qui défilent en parallaxe, des météores qui traversent le ciel, un mouvement permanent. Le nom "Caravan" est venu de là : quelque chose qui avance, qui traverse.

---

## Deux versions

**Prototype Vanilla JS (décembre 2023)** :
Le moteur de base. Génération procédurale de montagnes par ondes sinusoïdales, parallaxe multi-couches, étoiles et météores. Suffisant pour valider que l'animation fonctionnait, que le mouvement apportait ce qui manquait à Dune of Sidonia.

**Version Preact (mars 2026)** :
Réécriture complète pour l'intégrer à presque.cool. La génération de terrain est restée, mais tout le reste a été repensé. L'ajout principal : la radio ambient, empruntée à Orbital Drift. 3 stations de streaming (Dreamscapes, Chillwave, Lofi Radio via BoxRadio.net) qui accompagnent la contemplation. Un panneau de réglages, le support i18n, la PWA.

---

## Le terrain

7 couches de montagnes, chacune générée par un profil sinusoïdal. L'algorithme échantillonne 3000 points par couche, applique une pente variable (raide ou douce selon le seed) et empile les plans du plus lointain au plus proche.

Le parallaxe utilise le carré de la profondeur comme multiplicateur de vitesse. La couche 1 bouge à peine. La couche 7 défile vite. L'écart crée l'illusion de profondeur sans aucune 3D réelle.

Chaque couche reçoit un gradient de couleur qui se fond progressivement vers la teinte du ciel. Plus la couche est lointaine, plus elle se confond avec l'horizon. Les crêtes sont soulignées en noir pour découper les plans.

---

## Le ciel

Le seed détermine tout : la hauteur du gradient, les teintes (2 couleurs HSL interpolées), le nombre de soleils (0 à 5, avec 97% de chance d'en avoir au moins 1), la densité du champ d'étoiles.

Les étoiles (4000 par frame) se déplacent à des vitesses différentes selon leur couche, ce qui crée un second parallaxe, céleste cette fois. Les météores traversent le ciel avec une traînée lumineuse (composite operation `lighter`).

La vitesse de défilement peut être inversée selon le seed. Certains mondes avancent, d'autres reculent.

---

## Le seed

Le système de seed est hérité de Dune of Sidonia. Un entier 32 bits passé dans un PRNG xorshift32 produit une séquence déterministe. Le même seed génère toujours le même monde, partout.

L'encodage humain utilise le format `NN-LLLL-NN` (ex : `42-AXBQ-78`), soit environ 457 millions de mondes possibles. Le seed est stocké dans le hash de l'URL — un clic sur "partager" copie le lien, et les boutons back/forward du navigateur naviguent entre les mondes visités.

---

## La radio

Même principe qu'Orbital Drift : 3 stations de streaming ambient via BoxRadio.net. Volume persistant, station persistante, gestion propre de l'autoplay navigateur. La musique se coupe quand on quitte l'onglet (Visibility API) et reprend au retour.

C'est le genre de feature qui paraît secondaire sur le papier mais qui change complètement l'expérience. Un paysage silencieux, on le regarde 5 secondes. Avec de la musique ambient, on le laisse tourner.

---

## Stack technique

<ul class="tech-stack">
<li><strong>Preact</strong> + <strong>TypeScript</strong> — 3 KB de runtime</li>
<li><strong>Zustand</strong> — Préférences persistées en localStorage (langue, musique, station)</li>
<li><strong>Vite</strong> comme bundler</li>
<li><strong>Tailwind CSS</strong></li>
<li><strong>Canvas API</strong> — 7 couches de montagnes + ciel + étoiles + météores, le tout à 60 FPS</li>
<li><strong>PRNG xorshift32</strong> — Génération déterministe à partir d'un seed</li>
<li><strong>PWA</strong> — installable, offline</li>
<li><strong>i18n</strong> maison — français/anglais</li>
<li><strong>Compression</strong> — Brotli + Gzip sur les assets</li>
<li><strong>CSP</strong> — Content-Security-Policy avec hashes auto-générés</li>
</ul>

---

## Évolutions

| Date      | Version | Description                                                           |
| --------- | ------- | --------------------------------------------------------------------- |
| Déc 2023  | 1.0     | Prototype Vanilla JS — terrain parallaxe, étoiles, météores           |
| Mars 2026 | 2.0     | Refonte Preact — radio ambient, réglages, i18n, PWA pour presque.cool |

---

## Bilan

**Ce que j'ai appris** :

- La génération de terrain par ondes sinusoïdales avec parallaxe multi-couches, un cran au-dessus des gaussiennes de Dune of Sidonia
- L'optimisation Canvas pour de l'animation continue : canvas offscreen pour les éléments statiques (ciel, soleils), frame rate limiter, pré-allocation de couleurs pour réduire la pression GC
- La gestion du responsive en mode portrait (scaling uniforme + pan tactile horizontal)

**Ce que je referais pareil** :

- Commencer par la v1 en vanilla pour valider le concept visuel avant d'investir dans la stack finale
- Réutiliser le système de seed et le format d'encodage de Dune of Sidonia — ça évite de réinventer

**Ce que je changerais** :

- J'ajouterais plus de variété dans les éléments du paysage (végétation, structures, eau) pour casser la répétition des montagnes seules.

</div>

<div data-lang="en">

## The pitch

Caravan of Sidonia is an animated alien landscape generator. Parallax mountain ranges, generated skies, shooting stars, ambient radio. Click, a new world appears. Share it via URL.

**Try it**: [presque.cool/caravan-of-sidonia/](https://presque.cool/caravan-of-sidonia/)

<div class="quick-overview">
  <div class="overview-item">
    <span class="overview-label">Period</span>
    <span class="overview-value">Dec 2023 → Mar 2026</span>
  </div>
  <div class="overview-item">
    <span class="overview-label">Stack</span>
    <div class="tech-tags">
      <span class="tech-tag">Preact</span>
      <span class="tech-tag">TypeScript</span>
      <span class="tech-tag">Canvas API</span>
      <span class="tech-tag">PWA</span>
    </div>
  </div>
  <div class="overview-item">
    <span class="overview-label">Status</span>
    <span class="overview-value accent">✓ In production</span>
  </div>
</div>

---

## Origin

Dune of Sidonia generated static desert landscapes. Its retrospective already mentioned the desire to animate the dunes, to make the shooting stars move. In December 2023, I started answering that with a new project rather than patching the old one.

The idea: go from postcard to living landscape. Mountains scrolling in parallax, meteors crossing the sky, permanent movement. The name "Caravan" came from that — something that moves forward, that traverses.

---

## Two versions

**Vanilla JS prototype (December 2023)**:
The base engine. Procedural mountain generation via sine waves, multi-layer parallax, stars and meteors. Enough to validate that animation worked, that movement brought what Dune of Sidonia was missing.

**Preact version (March 2026)**:
Complete rewrite to integrate with presque.cool. Terrain generation stayed, everything else was rethought. The main addition: ambient radio, borrowed from Orbital Drift. 3 streaming stations (Dreamscapes, Chillwave, Lofi Radio via BoxRadio.net) to accompany contemplation. A settings panel, i18n support, PWA.

---

## The terrain

7 mountain layers, each generated from a sinusoidal profile. The algorithm samples 3,000 points per layer, applies variable slope (steep or gentle depending on the seed) and stacks the planes from farthest to nearest.

Parallax uses depth squared as a speed multiplier. Layer 1 barely moves. Layer 7 scrolls fast. The gap creates the illusion of depth without any real 3D.

Each layer receives a color gradient that progressively blends into the sky hue. The more distant the layer, the more it merges with the horizon. Ridges are outlined in black to separate the planes.

---

## The sky

The seed determines everything: gradient height, hues (2 interpolated HSL colors), sun count (0 to 5, with a 97% chance of at least 1), starfield density.

Stars (4,000 per frame) move at different speeds depending on their layer, creating a second parallax — celestial this time. Meteors cross the sky with luminous trails (composite operation `lighter`).

Scroll direction can be reversed depending on the seed. Some worlds move forward, others move backward.

---

## The seed

The seed system is inherited from Dune of Sidonia. A 32-bit integer fed into an xorshift32 PRNG produces a deterministic sequence. The same seed always generates the same world, everywhere.

Human encoding uses the `NN-LLLL-NN` format (e.g., `42-AXBQ-78`), representing roughly 457 million possible worlds. The seed is stored in the URL hash — clicking "share" copies the link, and the browser's back/forward buttons navigate between visited worlds.

---

## The radio

Same principle as Orbital Drift: 3 ambient streaming stations via BoxRadio.net. Persistent volume, persistent station, clean browser autoplay handling. Music cuts when you leave the tab (Visibility API) and resumes on return.

It's the kind of feature that seems secondary on paper but completely changes the experience. A silent landscape, you look at it for 5 seconds. With ambient music, you let it run.

---

## Tech stack

<ul class="tech-stack">
<li><strong>Preact</strong> + <strong>TypeScript</strong> — 3 KB runtime</li>
<li><strong>Zustand</strong> — Preferences persisted in localStorage (language, music, station)</li>
<li><strong>Vite</strong> as bundler</li>
<li><strong>Tailwind CSS</strong></li>
<li><strong>Canvas API</strong> — 7 mountain layers + sky + stars + meteors, all at 60 FPS</li>
<li><strong>PRNG xorshift32</strong> — Deterministic generation from a seed</li>
<li><strong>PWA</strong> — installable, offline</li>
<li><strong>i18n</strong> custom — French/English</li>
<li><strong>Compression</strong> — Brotli + Gzip on assets</li>
<li><strong>CSP</strong> — Content-Security-Policy with auto-generated hashes</li>
</ul>

---

## Timeline

| Date     | Version | Description                                                          |
| -------- | ------- | -------------------------------------------------------------------- |
| Dec 2023 | 1.0     | Vanilla JS prototype — parallax terrain, stars, meteors              |
| Mar 2026 | 2.0     | Preact rewrite — ambient radio, settings, i18n, PWA for presque.cool |

---

## Takeaways

**What I learned**:

- Terrain generation via sine waves with multi-layer parallax — a step up from Dune of Sidonia's Gaussians
- Canvas optimization for continuous animation: offscreen canvas for static elements (sky, suns), frame rate limiter, pre-allocated colors to reduce GC pressure
- Responsive handling in portrait mode (uniform scaling + horizontal touch pan)

**What I'd do the same**:

- Start with a vanilla v1 to validate the visual concept before investing in the final stack
- Reuse the seed system and encoding format from Dune of Sidonia — no need to reinvent

**What I'd change**:

- I'd add more variety to landscape elements (vegetation, structures, water) to break the repetition of mountains alone.

</div>
