chiark / gitweb /
docs: Document library magic items
[otter.git] / docs / shapelibs.rst
1 Shape libaries
2 ==============
3
4 Most pieces in a game in Otter will be from a shape library.
5
6 Introduction; general structure
7 -------------------------------
8
9 A shape library is a set of named pieces.  Mostly, it defines their
10 appearance.
11
12 Shape library pieces can have more or more sides (**faces**), and they
13 can also have an **occulted view** which is used when the identity of
14 the piece is to be hidden (possibly from only some of the players).
15
16 For example:
17
18 Playing cards have two faces: one is the front, which identifies the
19 card, and the other is the back, which is a generic card back.  Cards
20 also have an occulted view: again, the back.
21
22 Chess pieces usually have only one face.  The Knight has two faces,
23 because it is not symmetrical: the first face looks to the right, and
24 the other face to the left.  Chess pieces can be occulted, but when
25 they are occulted they reveal their shape but not their colour.  The
26 occulted view of a chess piece is a grey version of the piece.
27
28 A library has a **library name**.  This is a string.  For a library in
29 a bundle, it's the ``LIB`` part of the filename
30 ``libraries/LIB.toml``.
31
32 Each piece in a library has an **item name**.  Item names are unique
33 within a library.  The item name is used within Otter to refer to the
34 piece (for example, with ``otter library-add``).
35
36 Pieces in shape libraries cannot have "behaviours": they can't do
37 anything "special" like react to being moved or clicked on.  Pieces
38 with special functionality do exist, but they are built into Otter.
39 (See :ref:`gamespec:Piece specs` for all the kinds of piece.)
40
41 A library consists of a **catalogue**, and a set of **image files**
42 which contain the actual appearances.  When a library is in a bundle
43 the catalogue is ``libraries/LIB.toml`` and the image files are in a
44 directory ``libraries/LIB.toml``.  The layout of Otter's builtin
45 libraries is similar.
46
47 Image files
48 -----------
49
50 Otter supports uploading of SVG and PNG files.  They should be in the
51 directory ``library/LIB``, named after the item.  (See `Files entry`_
52 for details of how to specify the file names.)
53
54 Image files should be small --- ideally a handful of kilobytes, or
55 less.  SVG images should be of modest complexity.
56
57 Large image files don't just upload slowly; they also make the game
58 perform poorly when playing.  This is because the image files are
59 frequently (re)transmitted by the server to each client.
60
61 It is not normally necessary to specify images in great detail: they
62 take only a small space on the players' screens, so the resolution
63 does not need to be awesome.  As an example, the playing cards in the
64 builtin ``cards-oxymoron`` library are image files of just 73x97
65 pixels.
66
67 Catalogue
68 ---------
69
70 The catalogue defines what pieces the library contains.  For each
71 piece it defines each face looks like, how big it is on the screen,
72 whether and how the piece can be occulted, and what source image files
73 are to be used to display it.
74
75 The catalogue is a TOML file.
76
77 The file should have a toplevel key ``format``, specifying which
78 version of the Otter data formats the file was written to.
79 This document describes ``format=1``.
80 See :ref:`Bundle compatibility <bundle-compatibility>`.
81
82 The catalogue's main contents is a dictionary
83 ``groups``, mapping each group name to a sub-dict of parameters:
84
85 Each catalogue is organised into named **groups**.  Each group defines
86 some pieces.  It specifies various **parameters**, and also gives a
87 list of indvidual image files which should be processed according to
88 those parameters.
89
90 For example::
91
92   [group.dried]
93   outline = "Circle"
94   size = [14]
95   orig_size = [64, 48]
96   centre = [32,24]
97
98   files = """
99   dried-lemon   -       a dried lemon
100   """
101
102 This defines a group ``dried``, with parameters such as ``size`` and
103 ``outline``.  The ``files`` entry defines the list of pieces.
104
105 The group names are not visible when using the library, but they can
106 be used within the library using the ``inherit`` feature.
107
108 The builtin catalogues also have a toplevel dict ``scraper``, which
109 controls how the builtin shape data is processed during the build, and
110 how it is to be updated.  (Downloads are never automatically run
111 during the build.  If you updated the catalougue in a way that means
112 files should be re-downloaded, you should re-run ``./media-scraper
113 library/LIB.toml``.)
114
115 Files entry
116 -----------
117
118 Each group has an entry ``files``.  This is a string, which is treated
119 as a series of lines (so it is best to use the TOML multi-line string
120 syntax).
121
122 Each line of which has (normally) three fields (the leading ones
123 terminated by whitespace).  ``#`` comment lines are supported and
124 blank lines are ignored.
125
126 Each non-empty non-comment line in ``files`` specifies a single piece,
127 like this::
128
129    ITEM-SPEC SRC DESCRIPTION...
130
131 The **item name** of the piece will be ``ITEM-SPEC`` sandwiched
132 between the ``item_prefix`` and ``item_suffix`` parameters (see
133 below).
134
135 The **image filename** is derived from ``SRC`` or the item name, as
136 follows: ``library/LIB/SRC.svg`` or ``.png``.  If ``SRC`` is ``-``
137 then the item name is used for ``SRC``.  (Builtin libraries: these
138 support SVG only; and the ``SRC`` is not used at runtime, or when
139 loading shapes --- rather, only when scraping or building.)
140
141 ``DESCRIPTION`` is the **description**, a string which will be used to
142 describe the piece (eg in in-game log messages).  In English, it
143 should contain an article.  Eg, ``the black queen``, ``a white pawn``.
144 It will be HTML-escaped, so it should be plain text, not HTML.
145
146 It is also possible to specify additional data for each piece by
147 adding fields to each line in ``files``.  This is done by adding a
148 line at the start starting with ``:`` listing the extra fields, and
149 then additng one additional whitespace separated value before the
150 description on each data line.  Values given for unknown field are
151 ignored.
152
153 Currently the extra fields supported are:
154
155  * ``sort``: Specifies the sort key.  See the ``sort`` group
156    parameter.
157
158  * ``x...``: Can be referenced by templates in `"Magic" items`_.
159
160 The values for these extra fields come just before the
161 ``DWSCRIPTION``, after the other whitespace-delimited fields, in the
162 same order as specified in the ``:`` heading line.
163
164 Item names
165 ``````````
166
167 Item names do not need to be unique within a game, but there are
168 places where a piece is found *just* by the item name, so pieces
169 should have the same item name (only) if they are in some sense
170 equivalent.
171
172 Item names are conventionally structured using a hierarchical name
173 with ``-`` between the components.
174
175 The item name is a string but may contain only ASCII alphanumerics,
176 plain ASCII spaces, and the punctuation characters ``-._``.  Do not
177 put ``/`` or ``_`` in item names.  ``/`` is forbidden and ``_`` can
178 interfere with the template substitution system.
179
180 See the existing examples to see what item names usually look like.
181
182 Parameters
183 ----------
184
185 These are the entries which can appear in each ``group.GROUP``
186 dictionary:
187
188 Mandatory parameters
189 ````````````````````
190
191  * ``files``: The list of pieces to define, one per line.  See `Files
192    entry`_.  [multi-line string]
193
194  * ``outline`` [dictionary]: Defines the outline of the piece,
195    which is used for drawing "haloes" around the piece,
196    indicating selection and movement.
197
198  * ``outline`` [string]: Abbreviated way of specifying
199    ``outline = { shape: ... }``.
200    The shape mkust be specified, either via ``outline = "Shape"``
201    or by setting ``outline.shape``.
202
203  * ``outline.shape`` [``"Circle"`` or ``"Rect"`` ]:
204    If ``outline`` is ``Circle``, and the the nominal size
205    (calculated from all the other parameters)
206    has different width and height, the larger of the width and height is used
207    (ellipses are not supported).
208
209  * ``outline.size``: nominal size of the piece, used for calculating
210    the size of "haloes".  Note that this is not the szie of the
211    "haloes"; it is the (nominal) size of the piece image itself:
212    the "haloes" indicating selection etc. will be somewhat larger.
213    [1- or 2-element array of numbers: width and height;
214    default: calculated from the piece's ``size`` and ``scale`` ]
215
216  * ``outline.scale``: Adjusts the nominal size of the outline,
217    multiplying it by this factor.  Not meaningful together with
218    ``outline.size``.  [number; default ``1.0``]
219
220 Important parameters
221 ````````````````````
222
223  * ``inherit``: Causes this group to inherit
224    every parameter (except ``files``) from the group named by
225    ``inherit`` (recursively, if applicable).  [string: group name]
226
227    When inheritance is happening, there is of course a difference
228    between leaving a value unspecified, and specifying it to have
229    the usual default value: the latter would override any inherited
230    setting.
231
232  * ``item_prefix``, ``item_suffix``.  Prepended and appended to
233    ``ITEM-SPEC`` in ``files`` to produce the item name.  [strings]
234
235 Geometry parameters
236 ```````````````````
237
238  * ``centre``: The centre of the image, measured from the top left in
239    the image's own internal units.  If not supplied, calculated from
240    the size.  [2-element array]
241
242  * ``size``:
243    The size at which the piece will show up in the game, in nominal
244    game coordinate units.
245    The supplied SVG will be reiszed from its internall specified
246    witdth and height, to that specified.
247    If the aspect ratio does not match the supplied image,
248    ``scale`` controls the behaviour.
249    (Specifying only one value for ``size`` means a square of that size.)
250    [1- or 2-element array of numbers: width and height]
251
252    For reference: the builtin library's chess
253    pieces are 9.5 units; the builtin playing cards are 9.65, 17.125.
254
255  * ``scale`` [string]: Specifies what to do if the SVG's own size does
256    not have the same aspect ratio as a sspecified ``size``:
257
258     - ``"fit"``: the image is placed within the specified ``size``;
259     - ``"cover"``: the image is placed around the specified ``size``;
260     - ``"stretch"``: the image is distorted to become exactly ``size``.
261
262  * ``scale`` [number]: Specifies that the image SVG should be rescaled
263     by this amount.  This use of ``scale`` cannot be combined with ``size``.
264
265 Parameters for defining faces
266 `````````````````````````````
267
268  * ``flip``: Whether this piece can "flip".  If true, the piece will
269    have two faces, one of which is a mirror image of the other.  The
270    default face will be un-reflected version; the other face is the
271    same image, but flipped left-to-right.  [boolean]
272
273    It doesn't make sense to enable this for pieces with a symmetrical
274    appearance.  (It is a bad idea to have the game contain state which
275    is not visible to the players.)  Not compatible with ``back``.
276
277  * ``back``: [:ref:`Piece spec <gamespec:Piece Specs>`].  The back of
278    this piece looks like some other piece (typically, another library
279    item such as a card back).  If specified, the piece will have two
280    faces: the one implied by its ``files`` entry, and a 2nd face
281    looking like ``back``.  If you want to make the piece be
282    occultable, you must also specify ``occulted``.  ``back`` is not
283    compatible with ``flip``.
284
285 "Magic" items
286 `````````````
287
288 The shape library primarily defines inert image pieces.  But it is
289 also possible to define, as part of a library, a non-inert behaviour
290 to go with an image.  (These could be defined directly, in game spec
291 files, but library items are more convenient to reuse, since the
292 necessary parameters do not need to be recapitulated for each use.)
293
294 Magic items are produced by a ``magic`` section in the group.  This is
295 applied once for each item (ie, once for each entry in ``files``).
296 The ``magic`` section generates an additional item in the library for
297 each ordinary item defined by the group via its ``files``.
298
299 The magic item is typically defined using a non-library piece spec type,
300 and usually references the corresponding ordinary (base) item.
301
302 The magic section in the group may contain:
303
304  * ``magic.item_prefix``, ``magic.item_suffix``
305    [strings, default ``""``].
306    Defines the magic item name.  The item name to define is assembled
307    the same way as the base image item name, only with these prefix
308    and suffix instead of the main ones in the group.
309
310  * ``template``.  Template which will generate TOML defining the magic
311    piece.  The string value has variables ``${...}`` expanded, and
312    is then reparsed as a new piece of nested TOML.  The resulting
313    dictionary must be a valid :ref:`Piece Spec <piece-specs>`
314    Substitution variables are (in precedence order):
315
316    - ``${CVAR}``, the value of ``colours.COLOUR.substs.CVAR``
317      for the current ``COLOUR``, and for each ``SVAR`` defined there.
318
319    - ``${SVAR}``, the value of ``magic.substs.SVAR`` for each
320      any ``SVAR`` defined there.
321
322    - ``${x...}``, values of extra fields in the ``files`` list
323      (but only those starting with an ``x``).
324
325    - ``${image}`` a TOML in-line dictionary for the piece
326      spec for the base item.  (The substitution references the
327      containing library by name, so it is possible that later-loaded
328      libraries might intercept this reference.)
329    
330    - ``${colour}``, the recolouring name from the ``colours``
331      group parameter.
332
333  * ``substs``: Extra substitutions for the template.
334
335 Other group parameters
336 ```````````````````````
337    
338  * ``sort``.  The sort key.  Used for item sorting in hands.  When the
339    user asks to sort their hand, all the items in it are sorted
340    according to (primarily) simply this sort key, interpreted
341    lexicographically.  [string]
342
343    The sort key should generally contain all of the information in the
344    item name; if the item name contains an element referring to style
345    or aesthetic, that should appear at the end of the sort key (if at
346    all).
347
348    If neither the group parameter, nor the ``files`` extra field
349    ``sort``, are specified, the item name is used as the sort key.
350
351    If both are specified, the group parameter is used as a template:
352    ``_s`` is replaced by the ``sort`` extra field from the ``files``
353    list; ``_c`` is replaced by the colour, if applicable.
354
355  * ``colors`` [dictionary].
356    If specified and non-empty, specifies that this group should be
357    instantiated multiple times, for different colours.
358
359    For each entry in the ``colours`` dict, a separate piece is
360    generated for each item in the ``files`` list.  The keys of the
361    ``colours`` are recolouring names, and the values are sub-tables.
362
363    Every effective item name (i.e., after the ``item_prefix`` and
364    ``item_suffix`` have been added) must contain the substring ``_c``
365    exactly once, and every item description must contain the substring
366    ``${colour}`` exactly once.  ``_c`` in the item name will be
367    replaced with the value of the recoluring's ``abbrev``, and
368    ``${colour}`` with the recolouring name (the key of the ``colours``
369    dict).
370
371    For libraries in bundles, a separate image file must be supplied
372    for each recolouring.  If ``SRC`` is not ``-``, it also must
373    contain ``_c`` which will be substitued with ``abbrev`` to find the
374    colour-specific image file.
375
376    For builtin libraries, the Otter build system will do the
377    recolouring automatically at build time; each recolouring should
378    have a ``map`` entry which is a sub-sub-dict mapping input colours
379    (strings in ``#rrggbb`` format) to output colours.
380
381  * ``desc`` [string: template]: : If specified, provides a template
382    for the description, to allow formulaic descriptions of pieces in
383    this group.  The string specified by ``desc`` must contain ``${desc}``
384    exactly once; that will be replaced with the description calculated
385    according to the other rules.  (``${desc}`` substitution happens
386    after ``${colour}`` substitution.)
387
388  * ``occulted`` [dict, contents depend on ``occulted.method``].  If
389    specified, these pieces be occulted.  For example, when a player
390    has them in their hand and the hand is active and owned by them,
391    only the occulted view (eg, the back of a playing card) will be
392    shown.  ``occulted`` is a dict whose other contents depend on its
393    ``method`` entry, which must be a string:
394
395   * ``"ByColour"``: Occult by displaying a particular recolouring of
396     this piece.  The sub-entry ``occulted.colour`` names a
397     recolouring - one of the keys of the ``colours`` group parameter.
398     When the piece is occulted it will show that colour, instead of
399     its actual colour.  In the description, ``${colour}`` will be elided
400     rather than substituted (along with up to one of any spaces either
401     side of it).
402
403   * ``"ByBack"``: Occult by displaying the back of this piece, as
404     specified by the ``back`` group parameter.  The ``occulted`` dict
405     must also contain a sub-entry ``ilk``, a string.  Pieces which
406     have the same ``ilk`` display identically when occulted, even if
407     the different piece definitions imply different backs.  (Whichever
408     pieces are first loaded define what the backs of a particular ilk
409     look like.)
410
411     For pieces that are like cards, the ilk should be different for
412     cards which have different backs in the game.  Generally, standard
413     playing cards should all specify ``card-back``.