fix
This commit is contained in:
@@ -1,21 +1,22 @@
|
||||
# Halcyon belt
|
||||
# Halcyon
|
||||
|
||||
A once-a-day asteroid-belt simulator. Players cannot fly their ships: they write a
|
||||
A once-a-day asteroid-belt game. Players cannot fly their ships: they write a
|
||||
program for the ship's flight computer, launch it, and then exchange 1 KB a day with
|
||||
it over a "wormhole" link. The belt is simulated once a day, deterministically.
|
||||
it over a "wormhole" link. The belt is run once a day, deterministically.
|
||||
|
||||
- `docs/manual.txt` -- the HC-33 flight computer programmer's manual (also served at `/manual.txt`)
|
||||
- `docs/manual.md` -- the HC-33 flight computer programmer's manual (source; served at `/manual.md`)
|
||||
- `/manual.pdf` -- the same, typeset separately (see below)
|
||||
- `examples/programs/` -- sample ship programs (assembly)
|
||||
|
||||
## Run it
|
||||
|
||||
```sh
|
||||
go run ./cmd/server -db sqlite:wh.db # API + website on :8080
|
||||
go run ./cmd/daily -db sqlite:wh.db # simulate one day (run once a day, e.g. from cron)
|
||||
go run ./cmd/server -db sqlite:halcyon.db # API + website on :8080
|
||||
go run ./cmd/daily -db sqlite:halcyon.db # run one day of the belt (once a day, e.g. from cron)
|
||||
```
|
||||
|
||||
`-db` is `sqlite:<path>` or a `postgres://` URL. The world parameters (`-seed`,
|
||||
`-ticks-per-day`, `-asteroids`, ...) or their `WH_*` variables must be the same for `server` and
|
||||
`-ticks-per-day`, `-asteroids`, ...) or their `HALCYON_*` variables must be the same for `server` and
|
||||
`daily`, and cannot be changed for an existing database.
|
||||
|
||||
Open <http://localhost:8080/>, create an account (you are shown an access key once;
|
||||
@@ -26,27 +27,47 @@ it is your login), write a program, seal it into your ship, launch it, then run
|
||||
```sh
|
||||
docker build -t halcyon .
|
||||
docker run -d -p 8080:8080 -v whdata:/data halcyon # SQLite on a volume
|
||||
docker run --rm -v whdata:/data halcyon daily # simulate one day
|
||||
docker run -d -p 8080:8080 -e DATABASE_URL=postgres://user:pw@db/wh halcyon # or Postgres
|
||||
docker run --rm -v whdata:/data halcyon daily # run one day of the belt
|
||||
docker run -d -p 8080:8080 -e DATABASE_URL=postgres://user:pw@db/halcyon halcyon # or Postgres
|
||||
docker build --target test . # run the tests
|
||||
scripts/render-manual.sh # (re)render /manual.pdf, separately
|
||||
```
|
||||
|
||||
With Compose, Caddy serves the site over HTTPS at `sandbox.clearsky.dev` (edit `caddy/Caddyfile`
|
||||
for another name; DNS must point at the host and ports 80/443 must be open). The app itself is
|
||||
also on <http://localhost:8070>, bound to localhost only. SQLite lives in the `halcyon-data` volume:
|
||||
also on <http://localhost:8070>, bound to localhost only. SQLite lives in the `halcyon_data` volume:
|
||||
|
||||
```sh
|
||||
docker compose up -d --build
|
||||
scripts/daily.sh # one simulated day via `docker exec`; schedule it once a day
|
||||
scripts/daily.sh # one day's run via `docker exec`; schedule it once a day
|
||||
```
|
||||
|
||||
The world settings are environment variables (`WH_SEED`, `WH_TICKS_PER_DAY`, `WH_CYCLES_PER_TICK`,
|
||||
`WH_PROGRAM_BYTES`, `WH_RAM_BYTES`, `WH_COMM_BYTES`, `WH_ASTEROIDS`); flags of the same name override
|
||||
The world settings are environment variables (`HALCYON_SEED`, `HALCYON_TICKS_PER_DAY`, `HALCYON_CYCLES_PER_TICK`,
|
||||
`HALCYON_PROGRAM_BYTES`, `HALCYON_RAM_BYTES`, `HALCYON_COMM_BYTES`, `HALCYON_ASTEROIDS`); flags of the same name override
|
||||
them. In Compose they are set once on the `web` service, so `scripts/daily.sh` always matches the
|
||||
server. Change them only before a world has run.
|
||||
|
||||
`DATABASE_URL` sets the database for both `server` and `daily` (default in the image:
|
||||
`sqlite:/data/wh.db`); the `-db` flag overrides it. The image also contains `asm`.
|
||||
`sqlite:/data/halcyon.db`); the `-db` flag overrides it. The image also contains `asm`.
|
||||
|
||||
## The manual PDF
|
||||
|
||||
`docs/manual.md` is rendered to a PDF: typeset with WeasyPrint, then made to look like a well-used ring-binder
|
||||
copy -- coffee rings, three binder holes, and several generations of photocopying. The PDF keeps a live text
|
||||
layer, bookmarks and links. The look is generated by `docs/pdf/render.py` and is deterministic;
|
||||
`--intensity` (default 0.5) sets how worn the copies look, and `docs/pdf/check_legibility.py` OCRs every page
|
||||
against the text layer to check the result.
|
||||
|
||||
Rendering takes a couple of minutes, so it is **not** part of the app image: deploys stay fast, and the PDF is
|
||||
rendered separately into a volume that the server reads on every request (a new render is live at once, no restart):
|
||||
|
||||
```sh
|
||||
docker compose up -d --build # deploy the app (fast)
|
||||
scripts/render-manual.sh > /tmp/render-manual.log 2>&1 & # then re-render the PDF in the background
|
||||
scripts/manual-pdf.sh # or: render to docs/generated/ for a locally run server
|
||||
```
|
||||
|
||||
Until it has been rendered once, `/manual.pdf` is a 404 that says so. The Markdown source is always at `/manual.md`.
|
||||
|
||||
## Layout
|
||||
|
||||
@@ -54,12 +75,12 @@ server. Change them only before a world has run.
|
||||
|---|---|
|
||||
| `fixed`, `rng` | deterministic Q32.32 maths and PRNG |
|
||||
| `vm` | the ship CPU and its assembler (`cmd/asm`) |
|
||||
| `world`, `sim`, `market` | belt generation, the daily simulation, ore prices |
|
||||
| `world`, `sim`, `market` | belt generation, the daily run, ore prices |
|
||||
| `store`, `runner` | SQLite/Postgres persistence and the daily run |
|
||||
| `api`, `web`, `cmd/server` | HTTP API and the browser front end |
|
||||
| `examples`, `docs` | embedded sample programs and manual |
|
||||
|
||||
## Tests
|
||||
|
||||
`go test ./...` covers everything; set `WH_TEST_PG=postgres://...` to also run the API
|
||||
`go test ./...` covers everything; set `HALCYON_TEST_PG=postgres://...` to also run the API
|
||||
test against PostgreSQL (it wipes that database's `public` schema).
|
||||
|
||||
Reference in New Issue
Block a user