feat: Adding logging solution + alert for mobile phones
This commit is contained in:
98
README.md
98
README.md
@@ -1,16 +1,48 @@
|
||||
# Star Wars - Wild Space
|
||||
# Star Wars – Wild Space
|
||||
|
||||
Exploitable ring only (outer Ø100, inner Ø60). Planet positions are deterministic from the **server world seed**; **stats stay hidden** until you click a tile. Reveals are **persisted in PostgreSQL**.
|
||||
|
||||
> **Desktop only** — the galaxy map is not playable on phones or narrow screens (< 768 px wide).
|
||||
|
||||
## Layout
|
||||
|
||||
The UI is split into two panes:
|
||||
|
||||
| Pane | Content |
|
||||
|------|---------|
|
||||
| **Left column** | Title, team scores, player info, cooldown timer, world seed & period countdown, Refresh button, selection details |
|
||||
| **Right side** | Galaxy map — a perfect square anchored to the right edge of the viewport |
|
||||
|
||||
## Secrets & environment variables
|
||||
|
||||
**Never commit secrets.** All credentials live in **`.env`** (git-ignored).
|
||||
Copy the template and fill in your values before the first run:
|
||||
|
||||
```powershell
|
||||
cp .env.example .env
|
||||
# then edit .env
|
||||
```
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `JWT_SECRET` | Secret used to sign JWT tokens — use a long random string in production |
|
||||
| `POSTGRES_USER` | Game-DB username (default `game`) |
|
||||
| `POSTGRES_PASSWORD` | Game-DB password — **change in production** |
|
||||
| `POSTGRES_DB` | Game-DB name (default `star_wars_grid`) |
|
||||
| `POSTGRES_USERS_USER` | Users-DB username (default `users`) |
|
||||
| `POSTGRES_USERS_PASSWORD` | Users-DB password — **change in production** |
|
||||
| `POSTGRES_USERS_DB` | Users-DB name (default `star_wars_users`) |
|
||||
| `PORT` | HTTP port exposed by the app (default `8080`) |
|
||||
|
||||
## Runtime config (file + volume)
|
||||
|
||||
Edit **`config/game.settings.json`** on the host (mounted into the container at `/app/config/game.settings.json`). The server reloads it when the file’s **mtime** changes, on a schedule controlled by **`configReloadIntervalSeconds`** (minimum 5s), so frequent polling is avoided when nothing changed.
|
||||
Edit **`config/game.settings.json`** on the host (mounted into the container at `/app/config/game.settings.json`). The server reloads it when the file's **mtime** changes, on a schedule controlled by **`configReloadIntervalSeconds`** (minimum 5 s), so frequent polling is avoided when nothing changed.
|
||||
|
||||
| Field | Meaning |
|
||||
|--------|--------|
|
||||
|-------|---------|
|
||||
| `clickCooldownSeconds` | Cooldown between **new** reveals (same as before). |
|
||||
| `databaseWipeoutIntervalSeconds` | World period length in **seconds** (default `21600` = 6h). The **world seed** is `swg-<slot>` with `slot = floor(UTC unix seconds / this value)`. When the slot changes, **`grid_cells` is truncated** (full wipe). |
|
||||
| `debugModeForTeams` | If `true` or string `"true"` / `"True"` (case-insensitive), the **Blue / Red** segmented control is shown; if `false`, it is hidden. |
|
||||
| `databaseWipeoutIntervalSeconds` | World period length in **seconds** (default `21600` = 6 h). The **world seed** is `swg-<slot>` with `slot = floor(UTC unix seconds / this value)`. When the slot changes, **`grid_cells` is truncated** (full wipe). |
|
||||
| `debugModeForTeams` | If `true`, the **Blue / Red** segmented control is shown; if `false`, it is hidden. |
|
||||
| `configReloadIntervalSeconds` | How often the server **checks** the config file (mtime); also used by the client to poll `/api/config`. |
|
||||
|
||||
`GET /api/config` returns these values plus **`worldSeed`**, **`seedPeriodEndsAtUtc`**, **`seedPeriodStartsAtUtc`**.
|
||||
@@ -18,45 +50,73 @@ Edit **`config/game.settings.json`** on the host (mounted into the container at
|
||||
## Teams (blue / red)
|
||||
|
||||
- With **`debugModeForTeams`**: use the **Team** control (top-left) to switch perspective.
|
||||
- **Your** discovered tiles use your team color (blue: bright cyan; red: red when revealed). Unclaimed ring tiles use the **classic** idle tint for both teams.
|
||||
- **Your** discovered tiles use your team colour. Unclaimed ring tiles use the classic idle tint for both teams.
|
||||
- Tiles discovered by the **other** team appear **grey**, show **no planet**, and are **not clickable**. First reveal **owns** the tile (`discovered_by`).
|
||||
|
||||
## Cooldown
|
||||
|
||||
After revealing a **new** tile, a **cooldown** runs (top-right). During cooldown you **cannot reveal additional unseen tiles**, but you can still **click tiles your team already discovered** to view their stats.
|
||||
After revealing a **new** tile, a **cooldown** runs (left column). During cooldown you **cannot reveal additional unseen tiles**, but you can still **click tiles your team already discovered** to view their stats.
|
||||
|
||||
## Run with Docker Compose (Node + PostgreSQL)
|
||||
|
||||
From `d:\Users\GaWin\Travaux\Code\star_wars_grid_game`:
|
||||
### Prerequisites
|
||||
|
||||
```powershell
|
||||
docker compose up --build
|
||||
```
|
||||
1. Copy the environment template and set your secrets:
|
||||
```powershell
|
||||
cp star_wars_grid_game/.env.example star_wars_grid_game/.env
|
||||
# Edit .env — at minimum change JWT_SECRET, POSTGRES_PASSWORD, POSTGRES_USERS_PASSWORD
|
||||
```
|
||||
|
||||
Open `http://localhost:8080`.
|
||||
2. From `star_wars_grid_game/`:
|
||||
```powershell
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
- **App:** port `8080`
|
||||
- **Postgres:** port `5432` (user `game`, password `game`, database `star_wars_grid`)
|
||||
- **Config:** host folder **`./config`** is mounted to **`/app/config`** — edit `game.settings.json` without rebuilding the image.
|
||||
3. Open `http://localhost:8080`.
|
||||
|
||||
### Ports
|
||||
|
||||
| Service | Port | Notes |
|
||||
|---------|------|-------|
|
||||
| App | `8080` | configurable via `PORT` in `.env` |
|
||||
| Game Postgres | `5432` | user/pass from `.env` |
|
||||
| Users Postgres | `5433` | user/pass from `.env` |
|
||||
|
||||
### Database persistence
|
||||
|
||||
PostgreSQL data is under **`./data/postgres`** (bind mount). The **world wipe** only clears `grid_cells` when the UTC period slot changes; it does not delete the Postgres data directory.
|
||||
PostgreSQL data is under **`./data/postgres`** and **`./data/postgres_users`** (bind mounts). The **world wipe** only clears `grid_cells` when the UTC period slot changes; it does not delete the Postgres data directory.
|
||||
|
||||
## Local dev (without Docker)
|
||||
|
||||
Requires PostgreSQL and `DATABASE_URL`, then:
|
||||
Requires PostgreSQL, then:
|
||||
|
||||
```powershell
|
||||
cd star_wars_grid_game
|
||||
cp .env.example .env # fill in DATABASE_URL etc.
|
||||
npm install
|
||||
$env:DATABASE_URL="postgres://user:pass@localhost:5432/star_wars_grid"
|
||||
# export vars or use a tool like dotenv-cli
|
||||
$env:DATABASE_URL="postgres://game:game@localhost:5432/star_wars_grid"
|
||||
$env:USERS_DATABASE_URL="postgres://users:users@localhost:5433/star_wars_users"
|
||||
$env:JWT_SECRET="dev_secret"
|
||||
npm start
|
||||
```
|
||||
|
||||
Ensure `config/game.settings.json` exists (or copy from the repo).
|
||||
|
||||
## Docker image notes
|
||||
|
||||
- Base image: `node:20-alpine`
|
||||
- Runs as a **non-root user** (`appuser`) for security
|
||||
- `NODE_ENV=production` is set inside the image
|
||||
- Built-in **health check**: polls `GET /api/config` every 15 s (`wget`)
|
||||
- Secrets (`JWT_SECRET`, DB passwords) are **never baked into the image** — pass them via `.env` / Compose environment
|
||||
|
||||
## API
|
||||
|
||||
- `GET /api/config` — cooldown, wipe interval, debug flag, poll interval, `worldSeed`, period timestamps.
|
||||
- `GET /api/grid/:seed` — cells for that seed; **`410`** if `seed` is not the current world seed.
|
||||
- `POST /api/cell/reveal` — body `{ seed, x, y, team: "blue" \| "red" }` — first reveal wins; **`409`** if the other team owns the tile; **`410`** if seed is stale.
|
||||
- `POST /api/cell/reveal` — body `{ seed, x, y, team: "blue" | "red" }` — first reveal wins; **`409`** if the other team owns the tile; **`410`** if seed is stale.
|
||||
- `POST /api/auth/register` — `{ username, email, password, team }` → `{ token, user }`.
|
||||
- `POST /api/auth/login` — `{ username, password }` → `{ token, user }`.
|
||||
- `GET /api/auth/me` — Bearer token required → refreshed `{ token, user }`.
|
||||
- `GET /api/scores` — `{ blue: N, red: N }` tile counts for the current period.
|
||||
Reference in New Issue
Block a user