---
title: VOID ATLAS
canonical: "https://presque.cool/projects/voidatlas/"
description: "Générateur procédural de planètes pour le RPG Mothership. Atmosphère, gravité, mystères, points d'intérêt — une planète complète en un clic."
---

<div data-lang="fr">

## Le pitch

VOID ATLAS est un générateur procédural de planètes pour Mothership, le RPG de SF horrifique. Un clic produit une planète complète : nom, taille, atmosphère, gravité, température, éléments communs et rares, durée du jour, points d'intérêt, et une section Warden avec les accroches narratives, features et mystères réservés au meneur. Le tout accompagné d'une visualisation SVG.

**Utiliser** : [presque.cool/voidatlas/](https://presque.cool/voidatlas/)

<div class="quick-overview">
  <div class="overview-item">
    <span class="overview-label">Durée</span>
    <span class="overview-value">v1 : 3 jours · v2 : 3 jours</span>
  </div>
  <div class="overview-item">
    <span class="overview-label">Période</span>
    <span class="overview-value">Avr 2023 → Avr 2026</span>
  </div>
  <div class="overview-item">
    <span class="overview-label">Stack</span>
    <div class="tech-tags">
      <span class="tech-tag">React</span>
      <span class="tech-tag">TypeScript</span>
      <span class="tech-tag">Vite</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>

---

## Pourquoi ce projet

VOID ATLAS est une rétro-ingénierie d'[Anodyne Printware](https://anodyneprintware.com/planets), un générateur de planètes créé par Matt Umland pour le supplément _Hull Breach Vol. 1_ de Mothership, avec des graphismes de Meredith Silver et des textes de Ian Yusem. L'outil a remporté le Gold ENNIE 2023 pour le Best Aid/Accessory Digital, une référence dans la communauté.

Deux choses m'ont accroché : le style graphique des planètes en SVG, et l'esthétique UI inspirée d'_Alien_. J'avais envie de faire du procgen et du SVG, et l'idée de reproduire cet outil pour mon usage personnel en y apportant mes propres ajouts était une bonne excuse.

Les ajouts par rapport à l'original : couleurs plus douces, meilleure lisibilité, traduction française, fonction de sauvegarde, partage par lien, version imprimable.

---

## Deux versions, trois jours chacune

La v1 date d'avril 2023 : un sprint de 3 jours en Svelte. Rétro-ingénierie directe de l'interface et de la logique de génération de Rimspace Planet Generator.

Trois ans plus tard, j'avais beaucoup plus d'expérience React et une envie de repartir sur une base propre. La v2 (avril 2026) est une réécriture complète en React + TypeScript : architecture plus solide, fonctionnalités supplémentaires, meilleure accessibilité. La v2 a aussi pris 3 jours.

---

## Le seed partageable

Chaque planète a un seed encodé dans l'URL. Ouvrir le lien reproduit la planète à l'identique. Les re-rolls individuels (un champ qu'on relance sans tout regenerer) sont aussi encodés : l'URL contient le seed de base plus les compteurs de re-rolls par champ.

Le mode de partage fait la distinction entre la vue Warden (meneur de jeu, données complètes) et la vue Joueur (les informations que les personnages peuvent scanner). Partager le lien en vue Joueur masque les accroches narratives côté destinataire.

---

## La génération

Les planètes sont produites par tirage dans des tables JSON : taille, température, gravité, atmosphère, éléments, lieux d'intérêt, et selon le type de planète (sèche, aqueuse, gazeuse), des tables spécifiques de features, hooks et mystères. Les noms sont composés de préfixes/suffixes issus de sources variées (noms bibliques, noms de dieux, Shakespeare).

La visualisation SVG superpose plusieurs couches : fond étoilé, corps planétaire avec texture et couleur, eau si planète aqueuse, anneaux si applicable, puis les points d'intérêt orbitaux (lunes, stations, vaisseaux, gates, ascenseurs orbitaux, anomalies). Quatre thèmes de couleur (vert, bleu, rouge, ambre) changent la palette sans toucher à la structure.

---

## Stack technique

<ul class="tech-stack">
<li><strong>React 19</strong> + <strong>TypeScript</strong> (strict, zero any)</li>
<li><strong>Vite 8</strong> comme bundler (avec plugin-react)</li>
<li><strong>Tailwind CSS v4</strong> en mode CSS-first (OKLCH)</li>
<li><strong>Zustand</strong> pour le state : settings, toasts</li>
<li><strong>PWA</strong> via vite-plugin-pwa (Workbox, installable, offline)</li>
<li><strong>i18n</strong> maison (français/anglais)</li>
<li><strong>CSP</strong> avec hashes auto-générés</li>
<li><strong>Compression</strong> Brotli + Gzip</li>
</ul>

Architecture : logique de génération dans `lib/planet.ts`, tables de contenu dans `data/` (JSON), types dans `types/planet.ts`, rendu SVG dans `components/planet/`. Le seed et les re-rolls sont résolus dans `lib/url.ts` avant tout rendu.

---

## Évolutions

| Date     | Version | Description                                                    |
| -------- | ------- | -------------------------------------------------------------- |
| Avr 2023 | 1.0     | Version Svelte — rétro-ingénierie de Rimspace Planet Generator |
| Avr 2026 | 2.0     | Refonte React : sauvegarde, partage, i18n                      |

---

## Bilan

**Durée** : 3 jours (v1) + 3 jours (v2).

**Ce que j'ai appris** :

- Repartir de zéro sur un projet existant après 3 ans de pratique est une expérience utile. Les 3 jours de la v2 produisent une codebase sensiblement plus propre que les 3 jours de la v1, à périmètre fonctionnel plus large.
- Les tables de contenu en JSON externalisées rendent la maintenance du corpus de textes indépendante du code. Ajouter 50 entrées à une table de mystères ne touche pas une ligne de TypeScript.

**Ce que je referais pareil** :

- Le seed dans l'URL comme mécanisme de partage. L'URL encode le seed, les re-rolls et le mode d'affichage ; aucun backend à maintenir, liens permanents. Pour un outil de table de jeu utilisé ponctuellement, c'est le bon compromis.
- La séparation vue Warden / vue Joueur encodée dans l'URL. Elle couvre le cas d'usage principal (le meneur partage une planète sans spoiler ses notes).

**Ce que je changerais** :

- La v1 en Svelte n’appelait pas de refonte urgente. Le passage à React était surtout une préférence plutôt qu’une obligation technique.

</div>

<div data-lang="en">

## The pitch

VOID ATLAS is a procedural planet generator for Mothership, the sci-fi horror RPG. One click produces a complete planet: name, size, atmosphere, gravity, temperature, common and rare elements, day length, points of interest, and a Warden section with narrative hooks, features and mysteries reserved for the GM. All accompanied by an SVG visualization.

**Use it**: [presque.cool/VOID ATLAS/](https://presque.cool/voidatlas/)

<div class="quick-overview">
  <div class="overview-item">
    <span class="overview-label">Duration</span>
    <span class="overview-value">v1: 3 days · v2: 3 days</span>
  </div>
  <div class="overview-item">
    <span class="overview-label">Period</span>
    <span class="overview-value">Apr 2023 → Apr 2026</span>
  </div>
  <div class="overview-item">
    <span class="overview-label">Stack</span>
    <div class="tech-tags">
      <span class="tech-tag">React</span>
      <span class="tech-tag">TypeScript</span>
      <span class="tech-tag">Vite</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>

---

## Why this project

VOID ATLAS is a reverse-engineering of [Rimspace Planet Generator](https://anodyneprintware.com/planets), a planet generator created by Matt Umland for the _Hull Breach Vol. 1_ supplement for Mothership, with graphics by Meredith Silver and text by Ian Yusem. The tool won the Gold ENNIE 2023 for Best Aid/Accessory Digital, a reference in the community.

Two things caught my attention: the SVG planet visuals, and the _Alien_-inspired UI aesthetic. I wanted to work with procedural generation and SVG, and reproducing this tool for my own use while adding my own features was a good excuse.

My additions over the original: softer colors, better readability, French translation, save feature, shareable link, printer-friendly view.

---

## Two versions, three days each

v1 was April 2023: a 3-day sprint in Svelte. A direct reverse-engineering of Anodyne Printware's interface and generation logic.

Three years later, with considerably more React experience and a cleaner architecture in mind, v2 (April 2026) was a complete rewrite in React + TypeScript: cleaner architecture, additional features, better accessibility. v2 also took 3 days.

---

## The shareable seed

Every planet has a seed encoded in the URL. Opening the link reproduces the exact same planet. Individual re-rolls (re-rolling one field without regenerating the whole planet) are also encoded: the URL holds the base seed plus per-field re-roll counts.

The share mode distinguishes between Warden view (GM, full data) and Player view (what player characters can scan). Sharing a Player link hides narrative hooks from the recipient.

---

## The generation

Planets are produced by drawing from JSON tables: size, temperature, gravity, atmosphere, elements, points of interest, and, depending on planet type (dry, watery, gaseous), specific tables of features, hooks, and mysteries. Names are composed from prefix/suffix pools drawn from varied sources (biblical names, deity names, Shakespeare).

The SVG visualization layers multiple components: starfield background, planet body with texture and color palette, water if applicable, rings if applicable, then orbital points of interest (moons, stations, ships, jump gates, orbital elevators, anomalies). Four color themes (green, blue, red, amber) swap the palette without touching the structure.

---

## Tech stack

<ul class="tech-stack">
<li><strong>React 19</strong> + <strong>TypeScript</strong> (strict, zero any)</li>
<li><strong>Vite 8</strong> as bundler (with plugin-react)</li>
<li><strong>Tailwind CSS v4</strong> in CSS-first mode (OKLCH)</li>
<li><strong>Zustand</strong> for state: settings, toasts</li>
<li><strong>PWA</strong> via vite-plugin-pwa (Workbox, installable, offline)</li>
<li><strong>i18n</strong> custom (French/English)</li>
<li><strong>CSP</strong> with auto-generated hashes</li>
<li><strong>Compression</strong> Brotli + Gzip</li>
</ul>

Architecture: generation logic in `lib/planet.ts`, content tables in `data/` (JSON), types in `types/planet.ts`, SVG rendering in `components/planet/`. Seed and re-roll counts are resolved in `lib/url.ts` before any rendering.

---

## Timeline

| Date     | Version | Description                                               |
| -------- | ------- | --------------------------------------------------------- |
| Apr 2023 | 1.0     | Svelte version — reverse-engineering of Anodyne Printware |
| Apr 2026 | 2.0     | React rewrite: save, share, i18n                          |

---

## Looking back

**Duration**: 3 days (v1) + 3 days (v2).

**What I learned**:

- Starting over on an existing project after 3 years of practice is a useful exercise. The 3 days of v2 produce a noticeably cleaner codebase than the 3 days of v1, with a wider feature set.
- Externalizing content tables as JSON keeps the text corpus maintenance independent from the code. Adding 50 entries to a mysteries table doesn't touch a line of TypeScript.

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

- The seed-in-URL sharing mechanism. The URL encodes the seed, re-rolls, and display mode; no backend to maintain, permanent links. For a tabletop tool used occasionally, that's the right trade-off.
- The Warden/Player view separation encoded in the URL. It covers the main use case: GM shares a planet without spoiling their notes.

**What I'd change**:

- The Svelte v1 did not call for an urgent rewrite. Moving to React was mostly a preference rather than a technical requirement.

</div>
