1 OTTER - ONLINE TABLE TOP ENVIRONMENT RENDERER
2 =============================================
4 Otter is an online "table simulator" intended to be suitable for board
7 It is accessed from a web browser running JavaScript. The server runs
8 on a convenationl Unix host. Currently, joining a game requires a
9 unix shell account on the server.
11 The game does not have a built-in text chat system, nor any other
12 communication other than via moving the game pieces. I expect it to
13 be used with a concurrent voice chat, or perhaps a concurrent text
14 chat program. Right now the arrangements for the chat must be agreed
15 by the players without help from the Otter server.
17 Right now Otter is in an alpha state.
25 otter join-game unix:<user>::<game-name>
29 otter join-game unix:ijackson::test
32 See `otter --help` for further options, including setting your nick.
34 Currently when a new player joins a game (with the `otter` command),
35 all the other players must reload the page.
42 otter reset --reset-table local-users :test demo
43 /^^^^^^^^^^^ ^^^\ ^^^^'~ game spec
47 Here `local-users` refers to the file `local-users.table.spec` in the
48 Otter specs directory (`/volatile/Otter/specs` on chiark). The table
49 spec file handles access control (and some other global properties)
50 This particular file says that all local shell account users may join
53 `:test` is the game name. It starts with a colon, which means
54 implicitly `unix:<whoami>::test`. Other people have to name the game
55 with the full name, with all three colons in it.
57 `demo` refers to the file `demo.game.spec`. The "game spec" says what
58 shape table is and what pieces there are. This is a simple demo game.
59 There is also `penultima` which is a work-in-progress set of pieces
60 suitable for fairy chess etc.
62 See `otter --help` for some more options.
64 Currently, resetting a game (or otherwise adding or removing pieces)
65 will mean all the players will get errors until they reload the page.
71 If you want to use existing piece shapes that Otter already knows
72 about, you can do this by providing a `<something>.game.toml` file.
73 The format of these files is a TOML document representing a GameSpec
74 as found in `src/spec.rs` in the Otter source code.
76 todo: use rustdoc to provide this somewhere.
82 Otter uses SVGs. The sources for the SVGs are all in the otter source
83 tree, in the `library/` directory.
85 Unfortunately the mechanisms here are not yet particularly well
88 Some of these SVGs were scraped from Wikimedia. The scraper machinery
89 can perhaps be adapted to scrape SVGs from elsewhere.
91 You can also add your own SVGs in the library/edited/ directory.
92 If you do that, please make sure to include the actual source code.
93 If you copied or adapted an SVG from somewhere, provide details.
95 Contributions should be via git branch, eg a merge request on Salsa:
96 [https://salsa.debian.org/iwj/otter](https://salsa.debian.org/iwj/otter)
98 NB that shapes must come with a licence compatible with CC-BY-SA 4.0.
99 See `LICENCE` for more information about copyright status.
105 You will need about 5500 megabytes of disk space, and a good internet
106 connection. Your computer will be compiling a lot of code.
108 These instructions have been tested on Debian buster.
115 sudo apt install build-essential cpio git curl \
116 pkg-config libssl-dev \
120 2. Install Rust. This is most easily done with rustup:
123 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
126 and then follow the instructions about your `PATH`. If this rune
127 alarms you, see below about Rust privsep.
129 3. Switch your Rust install to use Rust Nightly and add the WASM
133 rustup default nightly
134 rustup target add wasm32-unknown-unknown
137 Unfortunately, it is possible that the Rust nightly you find when
138 you run this is missing some pieces. The following is known to
139 work (with otter from the time of writing):
141 rustup default nightly-2020-11-09
144 4. Install some build tools:
148 cargo install bundle-sources
151 This will put them in `~/.cargo/bin`, which you presumably have on
152 your PATH (or the above `rustup` and `cargo` runes wouldn't work).
154 5. Install the version of wasm-pack with the option I need (upstream
155 haven't reviewed my merge request):
158 git clone https://github.com/ijackson/wasm-pack.git -b cargo-opts
163 NB that wasm-pack will itself download and install more stuff when
164 it is run by the Otter Makefile.
171 git clone https://salsa.debian.org/iwj/otter
173 make -j8 all bundled-sources
183 target/debug/daemon-otter server-test.toml
186 The server does not daemonise, and the default config there makes it
187 quite verbose. So, in another shell:
191 --account server: --config server-test.toml --spec-dir=specs \
192 reset --reset-table test server::test demo
195 --account server: --config server-test.toml --spec-dir=specs \
196 join-game server::test
199 The URL printed can then be visited in a local browser.
202 Resetting/restoring things after tests, updating server, etc.
203 -------------------------------------------------------------
205 After the server is updated, you can just `^C` and restart it. Games
206 are constantly saved (although there is an up-to-1s lag on the most
207 frequently udpated game state).
209 If you want to clear out the server state, delete the files `[ag]-*`
210 and `accounts`. NB that you should do this with the server not
211 running, because the server has most of that information in memory and
212 will like to write it out again.
214 If you update Typescript (JS code) you will need to rerun `make` to
215 rebuild the JS output.
217 Apart from that, if you update JS or WASM code or Tera templates, you
218 do not need to restart the server - it will pick up changes
221 When testing, you do not need to `make bundled-sources` more than
222 once, at the beginning. So don't, because it's slow. But you
223 definitely should run it for every update if you make a deployment for
224 other people to use. Otherwise you might be running a privately
225 modified server without offering your users its source code. See
228 If you Do Something to the output from cargo, you should `rm stamp/*`,
229 since the `Makefile` won't notice, otherwise, that, the relevant cargo
230 rune(s) need to be re-run. Needlessly deleting all the stamp files
231 wastes only a handful of seconds (on my stupidly fast laptop).
234 Navigating the otter source code
235 --------------------------------
239 The main Rust source code. This is mixture of code used only by the
240 server and code used by the `otter` command line utility; these
241 aren't split up. In Rust terms this is a "library crate".
243 * `src/bin/*.rs`: The actual executables.
245 * `wasm/*.rs`: We ship WebAssembly bindings for a few things, mostly
246 to avoid having to write the code twice - once in Rust and once in
249 * `zcoord/*.rs`: Code shared by the host and the WebAssembly.
250 Notably, the Z coordinate handling, but also a
251 string-timestamp-handling function. This is a separate library
252 crate so that we don't have to compile Rocket for WASM...
254 * templates/script.ts
256 The main Typescript (typed Javascript) code. Otter's web
257 compatibility target is the earliest browser versions that properly
260 * `templates/session.tera`, `macros.tera`, etc.
262 Tera templates generating the main HTML screen. These templates are
263 filled in from structs in the Rust source code. In the case of
264 `session.tera` and `macros.tera`, the rendering uses an instance of
265 `SessionRenderContext` from `src/session.rs`.
269 The shape libraries. The program `./media-scraper` (which is not
270 run by the `Makefile`) reads `library/*.toml` for instructions and
271 generates `files.make` fragments. These fragments arrange to run
272 `./usvg-processor` which launders SVGs through `usvg`.
276 Rust, cargo, curl|bash-ware; privsep
277 ------------------------------------
279 If you follow the above instructions you will have downloaded and
280 executed - and, therefore, trusted:
282 * Various Debian packages - safe
283 * Rustup (the Rust downloader/installer) - this is pretty safe
284 * Rust itself - again, pretty safe
285 * Otter itself - well, I wrote this; up to you.
286 * My branch of wasm-pack - I haven't audited what I started with.
287 * 236 transitive dependencies of otter (from crates.io)
288 * 50 transitive dependencies of bundle-sources
289 * the transitive dependencies of resvg
290 * god knows how many transitive dependencies of wasm-pack
291 * whatever wasm-pack downloads at runtime (mostly(?) via cargo)
293 You will have trusted the integrity of the following:
295 * The Debian archive (via its apt keyring) (very good)
296 * Rustup's and Rust's TLS keyholders (good, I think)
297 * The HTTP TLS cabal (sigh)
298 * github (pretty good in practice)
299 * crates.io (extremely poor traceability)
300 * the project management of hundreds of random crates.io libraries
302 If this makes you uncomfortable, as it should, you may wish to
303 consider running everything in a separate shell account, or a VM or
304 container of some kind.
306 (I have a not-properly-released tool called "nailing-cargo" which
307 makes it possible to do most things in my main account but run the
308 Rust stuff in a separate less-privileged account. There is support
309 for this in the Makefile. But if you want to run *everything* in the
310 lesser account, you don't need to bother with that.)
313 Dependencies - apologia
314 -----------------------
318 This is needed almost solely because Rocket needs it. Rocket is
319 the web framework I am using. The next version of Rocket (0.5.x),
320 which is in development, will not need Nightly, but it will also be
321 a serious compatibility break. The existing Rocket (0.4.x) will
322 almost certainly never be ported to Stable Rust. When Rocket 0.5.x
323 is out, porting Otter to it will go on my list - but it won't be
326 * The many dependencies of Otter
328 These are partly because Rocket is a large piece of software with
329 much functionality. But also because I favoured my own programming
330 convenience and in some cases was experimenting with different
331 approaches. In practice, it seems to me that once I'm using Rocket
332 and WASM utilities and resvg and so on, there is not that much to
333 be gained by trying to prune the dependencies of the otter package
338 This is a wrapper program for various utilities for manipulating
339 WebAssembly files, and their Typescript and Javascript glue, etc.
340 It likes to run cargo and do god knows what. I'm not sure it's
341 buying me much over whatever things it runs, so ideally it would be
342 best to replace this with calls to the underlying utilities and
343 libraries. But there are some wrinkles, for example, some version
344 coupling requirements that wasm-pack takes care of. And to be
345 honest, I'm not sure precisely what it does and understanding that
346 would be a necessary first step to reproducing it in the Makefile.
348 * bundle-rust-sources
350 This is mine, but it needs to be properly released.
356 * For running on chiark I build with the Rust target
357 `x86_64-unknown-linux-musl` which on my system is configured to
358 produce a completely statically linked bionary. I have this in my
359 `~/.cargo/config` (in the lesser privsep account):
362 [target.x86_64-unknown-linux-musl]
363 rustflags = ["-C", "target-feature=+crt-static"]
364 # ^ from https://stackoverflow.com/questions/31770604/how-to-generate-statically-linked-executables