0G NOVA ADVENTURE - SERVER FOR LINUX

What this is: your own copy of the game world, running on your machine. Players sign in with
their normal accounts against the central account service; the world, the progress made in it,
and the ranks and bans you hand out belong to this server alone.


=== INSTALL ===

    tar -xzf zerog-nova-server-linux-x64.tar.gz
    cd zerog-nova-server
    sudo bash install.sh

("bash install.sh", not "./install.sh". The package is built on Windows, where tar cannot record
a Unix execute bit, so everything in it arrives unexecutable. Naming the interpreter sidesteps
that. The two server binaries are made executable by install.sh itself.)

Or skip the download entirely and let one command do all of the above, and start the server:

    curl -fsSL https://adventure.zerognova.com/install.sh | sudo bash

That creates a system user, a PostgreSQL role and database, applies the schema and the world
data, writes the settings file, and installs two systemd units. It does NOT start them - you
will probably want to name your server first.

    sudo bash install.sh --prefix /srv        install somewhere else
    sudo bash install.sh --no-systemd         files and database only
    sudo bash install.sh --help               the rest

You need PostgreSQL already installed and running. Nothing else: the binaries are
self-contained, so there is no .NET runtime to install.


=== WHAT IS IN HERE ===

    server/     the game server, one file
    gateway/    what players actually connect to, one file
    schema.sql  every table the server needs
    seed.sql    the world: items, ship frames, the station, drop tables
    install.sh  the above, done for you

Nothing here can mint a login token. jwt-public.pem verifies them and can sign nothing, which
is why it is safe to hand out with the download.


=== BEING FOUND ===

By default your server is private: it works, and nobody can find it unless you give them the
address. To appear in the in-game server list, give it a name in
/etc/systemd/system/zerog-server.service under [Service]:

    Environment="ZEROG_SERVER_NAME=My Server Name"
    Environment=ZEROG_SERVER_TAGS=PVE,Creative

Then:

    sudo systemctl daemon-reload
    sudo systemctl restart zerog-server

A name is all it takes. The server registers itself with the rendezvous, receives a join code,
and appears in the list - the same mechanism the official server uses. The join code is in the
log:

    sudo journalctl -u zerog-server | grep Registrar

To hold a join code without being listed publicly, add:

    Environment=ZEROG_PUBLISH=false


=== ONE COMMAND FOR A LISTED, BROWSER-READY SERVER ===

    sudo bash install.sh --admin "You" --name "My Server" --tags PVE

If this machine has a public IP, the installer also sets up BROWSER (WebGL) access, with no domain
and nothing to buy: it installs Caddy, gets a Let's Encrypt certificate for the IP itself (they
are short-lived, about 6 days, and Caddy renews them automatically), proxies wss://<ip>/ws to the
gateway, and declares that address to the rendezvous. It only declares the address once the
certificate actually works, so a failed attempt never lists a server browsers cannot reach.

Needed: ports 80 and 443 open to the internet - at your provider's firewall too, not just here -
AND not used by another program. Port 80 is where Let's Encrypt checks the certificate (at setup
and at every renewal) and 443 is where browser players connect. If something else already holds
them - a website on the same machine, say - the installer says so, changes nothing, and the server
stays desktop-only. A machine behind a home router with no forwarded ports is desktop-only too.
Desktop players never need 80 or 443; they only need 8081.

    --domain play.example.com   use a hostname you own instead of the IP (DNS must point here)
    --no-web                    skip browser access entirely

Safe to re-run; it changes only what you pass. --name and --tags are written to server.env, so
they survive re-running the installer.


=== IF YOU HAVE A DOMAIN AND A CERTIFICATE ===

(The manual version of the above, for an existing nginx/Apache setup.)

Put your reverse proxy in front of the gateway and tell the server where it really is:

    Environment=ZEROG_SERVER_PUBLIC_URL=wss://your.domain/ws
    Environment=ZEROG_GATEWAY_PORT=443

This matters more than it looks. Without it the rendezvous probes port 8081 and describes you
as "the IP we saw, on that port" - which is right for a machine listening directly on the
internet, and wrong for one behind a proxy whose game port is deliberately closed.

IT IS ALSO WHAT BROWSER PLAYERS NEED. The game is served to them over HTTPS, and a page loaded
over HTTPS cannot open a plain ws:// connection - the browser refuses it as mixed content, and
no setting on your side changes that. A server without a certificate is desktop-only. That is
a browser rule, not our choice.


=== RUNNING IT ===

    sudo systemctl start zerog-server zerog-gateway
    sudo systemctl status zerog-server --no-pager
    sudo journalctl -u zerog-server -f

Players connect to  ws://<your address>:8081/ws  - or your wss:// address if you set one up.

Open port 8081/tcp on your firewall. Port 25312/udp too if you want players to be introduced
directly to the game socket rather than going through the gateway.


=== SETTINGS ===

server/server.env holds the database connection and the path to the public key. It is 0600
and owned by the service user because it contains the database password. The installer
generates that password; you never need to know it.

Everything else is systemd Environment= lines, listed above.


=== HOW MANY PLAYERS ===

A server holds 10 players at once. That is the free limit, and it is enough for a group of
friends; the eleventh is turned away with a message saying the server is full rather than
being left to time out.

An Access Pass lets you choose the number instead, and there is nothing to install. Log in
to the game as normal and connect to your own server with an account that is Admin HERE -
the one you named with --admin, or anyone you have since promoted. The server reads the pass
from your login and lifts the cap on the spot. No restart, no key, no file to edit.

Then set the number under Server Settings inside the game: the Player limit field takes any
figure you like, or 0 for no limit at all. It is stored on the server, so it survives a
restart and applies to the next player who connects - nobody already playing is disturbed.
The Players row above it reads "3 connected - Up to 40 players" so you can see where you
stand.

Game Masters and Admins may exceed the limit, by up to 3. A 10-player server therefore holds
13 at the absolute most, and the last three have to be staff. That is so a full server never
locks out the person who could do something about it - and it is capped at three so that
promoting friends is not a way around the limit.


=== IF IT WILL NOT START ===

  "Missing required setting 'X'"
      The message names the setting and the file it belongs in. That is the configuration
      check working, not a bug.

  Exits immediately, complains about the database
      Check PostgreSQL is running and that server/server.env matches the role the installer
      created. journalctl has the actual error.

  Starts, but nobody can connect
      Almost always the firewall. Check 8081/tcp is open from outside, not just from the
      machine itself.

  Starts, but does not appear in the list
      Look for [Registrar] lines in the journal. No lines at all means ZEROG_SERVER_NAME is
      not set. A line saying "not listed right now" means the rendezvous could not be reached
      - your server is still perfectly playable, and it will keep retrying.


=== UPGRADING ===

Untar the new version and run install.sh again. It leaves an existing database and an existing
server.env alone, so your world and your settings survive; only the binaries are replaced.
