chiark / gitweb /
docs: Start of reorganisation and much editing
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 7 Apr 2021 22:54:10 +0000 (23:54 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 8 Apr 2021 19:34:21 +0000 (20:34 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
README.md
XDOCS.md [new file with mode: 0644]
docs/advanced.md [new file with mode: 0644]
docs/dev.md [new file with mode: 0644]
docs/user.md [new file with mode: 0644]

index 195101bf80e587fdf2cd303ddc538159d08428a6..be94387e539eac6431f1c84e6af649cf52bdf718 100644 (file)
--- a/README.md
+++ b/README.md
 OTTER - ONLINE TABLE TOP ENVIRONMENT RENDERER
 =============================================
 
-Otter is an online "table simulator" intended to be suitable for board
-games and similar.
+Otter is an online game system.
 
-It is accessed from a web browser running JavaScript.  The server runs
-on a convenationl Unix host.  Currently, joining a game requires a
-unix shell account on the server.
+But it is not like most online game systems.  It does not know (nor
+does it need to know) the rules of the game you are playing.  Instead,
+it lets you and your friends play with common tabletop/boardgame
+elements such as hands of cards, boards, and so on.
 
-I expect it to be used with a concurrent voice chat.
+So it's something like a "tabletop simulater" (but it does not have
+any 3D, or a physics engine, or anything like that).
 
-The game server does not currently have a built-in text chat system.
-The game organiser can use the game server to distribute (and update)
-voice chat and info links.
+This means that with Otter:
 
-Right now Otter is in an alpha state.
+ * Supporting a new game, that Otter doesn't know about yet, would
+   usually not involve writing or modifying any computer programs.
 
+ * If Otter already has the necessarily game elements (cards, say) all
+   you need to do is write a spec file saying what should be on the
+   table at the start of the game.  For example, most Whist variants
+   that start with a standard pack of 52 cards are already playble.
 
-JOINING A GAME
-==============
+ * You can play games where the rules change as the game goes along,
+   or are made up by the players, or are too complicated to write as a
+   computer program.
 
-In the simplest case:
-```
-  otter join-game unix:<user>::<game-name>
-```
-e.g.
-```
-  otter join-game unix:ijackson::test
-```
+ * House rules are no problem, since the computer isn't enforcing the
+   rules - you and your friends are.
 
-See `otter --help` for further options, including setting your nick.
+ * Everyone can interact with different items on the game table, at
+   any time.  (Otter doesn't know about your game's turn-taking, so
+   doesn't know whose turn it might be.)
 
-Currently when a new player joins a game (with the `otter` command),
-all the other players must reload the page.
+We have played successful and fun online games of both Penultima and
+Mao with Otter.
 
 
-CREATING A GAME
-===============
-
-```
-otter reset --reset-table local-users :test demo
-                         /^^^^^^^^^^^  ^^^\ ^^^^'~ game spec
-                         `table spec       game name
-```
-
-Here `local-users` refers to the file `local-users.table.spec` in the
-Otter specs directory (`/volatile/Otter/specs` on chiark).  The table
-spec file handles access control (and some other global properties)
-This particular file says that all local shell account users may join
-the game.
-
-`:test` is the game name.  It starts with a colon, which means
-implicitly `unix:<whoami>::test`.  Other people have to name the game
-with the full name, with all three colons in it.
-
-`demo` refers to the file `demo.game.spec`.  The "game spec" says what
-shape table is and what pieces there are.  This is a simple demo game.
-There is also `penultima` which is a work-in-progress set of pieces
-suitable for fairy chess etc.
-
-See `otter --help` for some more options.
-
-Currently, resetting a game (or otherwise adding or removing pieces)
-will mean all the players will get errors until they reload the page.
-
-
-MAKING YOUR OWN GAME
-====================
-
-If you want to use existing piece shapes that Otter already knows
-about, you can do this by providing a `<something>.game.toml` file.
-The format of these files is a TOML document representing a GameSpec
-as found in `src/spec.rs` in the Otter source code.
-
-todo: use rustdoc to provide this somewhere.
-
-
-ADDING SHAPES
-=============
-
-Otter uses SVGs.  The sources for the SVGs are all in the otter source
-tree, in the `library/` directory.
-
-Each shape is listed in one of the `library/*.toml` files, in a
-`files` entry.  (Most of) the syntax and semantics of this file are
-documented in the Rustdoc documentation for the module
-`otter::shapelib_toml`.  If you run `make -j8 shapelib` it will print
-out a `file://` url for these docs.
-
-You can preview the shapes, including any changes you make, without a
-whole game server, by running `make -j8 shapelib`, and looking at
-`templates/shapelib.html`.  As above, this make rune will print the
-`file://` url for you.  (See BUILDING AND TESTING for information
-about how to install the tools you will need.)
-
-Some of these SVGs were scraped from Wikimedia.  The scraper machinery
-can perhaps be adapted to scrape SVGs from elsewhere.
-
-You can also add your own SVGs in the library/edited/ directory.
-If you do that, please make sure to include the actual source code.
-If you copied or adapted an SVG from somewhere, provide details.
-
-Contributions should be via git branch, eg a merge request on Salsa:
-[https://salsa.debian.org/iwj/otter](https://salsa.debian.org/iwj/otter)
-
-NB that shapes must come with a licence compatible with CC-BY-SA 4.0
-or GNU AGPLv3+.  See `LICENCE` for more information about copyright status.
-
-
-BUILDING AND TESTING
-====================
-
-You will need at least 6000 megabytes of disk space, or more, and a
-good internet connection.  Your computer will be compiling a lot of
-code.
-
-These instructions have been tested on Debian buster.
-
-
-Setup
------
-
-1. 
-```
-     sudo apt install build-essential cpio git curl     \
-                      pkg-config libssl-dev             \
-                      node-typescript inkscape bubblewrap \
-                      netpbm imagemagick
-```
-
-2. Install Rust.  This is most easily done with [rustup](https://rustup.rs)):
-
-```
-     curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-```
-
-   and then follow the instructions about your `PATH`.  If this rune
-   alarms you, see below about Rust privsep.
-
-3. Switch your Rust install to use Rust Nightly and add the WASM
-   target:
-
-```
-     rustup default nightly
-     rustup target add wasm32-unknown-unknown
-```
-
-   Unfortunately, it is possible that the Rust nightly you find when
-   you run this is missing some pieces.  The following is known to
-   work (with otter from the time of writing):
-```
-     rustup default nightly-2021-01-26
-```
-
-4. Install the `usvg` SVG launderer, which we need for shape libraries
-
-```
-     cargo install usvg
-```
-
-   This will put it in `~/.cargo/bin`, which you presumably have on
-   your `PATH` (or the above `rustup` and `cargo` runes wouldn't work).
-
-
-** If you just want to edit and preview the shape libraries
-   (ie the piece shapes) you can stop here **
-
-
-5. Install some more build tools:
-
-```
-     cargo install bundle-sources
-```
-
-
-Build
------
-
-```
-     git clone https://salsa.debian.org/iwj/otter
-     cd otter
-     make -j8 all bundled-sources
-```
-
-Or if you just want to edit the piece libraries:
-
-```
-    make -j8 shapelib
-```
-And then open `./templates/shapelib.html` in your browser
-
-
-Ad-hoc tests
-------------
-
-In one shell:
-
-```
-     target/debug/daemon-otter server-test.toml
-```
-
-The server does not daemonise, and the default config there makes it
-quite verbose.  So, in another shell:
-
-```
-    target/debug/otter                                               \
-        --account server: --config server-test.toml --spec-dir=specs \
-        reset --reset-table test server::test demo
-
-    target/debug/otter                                               \
-        --account server: --config server-test.toml --spec-dir=specs \
-        join-game server::test
-```
-
-The URL printed can then be visited in a local browser.
-
-
-Resetting/restoring things after tests, updating server, etc.
--------------------------------------------------------------
-
-After the server is updated, you can just `^C` and restart it.  Games
-are constantly saved (although there is an up-to-1s lag on the most
-frequently udpated game state).
-
-If you want to clear out the server state, delete the files `[ag]-*`
-and `accounts`.  NB that you should do this with the server not
-running, because the server has most of that information in memory and
-will like to write it out again.
-
-If you update Typescript (JS code) you will need to rerun `make` to
-rebuild the JS output.
-
-Apart from that, if you update JS or WASM code or Tera templates, you
-do not need to restart the server - it will pick up changes
-automatically.
-
-When testing, you do not need to `make bundled-sources` more than
-once, at the beginning.  So don't, because it's slow.  But you
-definitely should run it for every update if you make a deployment for
-other people to use.  Otherwise you might be running a privately
-modified server without offering your users its source code.  See
-LICENCE.
-
-If you Do Something to the output from cargo, you should `rm stamp/*`,
-since the `Makefile` won't notice, otherwise, that, the relevant cargo
-rune(s) need to be re-run.  Needlessly deleting all the stamp files
-wastes only a handful of seconds (on my stupidly fast laptop).
-
-
-Navigating the otter source code
---------------------------------
-
-* `src/`
-
-  The main Rust source code.  This is mixture of code used only or
-  mainly by the server and code used by the `otter` command line
-  utility; these aren't split up in a wholly principled way.  In Rust
-  terms this is a "library crate".
-
-* `src/bin/*.rs`
-
-  Support executables, including in particular the command line
-  utility `otter` which is used to set up and join games.
-
-* `daemon/`
-
-  The Otter server.  This is a simple binary crare.  Much
-  functionality belonging primarily, or only, to the server, is in
-  `src/`, simply because it was easier not to disentangle it.
-  Anything that needs Rocket (the web framework) is in `daemon/`.
-
-* `zcoord/`
-
-  Code shared by the host and the WebAssembly.  Notably, the Z
-  coordinate handling, but also a a few other minor functions needed
-  by both client and server.  To avoid duplicating them are written
-  once in Rust and compiled twice - once for the host and once for
-  WebAssembly for use in the client.  This crate is kept minimal to
-  keeep the WebAssembly binary small.
-
-* `wasm/`
-
-  WebAssembly/Rust bindings for the items in `zcoord/`.  Produces the
-  single wasm file for use by the JavaScript, and corresponding
-  Typescript annotations etc.
-
-* `templates/script.ts`
-
-  The main Typescript (typed Javascript) code.  Otter's web
-  compatibility target is the earliest browser versions that properly
-  support WebAssembly.
-
-* `templates/session.tera`, `macros.tera`, etc.
-
-  Tera templates generating the main HTML screen.  These templates are
-  filled in from structs in the Rust source code.  The main files are
-  `session.tera` (portrait), `landscape.tera`, and `macros.tera`
-  (common), and their rendering uses an instance of
-  `SessionRenderContext` from `src/session.rs`.
-
-* `nwtemplates/`
-
-  "Non-web templataes".  Tera templates for things other than web
-  pages.  Currently this includes the server's outgoing emails.  These
-  have to be in a separate directory because Rocket likes to load
-  everything applicable it finds in its own `templates/` directory.
-  These are used via `src/nwtemplates.rs`.
-
-* `wdriver.rs`, `wdriver/`
-
-  WebDriver-based end-to-end tests.  Each `wdt-*.rs` is one test
-  utility.  `wdriver.rs` (in the top level to evade Cargo's
-  dur-brained search rules) is the library for these, and contains
-  most of the heavy lifting.
-
-  These are not standard Rust `#[test]` tests because they need to
-  reinvoke themselves via `bwrap` for test isolation reasons, and
-  because their dependencies are extensive and not properly capturable
-  in Cargo.  They are run by `make check`.
-
-* `library/`: The shape libraries.
-
-  The program `./media-scraper` (which is not run by the `Makefile`)
-  reads `library/*.toml` for instructions and generates `files.make`
-  fragments.  These fragments arrange to run `./usvg-processor` which
-  launders SVGs through `usvg`.  `usvg-processor`.
-
-  The shape libraries have a different, more relaxed, copyright
-  licence.
-
-
-Automatic in-browser tests
+Playing a game with Otter
 --------------------------
 
-* `apt install firefox`
+The Otter game environment is accessed from a web browser running
+JavaScript, using a magic https link obtained from joining the game.
 
-* `https://github.com/mozilla/geckodriver/releases/tag/v0.28.0`
-  download appropriate tarball, put "geckodriver" on PATH
+You will need to be able to talk to your friends about the game, while
+you play.  Otter works well when used together with a voice chat - we
+have had success with Jitsi in voice-only mode.
 
-`make check` runs all the tests; `make wdt` runs only those tests.  You can run
-an individual test with a rune like this:
+Most relatively modern desktop browsers should to work with Otter.
+(The most advanced feature needed is support for WebAssembly.)
 
-```
-  OTTER_TEST_LOG=otter_webdriver_tests=trace CARGO_MANIFEST_DIR=~ian/Rustup/Game/server time target/debug/wdt-simple --geckodriver-args=
-```
 
-(This rune has some example logging options in it, for you to change
-if you like. You can omit the `CARGO_MANIFEST_DIR` for an in-tree
-non-privsep build.)  After a test has run, you can find screenshots,
-etc. in `tmp/wdt-simple` or whatever.  You can restart the same game
-server setup as the test used, with the state left by the test, with a
-rune like this:
+Predefined games and pieces currently available
+-----------------------------------------------
 
-```
-  target/debug/daemon-otter tmp/wdt-simple/server-config.toml
-```
-and then play with it at this url:
-```
-  http://localhost:8000/?kmqAKPwK4TfReFjMor8MJhdRPBcwIBpe
-```
+Otter currently has, in its pieces library:
 
+  * Ingredients for chess, including fairy chess.  So there's a board,
+    pieces, including many fairy chess pieces, and a chess clock.
 
-Rust, cargo, curl|bash-ware; privsep
-------------------------------------
+  * Ingredients for card games.  So, a deck of 52 standard playing
+    cards, plus two kinds of joker.  Special "hand" and "deck" pieces
+    for player hands and a pickup deck.
 
-If you follow the above instructions you will have downloaded and
-executed - and, therefore, trusted:
+Currently there are game definitions for:
 
- * Various Debian packages - safe
- * Rustup (the Rust downloader/installer) - this is pretty safe
- * Rust itself - again, pretty safe
- * Otter itself - well, I wrote this; up to you.
- * 450 transitive dependencies of otter (from crates.io)
- * 50 transitive dependencies of bundle-sources
- * the transitive dependencies of resvg
- * a geckodriver binary directly from mozilla
+ * Penultima.  This can be used directly to play standard chess and
+   some fairy chess variants.
 
-You will have trusted the integrity of the following:
+ * Mao.  This can be used to play any game of roughly that shape.
 
- * The Debian archive (via its apt keyring) (very good)
- * Rustup's and Rust's TLS keyholders (good, I think)
- * The HTTP TLS cabal (sigh)
- * github (pretty good in practice)
- * whatever mozilla do to make binaries, in particular geckodriver
- * crates.io (extremely poor traceability)
- * the project management of hundreds of random crates.io libraries
+Defining new games using the existing pieces from the library is
+fairly easy.  It is also possible to add elements from the library
+ad-hoc, even while a game is in progress.
 
-If this makes you uncomfortable, as it should, you may wish to
-consider running everything in a separate shell account, or a VM or
-container of some kind.
 
-(I have a not-properly-released tool called "nailing-cargo" which
-makes it possible to do most things in my main account but run the
-Rust stuff in a separate less-privileged account.  There is support
-for this in the Makefile.  But if you want to run *everything* in the
-lesser account, you don't need to bother with that.)
+Limitations
+-----------
 
+Currently, joining a game requires a unix shell account on the server
+host (or help from a shell account user).
 
-Dependencies - apologia
------------------------
+There is not currently a publicly available server.  The server code
+is Free Software and if you have a suitable vm or server you are
+encouraged to build and run it yourself, for you and your friends.
 
- * Rust Nightly
+Mobile phones are not really suitable for playing on Otter because
+their screens are too small.  Tablets and other touchscreen based
+systems could be made to work, but don't work well right now.
 
-   This is needed almost solely because Rocket needs it.  Rocket is
-   the web framework I am using.  The next version of Rocket (0.5.x),
-   which is in development, will not need Nightly, but it will also be
-   a serious compatibility break.  The existing Rocket (0.4.x) will
-   almost certainly never be ported to Stable Rust.  When Rocket 0.5.x
-   is out, porting Otter to it will go on my list - but it won't be
-   trivial.  Sorry.
+Otter does not currently have even a built-in text chat facility.  It
+does have a way to share a URL for a voice chat.
 
- * The many dependencies of Otter
+Right now Otter is in a beta state.  There are significant
+as-yet-unimplemented improvements that would make it work better for
+more people and more games.  I don't currently promise savefile
+compatibility, or upgradeability, from one Otter version to the next.
+And there are still bugs.
 
-   These are partly because Rocket is a large piece of software with
-   much functionality.  But also because I favoured my own programming
-   convenience and in some cases was experimenting with different
-   approaches.  In practice, it seems to me that once I'm using Rocket
-   and WASM and resvg and so on, there is not that much to be gained
-   by trying to prune the dependencies of the otter package itself.
 
- * bundle-rust-sources
+Free software, and user freedom
+-------------------------------
 
-   This is mine, but it needs to be properly released.
+Otter is Free Software.  I wrote it to liberate game players from the
+need to encode their game rules as computer programs and thus from the
+tyranny of programmers `:-)`.
 
- * geckodriver (for the automated in-browser tests)
+I would love contributions, particularly to address the limitations I
+mention above, and to improve the user experience.
 
-   This is done with a protocol called "WebDriver" which is a
-   cross-browser way to puppet a browser.  There is a thing called
-   "geckodriver" which converts that to a firefox-specific protocol
-   for the same purpose, called "Marionette".  (In practice all this
-   seems to have lots of bugs and misfeatures.)
+I am also working to make it possible to let you define your own games
+(including your own pieces, cards, boards, and so on) without having
+to install them on the server.
 
-   AFAICT the usual approach for using geckodriver to have it *bind to
-   a fixed TCP port accessible to all local programs*.  My wrapper
-   tooling arranges to run this in an ephemeral $HOME and a private
-   network namespace.
-
-   AFAICT the only practical way to get geckodriver is to download the
-   binary.  I got mine here:
-     https://github.com/mozilla/geckodriver/releases/tag/v0.28.0 You
-   You just dump the binary on your PATH.
-
-
-Final weirdness
----------------
-
- * For running on chiark I build with the Rust target
-   `x86_64-unknown-linux-musl` which on my system is configured to
-   produce a completely statically linked bionary.  I have this in my
-   `~/.cargo/config` (in the lesser privsep account):
-
-```
-[target.x86_64-unknown-linux-musl]
-rustflags = ["-C", "target-feature=+crt-static"]
-# ^ from https://stackoverflow.com/questions/31770604/how-to-generate-statically-linked-executables
-```
+The Otter software project is hosted on Debian's GitLab, at
+  https://salsa.debian.org/iwj/otter
+Merge requests (accompanied by a `Signed-off-by` indicating sign-off
+of the Developer Certificate of Origin) would be very welcome.
diff --git a/XDOCS.md b/XDOCS.md
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs/advanced.md b/docs/advanced.md
new file mode 100644 (file)
index 0000000..a0f4620
--- /dev/null
@@ -0,0 +1,41 @@
+Making your own game
+====================
+
+If you want to use existing piece shapes that Otter already knows
+about, you can do this by providing a `<something>.game.toml` file.
+The format of these files is a TOML document representing a `GameSpec`
+as found in `src/spec.rs` in the Otter source code.
+
+
+Adding shapes
+=============
+
+Otter uses SVGs.  The sources for the SVGs are all in the otter source
+tree, in the `library/` directory.
+
+Each shape is listed in one of the `library/*.toml` files, in a
+`files` entry.  (Most of) the syntax and semantics of this file are
+documented in the Rustdoc documentation for the module
+`otter::shapelib_toml`.  If you run `make -j8 shapelib` it will print
+out a `file://` url for these docs.
+
+You can preview the shapes, including any changes you make, without a
+whole game server, by running `make -j8 shapelib`, and looking at
+`templates/shapelib.html`.  As above, this make rune will print the
+`file://` url for you.
+
+See BUILDING AND TESTING for information about how to install the
+tools you will need.
+
+Some of these SVGs were scraped from Wikimedia.  The scraper machinery
+can perhaps be adapted to scrape SVGs from elsewhere.
+
+You can also add your own SVGs in the library/edited/ directory.
+If you do that, please make sure to include the actual source code.
+If you copied or adapted an SVG from somewhere, provide details.
+
+Contributions should be via git branch, eg a merge request on Salsa:
+[https://salsa.debian.org/iwj/otter](https://salsa.debian.org/iwj/otter)
+
+NB that shapes must come with a licence compatible with CC-BY-SA 4.0
+or GNU AGPLv3+.  See `LICENCE` for more information about copyright status.
diff --git a/docs/dev.md b/docs/dev.md
new file mode 100644 (file)
index 0000000..a8f823a
--- /dev/null
@@ -0,0 +1,375 @@
+BUILDING AND TESTING OTTER
+==========================
+
+Otter is mostly written in Rust.
+
+The web UI frontend is written in Typescript, with a small amount of
+Rust support code delivered via WebAssembly.
+
+
+You will need at least 6000 megabytes of disk space, or more, and a
+good internet connection.  Your computer will be compiling a lot of
+code.
+
+These instructions have been tested on Debian buster.
+
+
+Setup
+-----
+
+1. 
+```
+     sudo apt install build-essential cpio git curl     \
+                      pkg-config libssl-dev             \
+                      node-typescript inkscape bubblewrap \
+                      netpbm imagemagick
+```
+
+2. Install Rust.  This is most easily done with [rustup](https://rustup.rs)):
+
+```
+     curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+```
+
+   and then follow the instructions about your `PATH`.  If this rune
+   alarms you, see below about Rust privsep.
+
+3. Switch your Rust install to use Rust Nightly and add the WASM
+   target:
+
+```
+     rustup default nightly
+     rustup target add wasm32-unknown-unknown
+```
+
+   Unfortunately, it is possible that the Rust nightly you find when
+   you run this is missing some pieces.  The following is known to
+   work (with otter from the time of writing):
+```
+     rustup default nightly-2021-01-26
+```
+
+4. Install the `usvg` SVG launderer, which we need for shape libraries
+
+```
+     cargo install usvg
+```
+
+   This will put it in `~/.cargo/bin`, which you presumably have on
+   your `PATH` (or the above `rustup` and `cargo` runes wouldn't work).
+
+
+** If you just want to edit and preview the shape libraries
+   (ie the piece shapes) you can stop here **
+
+
+5. Install some more build tools:
+
+```
+     cargo install bundle-sources
+```
+
+
+Build
+-----
+
+```
+     git clone https://salsa.debian.org/iwj/otter
+     cd otter
+     make -j8 all bundled-sources
+```
+
+Or if you just want to edit the piece libraries:
+
+```
+    make -j8 shapelib
+```
+And then open `./templates/shapelib.html` in your browser
+
+
+Ad-hoc tests
+------------
+
+In one shell:
+
+```
+     target/debug/daemon-otter server-test.toml
+```
+
+The server does not daemonise, and the default config there makes it
+quite verbose.  So, in another shell:
+
+```
+    target/debug/otter                                               \
+        --account server: --config server-test.toml --spec-dir=specs \
+        reset --reset-table test server::test demo
+
+    target/debug/otter                                               \
+        --account server: --config server-test.toml --spec-dir=specs \
+        join-game server::test
+```
+
+The URL printed can then be visited in a local browser.
+
+
+Resetting/restoring things after tests, updating server, etc.
+-------------------------------------------------------------
+
+After the server is updated, you can just `^C` and restart it.  Games
+are constantly saved (although there is an up-to-1s lag on the most
+frequently udpated game state).
+
+If you want to clear out the server state, delete the files `[ag]-*`
+and `accounts`.  NB that you should do this with the server not
+running, because the server has most of that information in memory and
+will like to write it out again.
+
+If you update Typescript (JS code) you will need to rerun `make` to
+rebuild the JS output.
+
+Apart from that, if you update JS or WASM code or Tera templates, you
+do not need to restart the server - it will pick up changes
+automatically.
+
+When testing, you do not need to `make bundled-sources` more than
+once, at the beginning.  So don't, because it's slow.  But you
+definitely should run it for every update if you make a deployment for
+other people to use.  Otherwise you might be running a privately
+modified server without offering your users its source code.  See
+LICENCE.
+
+If you Do Something to the output from cargo, you should `rm stamp/*`,
+since the `Makefile` won't notice, otherwise, that, the relevant cargo
+rune(s) need to be re-run.  Needlessly deleting all the stamp files
+wastes only a handful of seconds (on my stupidly fast laptop).
+Deleting the xtamp files is not needed if you simpl edit Rust source
+files.
+
+
+Navigating the otter source code
+--------------------------------
+
+* `src/`
+
+  The main Rust source code.  This is mixture of code used only or
+  mainly by the server and code used by the `otter` command line
+  utility; these aren't split up in a wholly principled way.  In Rust
+  terms this is a "library crate".
+
+* `src/bin/*.rs`
+
+  Support executables, including in particular the command line
+  utility `otter` which is used to set up and join games.
+
+* `daemon/`
+
+  The Otter server.  This is a simple binary crate.  Much
+  functionality belonging primarily, or only, to the server, is in
+  `src/`, simply because it was easier not to disentangle it.
+  Anything that needs Rocket (the web framework) is in `daemon/`.
+
+* `base/`
+
+  Code shared by the host and the WebAssembly.  Notably, the Z
+  coordinate handling, but also a a few other minor functions needed
+  by both client and server.  To avoid duplicating them are written
+  once in Rust and compiled twice - once for the host and once for
+  WebAssembly for use in the client.  This crate is kept fairly small
+  to keeep the WebAssembly binary small (currently, ~100kby).
+
+* `wasm/`
+
+  WebAssembly/Rust bindings for the items in `zcoord/`.  Produces the
+  single wasm file for use by the JavaScript, and corresponding
+  Typescript annotations etc.
+
+* `templates/script.ts`
+
+  The main Typescript (typed Javascript) code.  Otter's web
+  compatibility target is the earliest browser versions that properly
+  support WebAssembly.
+
+* `templates/session.tera`, `macros.tera`, etc.
+
+  Tera templates generating the main HTML screen.  These templates are
+  filled in from structs in the Rust source code.  The main files are
+  `session.tera` (portrait), `landscape.tera`, and `macros.tera`
+  (common), and their rendering uses an instance of
+  `SessionRenderContext` from `src/session.rs`.
+
+* `nwtemplates/`
+
+  "Non-web templataes".  Tera templates for things other than web
+  pages.  Currently this includes the server's outgoing emails.  These
+  have to be in a separate directory because Tera (invoked by Rocket)
+  likes to load everything applicable it finds in its own `templates/`
+  directory.  These are used via `src/nwtemplates.rs`.
+
+* `apitest/`
+
+  Tests of the server which use its APIs - specifically, the
+  management socket (also used by the `otter` command line tool) and
+  the web API, but which do not use any JavaScript.
+
+  These are not standard Rust `#[test]` tests because they need to
+  reinvoke themselves via `bwrap` for test isolation reasons, and
+  because their dependencies are extensive and not properly capturable
+  in Cargo.  They are run by `make check`.
+
+  The file `apitest/apitest.rs` also contains code which is reused by
+  the WebDriver tests.
+
+* `wdriver/`
+
+  WebDriver-based end-to-end tests.  Each `wdt-*.rs` is one test
+  utility.  `wdriver.rs` is the library for these, and contains most
+  of the heavy lifting.
+
+  The tests produce a single portmanteau binary to reduce compile
+  times.  You run it with `target/debug/wdriver --test=wdt-something`.
+
+* `specs/`.  The table and game specs, as used directly by `otter`.
+
+* `library/`: The shape libraries.
+
+  The program `./media-scraper` (which is not run by the `Makefile`)
+  reads `library/*.toml` for instructions and generates `files.make`
+  fragments.  These fragments arrange to run `./usvg-processor` which
+  launders SVGs through `usvg`.  `usvg-processor`.
+
+  The shape libraries have a different, more relaxed, copyright
+  licence.
+
+* `webassembly-types`: A git-subtree of "WebAssembly Types".
+
+
+Automatic in-browser tests (`wdriver`)
+--------------------------------------
+
+* `apt install firefox`
+
+* `https://github.com/mozilla/geckodriver/releases/tag/v0.28.0`
+  download appropriate tarball, put "geckodriver" on PATH
+
+`make check` runs all the tests; `make wdt` runs only those tests.  You can run
+an individual test with a rune like this:
+
+```
+  OTTER_TEST_LOG=otter_webdriver_tests=trace CARGO_MANIFEST_DIR=~ian/Rustup/Game/server time target/debug/wdriver --test=wdt-simple --geckodriver-args=
+```
+
+(This rune has some example logging options in it, for you to change
+if you like. You can omit the `CARGO_MANIFEST_DIR` for an in-tree
+non-privsep build.)  After a test has run, you can find screenshots,
+etc. in `tmp/wdt-simple` or whatever.  You can restart the same game
+server setup as the test used, with the state left by the test, with a
+rune like this:
+
+```
+  target/debug/daemon-otter tmp/wdt-simple/server-config.toml
+```
+and then play with it at this url:
+```
+  http://localhost:8000/?kmqAKPwK4TfReFjMor8MJhdRPBcwIBpe
+```
+
+
+Rust, cargo, curl|bash-ware; privsep
+------------------------------------
+
+If you are not the kind of person to worry about your software supply
+chains you can skp this part.
+
+If you follow the above instructions you will have downloaded and
+executed - and, therefore, trusted:
+
+ * Various Debian packages - safe
+ * Rustup (the Rust downloader/installer) - this is pretty safe
+ * Rust itself - again, pretty safe
+ * Otter itself - well, I wrote this; up to you.
+ * 450 transitive dependencies of otter (from crates.io)
+ * 50 transitive dependencies of bundle-sources
+ * the transitive dependencies of resvg
+ * a geckodriver binary directly from mozilla
+
+You will have trusted the integrity of the following:
+
+ * The Debian archive (via its apt keyring) (very good)
+ * Rustup's and Rust's TLS keyholders (good, I think)
+ * The HTTP TLS cabal (sigh)
+ * github (pretty good in practice)
+ * whatever mozilla do to make binaries, in particular geckodriver
+ * crates.io (extremely poor traceability)
+ * the project management of hundreds of random crates.io libraries
+
+If this makes you uncomfortable, as it should, you may wish to
+consider running everything in a separate shell account, or a VM or
+container of some kind.
+
+(I have a not-properly-released tool called "nailing-cargo" which
+makes it possible to do most things in my main account but run the
+Rust stuff in a separate less-privileged account.  There is support
+for this in the Makefile.  But if you want to run *everything* in the
+lesser account, you don't need to bother with that.)
+
+
+Dependencies - apologia
+-----------------------
+
+ * Rust Nightly
+
+   This is needed almost solely because Rocket needs it.  Rocket is
+   the web framework I am using.  The next version of Rocket (0.5.x),
+   which is in development, will not need Nightly, but it will also be
+   a serious compatibility break.  The existing Rocket (0.4.x) will
+   almost certainly never be ported to Stable Rust.  When Rocket 0.5.x
+   is out, porting Otter to it will go on my list - but it won't be
+   trivial.  Sorry.
+
+ * The many dependencies of Otter
+
+   These are partly because Rocket is a large piece of software with
+   much functionality.  But also because I favoured my own programming
+   convenience and in some cases was experimenting with different
+   approaches.  In practice, it seems to me that once I'm using Rocket
+   and WASM and resvg and so on, there is not that much to be gained
+   by trying to prune the dependencies of the otter package itself.
+
+ * bundle-rust-sources
+
+   This is mine, but it needs to be properly released.
+
+ * geckodriver (for the automated in-browser tests)
+
+   This is done with a protocol called "WebDriver" which is a
+   cross-browser way to puppet a browser.  There is a thing called
+   "geckodriver" which converts that to a firefox-specific protocol
+   for the same purpose, called "Marionette".  (In practice all this
+   seems to have lots of bugs and misfeatures.)
+
+   AFAICT the usual approach for using geckodriver to have it *bind to
+   a fixed TCP port accessible to all local programs*.  My wrapper
+   tooling arranges to run this in an ephemeral $HOME and a private
+   network namespace.
+
+   AFAICT the only practical way to get geckodriver is to download the
+   binary.  I got mine here:
+     https://github.com/mozilla/geckodriver/releases/tag/v0.28.0 You
+   You just dump the binary on your PATH.
+
+
+Final weirdness
+---------------
+
+ * The `Makefile` `deploy` target is very specific to my setup.
+
+ * For running on chiark I build with the Rust target
+   `x86_64-unknown-linux-musl` which on my system is configured to
+   produce a completely statically linked bionary.  I have this in my
+   `~/.cargo/config` (in the lesser privsep account):
+
+```
+[target.x86_64-unknown-linux-musl]
+rustflags = ["-C", "target-feature=+crt-static"]
+# ^ from https://stackoverflow.com/questions/31770604/how-to-generate-statically-linked-executables
+```
diff --git a/docs/user.md b/docs/user.md
new file mode 100644 (file)
index 0000000..724fe73
--- /dev/null
@@ -0,0 +1,167 @@
+OTTER - USER DOCUMENTATION
+==========================
+
+Basics; joining a game
+----------------------
+
+To join a game, you run a command like this on the server host:
+```
+  otter [--nick <nick>] join-game unix:ijackson::test
+                                       /^^^^^^^  ^^^^\
+                             game owner             game name
+```
+
+Tbis will print a URL.  You cut and paste that URL into your browser.
+It is not usually necessary to expliitly leave a game, although
+a `leave-game` subcommand is available.
+
+You can have the same URL open in multiple browsers if you wish.  The
+browser you use must support JavaScript and WebAssembly.  Cookies are
+not used; anyone with your link can see your view of the game.
+
+Game UI
+-------
+
+The main Otter UI is fairly sparse and is dominated by the game table
+area.  In that area are various elements such as cards, boards, chess
+pieces, or whatever.
+
+You can pick up and move those pieces about with the mouse.  When you
+move an object (henceforth, a "piece"), everyone else will see it move
+too.
+
+Only one player at once may "grasp" a piece.  If you and someone else
+both try to manipulate a piece at the same time, only one of your
+manipulations will take effect.  For example, if you both try to pick
+up and drag a piece right at the same time, whichever of you got to it
+last will see the piece "jump" out of your grasp.
+
+But in general different players can manipulate separate pieces (eg,
+separate cards) concurrently.
+
+
+Keyboard commands and special functions
+---------------------------------------
+
+Otter makes use of keyboard commands for many functions.  The UI will
+display a list of the currently-valid keyboard commands.  Note that
+the set of valid command can depend on what you have selected, and
+what state it is in.
+
+
+Hidden information - secrets, card shuffling, etc.
+--------------------------------------------------
+
+Otter supports what is known in gaming terms as "hidden information".
+
+This is achieved by special "pieces" which are capable of hiding, or
+scrambling, other pieces.  In Otter this is called "occultation".
+
+For example, a draw pile deck contains cards but maintains them
+shuffled and shows everyone only the backs of the cards.  Each time
+anyone draws a card, it is chosen randomly from whatever cards are in
+that draw pile.
+
+There are also occulters which treat different players differently.
+For example, there are "hand repositories".  When you have "claimed" a
+hand repository (with the keyboard command), it becomes "your hand".
+Any cards you put in it are identifable only by you.  You see the
+fronts of the cards, and their precise positions (and orientations).
+The other players see only a simplified view, showing the backs of
+cards in predetermined locations.  Another player can select a card
+from your hand, but their view of even which card is which is
+scrambled, so if they pick a card from your hand they get one selected
+at random.
+
+These special occulting pieces need to be activated before they do
+their thing.  This is done by selecting the occulter, and issuing
+keyboard commands.
+
+
+UI features
+-----------
+
+The UI has a number of features intended to ease play of various
+games.  It can be worth experimenting with the UI in a test game, to
+see how things work.  The information presented by the game interfae
+itself is meant as prompts and hints rather than full documentation.
+
+Notable features you might otherwise overlook include these:
+
+Pressuing "h" repeatedly cycles through various amounts of history
+view (the overliad yellow arrows showing what recently happened).
+
+Typing numbers will get you into a multiple selection mode, which you
+can use (for example) to draw yourself a hand of multiple cards.
+
+Typing a zero will get you into a special selection mode for selecting
+the lowermost piece.  This can useful to grasp a hand or pickup deck
+if it is covered in cards so you can't see it.
+
+Hands have an organise function, which lets you neaten the layout of
+the cards, or even sort them.  Select the hand and look for the `o`
+and `O` keyboard commands.
+
+There is a Wresting mode for making exceptional changes to the game
+state, such as forcibly grasping a piece out of another player's
+grasp.  Don't forget to exit Wresting mode when you're finished with
+it.
+
+
+Bugs and errors
+---------------
+
+Sometimes, bugs can cause things to mess up; in particular, you can
+see error messages on the screen in your browser.  They typically
+appear at the top, and they say "reloading may help".
+
+If this happens, do try simply reloading the page in your browser.
+Typically this will improve matters.  Hopefully the game state on the
+server side is not too badly affected.
+
+If you can reproduce a bug, please file a bug report;
+  https://salsa.debian.org/iwj/otter/-/issues/new
+
+Of course you might want to reload the Otter game page if you have
+trouble with your network or web browser.  The state is all on the
+server, so you can reload when you want to.
+
+
+Game administration
+-------------------
+
+Creating and modifying games is done via the `otter` command line
+utility.  See its `--help` message for full details.
+
+The most usual game-creation command looks something like this:
+
+```
+otter reset --reset-table local-users unix:ijackson::test demo
+                         /^^^^^^^^^^^                    /^^^^
+                         `table spec            game spec
+```
+
+Here `local-users` refers to the file `local-users.table.spec` in the
+Otter specs directory (`/volatile/Otter/specs` on chiark).  The table
+spec file handles access control (and some other global properties)
+This particular file says that all local shell account users may join
+the game.
+
+`demo` refers to the file `demo.game.spec`.  The "game spec" says what
+shape table is and what pieces there are.  This is a simple demo game.
+
+Currently there are also `penultima` and `mao` game specs.
+
+After a game has finished and you wnat to play again, you can put
+everything back to the starting state (or, even, the starting state
+for a different game) with something like this:
+
+```
+otter reset unix:ijackson::test demo
+           /^^^^^^^^^^^^^^^^^^^ ^^^^\
+        game name                   game spec
+```
+
+The `otter` command line tool has further subcommands for
+adding/removing players, for ad-hoc addition of pieces from the
+library to an existing game, and so on.