Go to file
Brian Fertig eafc3c4314 Add v0.2: seedable galaxy, system archetypes, and two-level procedural generation
- Main menu Galaxy Seed panel: displayed, editable, rerollable; the menu
  previews what the seed builds (galaxy name, scale, archetypes) before
  committing. Same seed always generates the same galaxy.
- js/galaxy/Galaxy.js: seeded roster of 40k systems (disk + core + spiral
  arms, type weights, radial bands) with spatial hash for neighbor queries;
  contents generated lazily on arrival — identical to eager generateAll()
  because each system draws from Rng.derive(seed, 'system', id).
- js/galaxy/SystemGenerator.js + data/systems.json: six themed archetypes
  whose attributes (star classes, planet count spread, class weights,
  moons, belts, habitability, hazard) steer content generation.
- data/galaxy.json layout/distribution knobs, incl. distribution.rules[]
  hook for future proximity/clustering rules; data/naming.json name pools.
- GameScene: current system name/identity HUD (lazy content generation
  on arrival); dev boot without a menu falls back to a dev galaxy.
- dev/galaxy.test.mjs: determinism, distribution, bands, lazy==eager,
  neighbor brute-force checks (40k roster in ~70ms).
- Docs: world model, determinism rules, roadmap update.
2026-09-03 10:49:22 -06:00
data Add v0.2: seedable galaxy, system archetypes, and two-level procedural generation 2026-09-03 10:49:22 -06:00
dev Add v0.2: seedable galaxy, system archetypes, and two-level procedural generation 2026-09-03 10:49:22 -06:00
docs Add v0.2: seedable galaxy, system archetypes, and two-level procedural generation 2026-09-03 10:49:22 -06:00
js Add v0.2: seedable galaxy, system archetypes, and two-level procedural generation 2026-09-03 10:49:22 -06:00
lib Add v0.1 foundation: menu, click-to-fly ship, and JSON config system 2026-09-02 22:31:34 -06:00
README.md Add v0.2: seedable galaxy, system archetypes, and two-level procedural generation 2026-09-03 10:49:22 -06:00
index.html Add v0.1 foundation: menu, click-to-fly ship, and JSON config system 2026-09-02 22:31:34 -06:00

README.md

Orbit

A procedurally generated space RPG in the spirit of Privateer, in top-down 2D. Built with Phaser 4 as plain ES6 modules — no build step, no package managers required to run.

Run it

Any static file server works (Python, Node, Caddy, nginx, …):

cd orbit
python3 -m http.server 8080
# → http://localhost:8080

Must be served over http(s) — opening index.html via file:// won't work, because the game uses ES modules and fetches its JSON config.

Current state — v0.2: a seedable galaxy

  • Main menu with New Game and a Galaxy Seed panel: the seed is displayed, editable (click it and type), and rerollable — and the menu shows what that seed builds (the galaxy's name, system count, archetype count) before you commit. Same seed ⇒ same galaxy.
  • Procedural galaxy: 40,000 star systems in a seeded disk + core + spiral arms (data/galaxy.json), typed into six themed archetypes (data/systems.json) with per-type distribution weights and radial bands — the first "how does the galaxy lay itself out" rules.
  • Two-level generation: the whole galaxy roster is generated at New Game (~70 ms); each system's planets/moons/belts are generated lazily on arrival, deterministically (seed + system id), so lazy and eager give identical results. The current system's name/identity shows top-left in the game scene.
  • Game screen with a basic top-down ship: click anywhere to fly there in infinite, unbounded space (system boundaries/jumps come next)
  • Camera gently trails the ship; the parallax starfield streams past while it flies and the view slowly recenters (≈1.5 s) once the ship comes to rest
  • Config-driven setup: every tunable value lives in data/*.json

Project layout

orbit/
├── index.html              # boots the game
├── data/                   # ← ALL tunable config (edit these freely)
│   ├── manifest.json       #   which config files exist
│   ├── game.json           #   dimensions, colors, starfield, …
│   ├── menu.json           #   menu text, colors, button layout, seed panel
│   ├── ship.json           #   ship feel: thrust, drag, maxSpeed, …
│   ├── galaxy.json         #   galaxy scale & shape (count, radius, spiral…)
│   ├── systems.json        #   system archetypes: theme, attributes, distribution
│   └── naming.json         #   syllable pools for names
├── lib/                    # vendored third-party libs (Phaser 4.2.1)
├── js/
│   ├── main.js             # entry point: load config → boot Phaser
│   ├── config/             # Config singleton, ConfigLoader, game config
│   ├── scenes/             # MenuScene, GameScene (thin, orchestration)
│   ├── entities/           # Ship (own behavior)
│   ├── galaxy/             # Galaxy (seeded world model), SystemGenerator
│   ├── ui/                 # MenuButton (reusable)
│   ├── visuals/            # Starfield (decorative)
│   ├── utils/              # small pure helpers (Color, Rng, NameGenerator)
│   └── vendor/             # shim to the vendored Phaser
└── docs/PROJECT_NOTES.md   # ← project conventions: read this

Conventions (short version)

  • Config in JSON. If a value might change, it goes in data/, not code. Add a file = one line in data/manifest.json.
  • One class per file, ES modules, scenes stay thin, entities own their behavior. Details in docs/PROJECT_NOTES.md.
  • Phaser is imported only via js/vendor/phaser.js (one-file version swap).

Dev tools

node dev/ship-behavior.test.mjs   # runs the real Ship.update() loop in Node
node dev/starfield.test.mjs       # runs the real Starfield.create() in Node
node dev/galaxy.test.mjs          # galaxy determinism, distribution, lazy vs eager

dev/test-game.html boots straight into the GameScene (no menu click), handy for manual testing of the flight feel.

Phaser

Phaser 4.2.1 is vendored at lib/phaser.min.js (UMD build, MIT license — see lib/PHASER_LICENSE.md). No internet or npm needed at runtime.