Add project README

This commit is contained in:
2026-06-17 11:42:50 +10:00
parent 6fc4d62342
commit ce81534bdc
+71 -2
View File
@@ -1,3 +1,72 @@
# newbury-nights
# Newbury Nights
Fan-made AR ghost-hunting web app — tribute to LEGO Hidden Side AR mechanics. Node/Express + SQLite + Three.js. Not affiliated with the LEGO Group.
A fan-made AR ghost-hunting web app — a tribute to the AR mechanics of the LEGO® Hidden Side™ app. The focus is the **Hunter Mode** AR loop: raise your phone as a ghost detector, scan the colour wheel to uncover gloom, lock on, and blast ghosts down before your battery dies.
> Fan-made tribute. Not affiliated with, sponsored by, or endorsed by the LEGO Group. LEGO® and Hidden Side™ are trademarks of the LEGO Group.
## What's inside
- **Backend** — Node + Express 5, SQLite via `better-sqlite3`, bcrypt password hashing, JWT auth (8h), multer image uploads.
- **Frontend** — Three.js (ES module import maps via CDN), `getUserMedia` camera passthrough with `DeviceOrientation` gyro look (iOS Safari friendly), `BarcodeDetector` QR scanning with a manual code fallback.
- **Ghost rendering** — animated-GIF billboards (texture pumped via `texture.needsUpdate` each frame) when a ghost has an uploaded image; procedural Three.js wisp meshes otherwise.
- **Spawning** — rarity-weighted: ★ common down to ★★★★ legendary.
- **Admin panel** (`/admin`) — JWT-gated. Upload / enable / disable / delete ghost images, create sets with scan codes linked to ghost rosters (many-to-many via `set_ghosts`).
- **Public endpoint** — `GET /api/scan/:code` requires no auth and returns a set's ghost roster.
## Data
The ghost roster, stats, abilities, and boss→set references are seeded from `data/*.json`, which are generated from the source spreadsheet by `scripts/extract_ghosts.py`. Three ghost types (red / yellow / blue) and four rarity tiers drive the colour-wheel and damage mechanics.
To regenerate the JSON from a spreadsheet:
```bash
python3 scripts/extract_ghosts.py path/to/Ghost_Data.xlsx data
```
## Setup
Requires Node 18+ and `build-essential` on Ubuntu (so `better-sqlite3` can compile its native module):
```bash
sudo apt-get install -y build-essential
npm install
cp .env.example .env # then edit JWT_SECRET and admin creds
npm run seed # creates the DB, seeds ghosts/sets, bootstraps admin
npm start
```
The app listens on `PORT` (default 3000) over plain HTTP — **nginx terminates HTTPS in front of it**. `app.set('trust proxy', 1)` is set so secure cookies work behind the proxy.
Re-running `npm run seed` is safe: it only seeds ghost/set data when the `ghosts` table is empty, so it won't clobber admin edits. It always ensures an admin user exists.
## nginx
See `deploy/nginx.conf.example` for a reverse-proxy block. Camera and gyro APIs require a secure context, so the site must be served over HTTPS (which nginx already handles for you).
## API quick reference
Public:
- `GET /api/scan/:code` — set roster + boss for a scan code
- `GET /api/freehunt?n=&type=` — rarity-weighted random spawns
- `GET /api/ghosts?type=&rarity=&boss=` — public ghost index (enabled only)
- `GET /api/abilities` — ability reference
Auth:
- `POST /auth/login` · `POST /auth/logout` · `GET /auth/me` · `POST /auth/change-password`
Admin (JWT required):
- `GET/POST /api/admin/ghosts`, `PATCH/DELETE /api/admin/ghosts/:id`, `POST /api/admin/ghosts/:id/image`
- `GET/POST /api/admin/sets`, `PATCH/DELETE /api/admin/sets/:id`, `PUT /api/admin/sets/:id/roster`
## Project layout
```
server.js Express app + static hosting
db/index.js SQLite schema + connection
routes/ auth, public api, admin api, auth middleware
scripts/extract_ghosts.py xlsx -> data/*.json
scripts/seed.js seed DB from data/*.json + bootstrap admin
data/ ghosts.json, abilities.json, sets.json
public/ index.html (game), admin.html, css/, js/
uploads/ uploaded ghost billboards (gitignored)
```