Private
Public Access
1
0

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:

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 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 = 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.

Teams (blue / red)

  • With debugModeForTeams: use the Team control (top-left) to switch perspective.
  • 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 (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)

Prerequisites

  1. Copy the environment template and set your secrets:

    cp star_wars_grid_game/.env.example star_wars_grid_game/.env
    # Edit .env — at minimum change JWT_SECRET, POSTGRES_PASSWORD, POSTGRES_USERS_PASSWORD
    
  2. From star_wars_grid_game/:

    docker compose up --build
    
  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 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, then:

cd star_wars_grid_game
cp .env.example .env    # fill in DATABASE_URL etc.
npm install
# 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/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.
Description
No description provided
Readme 7.7 MiB
Languages
JavaScript 75.8%
CSS 14.3%
HTML 9.4%
Dockerfile 0.5%