# 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, …): ```sh 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 `fetch`es 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`](docs/PROJECT_NOTES.md). - Phaser is imported only via `js/vendor/phaser.js` (one-file version swap). ## Dev tools ```sh 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.