chiark / gitweb /
changelog: document further make-release changes
[otter.git] / docs / dev.md
1 Developing
2 ==========
3
4 Otter is mostly written in Rust.
5
6 The web UI frontend is written in Typescript, with a small amount of
7 Rust support code delivered via WebAssembly.
8
9 The HTML and SVG skeleton is in a templating language called Tera,
10 which is a jinja-like but from the Rust community.
11
12
13 Ad-hoc testing, playing about, etc.
14 -----------------------------------
15
16 In one shell:
17
18 ```
19      target/debug/daemon-otter server-test.toml
20 ```
21
22 The server does not daemonise, and the default config there makes it
23 quite verbose.  So, in another shell:
24
25 ```
26     target/debug/otter                                               \
27         --account server: --config server-test.toml --spec-dir=specs \
28         --game test server::test reset --reset-table demo
29
30     target/debug/otter                                               \
31         --account server: --config server-test.toml --spec-dir=specs \
32         --game server::test join-game
33 ```
34
35 The URL printed can then be visited in a local browser.
36
37
38 Resetting/restoring things after tests, updating server, etc.
39 -------------------------------------------------------------
40
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).
44
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.
49
50 If you update Typescript (JS code) you will need to rerun `make` to
51 rebuild the JS output.
52
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
55 automatically.
56
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
62 LICENCE.
63
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
69 files.
70
71
72 Adding shapes (pieces, cards, etc.) to the builtin library
73 ----------------------------------------------------------
74
75 (Consider making an uploadable game bundle instead.)
76
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.
79
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.)
84
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.
89
90 See the build instructions for information about how to install the
91 tools you will need.
92
93 Some of these SVGs were scraped from Wikimedia.  The scraper machinery
94 can perhaps be adapted to scrape SVGs from elsewhere.
95
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).
100
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)
103
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.
106
107
108 Navigating the otter source code
109 --------------------------------
110
111 * `src/`
112
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".
117
118 * `src/bin/*.rs`
119
120   Support executables, including in particular the command line
121   utility `otter` which is used to set up and join games.
122
123 * `daemon/`
124
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.
130
131 * `base/`
132
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).
139
140 * `wasm/`
141
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.
145
146 * `templates/script.ts`
147
148   The main Typescript (typed Javascript) code.  Otter's web
149   compatibility target is the earliest browser versions that properly
150   support WebAssembly.
151
152 * `templates/session.tera`, `macros.tera`, etc.
153
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`.
159
160 * `nwtemplates/`
161
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`.
167
168 * `apitest/`
169
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.
173
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`.
178
179   The file `apitest/apitest.rs` also contains code which is reused by
180   the WebDriver tests.
181
182 * `wdriver/`
183
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.
187
188   The tests produce a single portmanteau binary to reduce compile
189   times.  You run it with `target/debug/wdriver --test=wdt-something`.
190
191 * `jstest/`
192
193   Node.js-based unit tests.
194
195 * `specs/`.  The table and game specs, as used directly by `otter`.
196
197 * `library/`: The shape libraries.
198
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`.
203
204   The shape libraries have a different, more relaxed, copyright
205   licence.
206
207 * `webassembly-types`: A git-subtree of "WebAssembly Types".
208
209
210 Automatic in-browser tests (`wdriver`)
211 --------------------------------------
212
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
215 this:
216
217 ```
218   OTTER_TEST_LOG=otter_webdriver_tests=trace CARGO_MANIFEST_DIR=~ian/Rustup/Game/server time target/debug/wdriver --test=wdt-simple --geckodriver-args=
219 ```
220
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
226 rune like this:
227
228 ```
229   target/debug/daemon-otter tmp/wdt-simple/server-config.toml
230 ```
231 and then play with it at these urls:
232 ```
233   http://localhost:8000/?kmqAKPwK4TfReFjMor8MJhdRPBcwIBpe
234   http://localhost:8000/?ccg9kzoTh758QrVE1xMY7BQWB36dNJTx
235 ```
236
237 (Yes, those are fixed game access links, hardcoded by the tests.
238 You can bookmark them.)