rs_dossier
Every piece of paper in *Red String Over the Atlantic* has a face of its own. This module draws them and bakes them into the world's texture assets, so any other slice can put a real object on the board with one string.
rs_dossier — the evidence, as objects
Every piece of paper in Red String Over the Atlantic has a face of its own. This module draws them and bakes them into the world's texture assets, so any other slice can put a real object on the board with one string.
Using it
local Dossier = Core.need("dossier")
-- a finished widget, at the true proportion of the sheet
Dossier.face("wire_0212", { width = 320, onClick = "pick_wire_0212" })
Dossier.portrait("hallam", { width = 200 })
-- or just the texture name, if you would rather build the node yourself
local name, baked = Dossier.evidenceArt("wire_0212") --> "rs_ev_wire_0212", true
local name, baked = Dossier.portraitArt("hallam") --> "rs_por_hallam", true
Nothing throws and nothing returns nil for a card it does not know. A card with no baked texture falls back to its inline SVG; a card with no plate at all falls back to typed text on a paper-coloured ground. The board always has something to pin.
What is in it
| Call | What it gives you |
|---|---|
Dossier.face(id, o) | the card as a widget tree — baked texture, else inline SVG, else typed fallback |
Dossier.portrait(personId, o) | a mounted photographic print as a widget tree |
Dossier.evidenceArt(id) | name, baked — the texture name from the art contract |
Dossier.portraitArt(personId) | name, baked |
Dossier.svg(id, card) | the inline SVG for a card, for an svg widget at any size |
Dossier.aspect(id) | width ÷ height of that sheet — a flimsy is not a statement |
Dossier.kind(id) | telegram / testimony / document / plan / object / photograph |
Dossier.person(id) | name, role and caption for one of the eight |
Dossier.people | all eight, in order, the victim first |
Dossier.ids() | every card id that has a face here |
Dossier.status() | how many of the thirty-five plates are baked, and which are not |
Dossier.bake() | redraw and re-import every drawn card (edit mode) |
Dossier.ink | the drawing primitives, for a slice that wants to draw its own paper |
The kinds of paper
- Wireless flimsy — a strip torn off the operator's spool, printed letterhead, the message in block capitals, the station stamp struck across the corner and the operator's initials in pencil.
- Typed statement — onionskin, a rusted paperclip, one letter struck over, and a signature in ink.
- Manifest page — ruled and columned, with one line gone round in red.
- The deck plan — A deck drawn to scale with the six stations where the ship actually puts them, an inboard profile of the keel below it, and somebody's pencil all over it.
- Ticket stub — torn off at the perforation, deco border, coupon number.
- Printed slip — the Lloyd's endorsement, the cargo note, a wax seal.
- Log page — ruled, torn out of the watch book, one entry in a different hand.
- Exhibit card — the object photographed against a dark board with the purser's typed label gummed under it.
- Photographic plate — a print in a white mount with a pencil caption.
Where the art lives
/source/art/rs_ev_<cardId>.texture and /source/art/rs_por_<personId>.texture,
which is exactly what Core.art.evidence(id) and Core.art.portrait(p) name.
Each is baked from an SVG this module generates, so Dossier.bake() in edit
mode redraws all of them from source.
Three things to know before you draw more paper
Dossier.ink is the same brush this module paints with — paper grounds, torn
edges, typewriter blocks with the platen's wander, rubber stamps, pencil
annotation, and photographic emulsion.
- Set type in the families the SVG rasteriser resolves, which are not the
strings
Core.typeuses.Ink.facenames the five that work:Anton,Archivo Black,EB Garamond,PT Serif, andLiberation Monofor anything typed. A family it cannot match draws nothing at all, and the import still reports success. - Filters are available and they are what make paper look like paper.
url(#fib)is laid fibre,url(#emul)is film grain, and#soft/#softer/#softest/#crispare the blurs that stop a shape reading as a shape. A nested<svg x y width height viewBox>clips whatever is drawn inside it. - Draw across frames. A plate is a few thousand shapes; baking a dozen in
one call runs past the per-frame budget and the watchdog takes the VM.
Dossier.bake()yields between plates.
Scoped to this part · feeds back into the world's score.