4 Otter is mostly written in Rust.
6 The web UI frontend is written in Typescript, with a small amount of
7 Rust support code delivered via WebAssembly.
9 The HTML and SVG skeleton is in a templating language called Tera,
10 which is a jinja-like but from the Rust community.
13 Ad-hoc testing, playing about, etc.
14 -----------------------------------
19 target/debug/daemon-otter server-test.toml
22 The server does not daemonise, and the default config there makes it
23 quite verbose. So, in another shell:
27 --account server: --config server-test.toml --spec-dir=specs \
28 --game test server::test reset --reset-table demo
31 --account server: --config server-test.toml --spec-dir=specs \
32 --game server::test join-game
35 The URL printed can then be visited in a local browser.
38 Resetting/restoring things after tests, updating server, etc.
39 -------------------------------------------------------------
41 After the server is updated, you can just `^C` and restart it. Games
42 are constantly saved (although there is an up-to-1s lag on the most
43 frequently updated game state).
45 If you want to clear out the server state, delete the files `[ag]-*`
46 and `accounts`. NB that you should do this with the server not
47 running, because the server has most of that information in memory and
48 will like to write it out again.
50 If you update Typescript (JS code) you will need to rerun `make` to
51 rebuild the JS output.
53 Apart from that, if you update JS or WASM code or Tera templates, you
54 do not need to restart the server - it will pick up changes
57 When testing, you do not need to `make bundled-sources` more than
58 once, at the beginning. So don't, because it's slow. But you
59 definitely should run it for every update if you make a deployment for
60 other people to use. Otherwise you might be running a privately
61 modified server without offering your users its source code. See
64 If you Do Something to the output from cargo, you should `rm stamp/*`,
65 since the `Makefile` won't notice, otherwise, that the relevant cargo
66 rune(s) need to be re-run. Needlessly deleting all the stamp files
67 wastes only a handful of seconds (on my stupidly fast laptop).
68 Deleting the stamp files is not needed if you simply edit Rust source
72 Adding shapes (pieces, cards, etc.) to the builtin library
73 ----------------------------------------------------------
75 (Consider making an uploadable game bundle instead.)
77 Otter's builtin shape libraries use SVGs. The sources for the SVGs
78 are all in the otter source tree, in the `library/` directory.
80 Each shape is listed in one of the ``library/*.toml`` files, in a
81 `files` entry. These are shape library catalogues, although in a
82 slightly different format to the ones found in bundles. (In
83 particular, the builtin libraries are not processed with Tera.)
85 You can preview the shapes, including any changes you make, without a
86 whole game server, by running `make -j8 shapelib`, and looking at
87 `templates/shapelib.html`. As above, this make rune will print the
88 `file://` url for you.
90 See the build instructions for information about how to install the
93 Some of these SVGs were scraped from Wikimedia. The scraper machinery
94 can perhaps be adapted to scrape SVGs from elsewhere.
96 You can also add your own SVGs in the `library/edited/` directory. If
97 you do that, please make sure to include the actual source code there
98 too. If you copied or adapted an SVG from somewhere, note the details
99 of where you got it (eg, in a git commit message).
101 Contributions should be via git branch, eg a merge request on Salsa:
102 [https://salsa.debian.org/iwj/otter](https://salsa.debian.org/iwj/otter)
104 NB that shapes must come with a licence compatible with CC-BY-SA 4.0
105 or GNU AGPLv3+. See `LICENCE` for more information about copyright status.
108 Navigating the otter source code
109 --------------------------------
113 The main Rust source code. This is mixture of code used only or
114 mainly by the server and code used by the `otter` command line
115 utility; these aren't split up in a wholly principled way. In Rust
116 terms this is a "library crate".
120 Support executables, including in particular the command line
121 utility `otter` which is used to set up and join games.
125 The Otter server. This is a simple binary crate. Much
126 functionality belonging primarily, or only, to the server is in
127 `src/`, simply because it was easier not to disentangle it.
128 Anything that needs Actix (the web framework) is in `daemon/`.
129 Generally, we try to keep async confined to there too.
133 Code shared by the host and the WebAssembly. Notably, the Z
134 coordinate handling, but also a a few other minor functions needed
135 by both client and server. To avoid duplication they are written
136 once in Rust and compiled twice - once for the host and once for
137 WebAssembly for use in the client. This crate is kept fairly small
138 to keeep the WebAssembly binary small (currently, ~140kby).
142 WebAssembly/Rust bindings for the items in `base/`. Produces the
143 single wasm file for use by the JavaScript, and corresponding
144 Typescript annotations etc.
146 * `templates/script.ts`
148 The main Typescript (typed Javascript) code. Otter's web
149 compatibility target is the earliest browser versions that properly
152 * `templates/session.tera`, `macros.tera`, etc.
154 Tera templates generating the main HTML screen. These templates are
155 filled in from structs in the Rust source code. The main files are
156 `session.tera` (portrait), `landscape.tera`, and `macros.tera`
157 (common), and their rendering uses an instance of
158 `SessionRenderContext` from `src/session.rs`.
162 "Non-web templates". Tera templates for things other than web
163 pages. Currently this includes the server's outgoing emails. These
164 are in a separate directory to distinguish them from the templates
165 for the actix webserver's Tera instance, which loads everything
166 in `templates/*.tera`.
170 Tests of the server which use its APIs - specifically, the
171 management socket (also used by the `otter` command line tool) and
172 the web API, but which do not use any JavaScript.
174 These are not standard Rust `#[test]` tests because they need to
175 reinvoke themselves via `bwrap` for test isolation reasons, and
176 because their dependencies are extensive and not properly capturable
177 in Cargo. They are run by `make check`.
179 The file `apitest/apitest.rs` also contains code which is reused by
184 WebDriver-based end-to-end tests. Each `wdt-*.rs` is one test
185 utility. `wdriver.rs` is the library for these, and contains most
186 of the heavy lifting.
188 The tests produce a single portmanteau binary to reduce compile
189 times. You run it with `target/debug/wdriver --test=wdt-something`.
193 Node.js-based unit tests.
195 * `specs/`. The table and game specs, as used directly by `otter`.
197 * `library/`: The shape libraries.
199 The program `./media-scraper` (which is not run by the `Makefile`)
200 reads `library/*.toml` for instructions and generates `files.make`
201 fragments. These fragments arrange to run `./usvg-processor` which
202 launders SVGs through `usvg`.
204 The shape libraries have a different, more relaxed, copyright
207 * `webassembly-types`: A git-subtree of "WebAssembly Types".
210 Automatic in-browser tests (`wdriver`)
211 --------------------------------------
213 `make check` runs all the tests; `make wdt` runs only the webdriver
214 (in-browser) tests. You can run an individual test with a rune like
218 OTTER_TEST_LOG=otter_webdriver_tests=trace CARGO_MANIFEST_DIR=~ian/Rustup/Game/server time target/debug/wdriver --test=wdt-simple --geckodriver-args=
221 (This rune has some example logging options in it, for you to change
222 if you like. You can omit the `CARGO_MANIFEST_DIR` for an in-tree
223 non-privsep build.) After a test has run, you can find screenshots,
224 etc. in `tmp/wdt-simple` or whatever. You can restart the same game
225 server setup as the test used, with the state left by the test, with a
229 target/debug/daemon-otter tmp/wdt-simple/server-config.toml
231 and then play with it at these urls:
233 http://localhost:8000/?kmqAKPwK4TfReFjMor8MJhdRPBcwIBpe
234 http://localhost:8000/?ccg9kzoTh758QrVE1xMY7BQWB36dNJTx
237 (Yes, those are fixed game access links, hardcoded by the tests.
238 You can bookmark them.)