- TypeScript 97.8%
- JavaScript 1.8%
- HTML 0.3%
- CSS 0.1%
Full-screen loader (reusing the boot spinner look, cb-8yc) shown from Launch while the board fills (cb-134.23) and the ship settles over the spawn-grace window (cb-134.16); fades out to reveal a clean game once grace ends. |
||
|---|---|---|
| designs | ||
| poc/physics-engine-spike | ||
| src | ||
| .gitignore | ||
| eslint.config.js | ||
| index.html | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.app.json | ||
| tsconfig.json | ||
| tsconfig.node.json | ||
| vite.config.ts | ||
Celilo Blast — Ship Designer
A web tool for designing procedural spaceships for Celilo Blast. Randomize a ship, tweak every field of its genome by hand, and save/export the ones you like. Ships are stored as plain ShipSpec data (not images), so the same spec can be handed to any renderer in the game.
Prerequisites
- Node.js 18+ (developed on Node 24; any modern LTS works)
- npm (this repo ships a
package-lock.json)
Install
npm install
Run (dev)
npm run dev
Vite serves the app at http://localhost:5173 (it prints the URL on start).
Build & preview
npm run build # type-checks (tsc -b) and builds to dist/
npm run preview # serves the production build locally
Other scripts: npm run typecheck (types only), npm run lint (ESLint).
Test
npm test # Vitest, single run
npx vitest # watch mode
Unit tests (src/**/*.test.ts, Vitest — pixi-free/Node, no browser needed)
guard the paths that actually broke or are fragile:
- spec load/migration —
loadShips()/parseSpec()upgrade legacy/partial/garbage specs againstDEFAULT_SHIPwithout ever crashing the renderer (the cb-185 bug). - renderer/firing tolerance —
firingOrigins()(the pixi-free twin of the renderer's weapon placement) handles hardpoints missing later-added fields (angle,weapon) with no unguarded access. - background scroll — decoration defaults, and the tile-recycle math
(
advanceStrip) stays contiguous forever (no gaps, no leaks).
The older hand-run src/**/*.check.ts self-checks are folded in via
src/checks.test.ts, so npm test runs everything in one command.
Using the tool
The layout is a top toolbar, a Controls panel on the left, the live ship in the middle, and a Gallery on the right.
- 🎲 Randomize — generate a fresh ship from a random seed. The current seed is shown in the toolbar, so a ship is reproducible from its seed.
- Controls panel — every ShipSpec field is a live control: hull length/width, silhouette, cockpit, wings, engines, palette colors, greebles, seed, and weapon hardpoints (add/remove). Edits re-render the ship instantly.
- Save — names the ship and stores it (with a thumbnail) in your browser's localStorage.
- Gallery — Load, Dup (duplicate), or Del (delete) any saved ship.
- Export — download the current ship as a
.jsonspec for sharing. - Import — load a
.jsonspec exported from anywhere.
Saved ships live in localStorage under the celilo-blast:ships key — they
persist in that browser until you delete them or clear site data.
Tech stack
React 19 + Vite 6 + TypeScript, with PixiJS 8 for rendering. Ships are
renderer-agnostic ShipSpec data; the Pixi renderer is just one consumer of it.
Project structure
src/
ship/
spec.ts ShipSpec genome + DEFAULT_SHIP
randomizer.ts seeded "cool ship" generator
renderer.ts draws a ShipSpec with PixiJS
storage/
shipStore.ts localStorage gallery + export/import
components/
Toolbar.tsx randomize / save / export / import
ControlsPanel.tsx live field-by-field editor
Canvas.tsx Pixi canvas + thumbnail snapshots
Gallery.tsx saved-ship grid (load/dup/delete)
App.tsx wires it all together
main.tsx React entry point