# Orbit — Project Notes Working agreements and conventions for building this game. Read this before adding new systems — these are the rules that keep the project scalable. ## What we're building A procedurally generated space RPG in the spirit of **Privateer**, but in **top-down 2D**: stars/sectors you can jump between, ships to fly, crew, trading/economy, stations, quests — to be scoped as we go. **Hard technical constraints:** - Plain **ES6 modules**, no transpilation, no build step. - **No package managers required to run** — the game must work from any static HTTP server (the browser fetches everything). - Third-party libraries are **vendored** into `lib/` (right now: `lib/phaser.min.js`, Phaser 4.2.1 UMD build, see `lib/PHASER_LICENSE.md`). - Must be served over http(s), not `file://` (ES modules + `fetch` of JSON). ## Config lives in JSON (important) - Tunable data lives in `data/*.json`: dimensions, colors, text, physics, balance, spawn tables, and anything a non-programmer might want to tweak. - `data/manifest.json` lists which files to load. **Add a config file = drop it in `data/` + one line in the manifest.** It is then available as a section named after the file (`ship.json` → `config.get('ship.thrust')`). - Code reads config through the `config` singleton (`js/config/Config.js`): ```js import { config } from '../config/Config.js'; const thrust = config.get('ship.thrust', 900); const menu = config.section('menu', {}); ``` Always supply a sensible fallback so code never depends on a missing key. - **Rule of thumb:** if a value might ever change (balance, layout, copy, colors), it belongs in JSON, not code. Code owns *behavior*, JSON owns *parameters*. - Split config by concern as the game grows: `data/sectors.json` for world generation, `data/economy.json`, `data/ships.json`, `data/crew.json`, etc. One file per system beats one giant file. ## Code is modular & class-based (important) - One class per file, ES module exports, no globals (except the deliberate singletons: `config`). - Layering: - `js/scenes/` — Phaser scenes: state + orchestration only (thin classes) - `js/entities/` — in-world objects that own their behavior (Ship, NPC, …) - `js/ui/` — reusable UI components (MenuButton, panels, HUD) - `js/visuals/` — decorative, non-interactive visuals (Starfield, …) - `js/utils/` — small pure helpers (Color, math, rng) - `js/config/` — config loading + Phaser game config - `js/vendor/` — shims to pinned third-party libraries - Scenes stay thin: they compose entities/UI and wire input. They don't hold balance numbers or game rules. - Every class should be standalone-constructible: it takes what it needs (`scene`, config values) in its constructor rather than reaching for globals — that keeps things testable and reusable. - Entities drive themselves from their own `update(time, delta)` method, called by the owning scene (e.g. `GameScene.update`). If an entity ever needs the engine's auto-update instead, define `preUpdate` (the Phaser v4 hook — v4 does not auto-call `update`). - Import Phaser only through `js/vendor/phaser.js` — the single place that changes if we swap framework versions. ## Phaser version - Pinned: **Phaser 4.2.1** ("Giedi"), vendored in `lib/phaser.min.js`. - App code is v4-specific where v4 changed things (e.g. `Phaser.Math.Angle.RotateTo`, `banner: false`, `Clamp(value, min, max)`). - To upgrade: replace the vendored file + note the version here. ## Roadmap (working list, intentionally rough) - [x] v0.1 foundation — menu → New Game → click-to-fly ship - [ ] Decide the world model: **infinite open space for now** (ship flies unbounded; borders/sectors planned for later) — affects camera, starfield, and world gen - [ ] Procedural star map / sector generation (driven by `data/sectors.json`) - [ ] Ship input beyond click-to-fly (throttle/brake keys, manual rotation) - [ ] HUD (speed, sector name, later: fuel/crew) - [ ] Save/load (the `config` + entity split should make this tractable) - [ ] Economy/trading loop (the Privateer heart)