Skip to content

osrforge.tracing.truth

The geometry truth format: what a map shows, and the levels and areas made from it.

One document describes one adventure module's maps. It has two layers. The reading layer is what the map shows: each printed Region with its registration, and each Panel with its cells, edges, key marks, outlines, and symbols. The resolution layer is what the rules in docs/tracing-conventions.md make from that reading: each Level with its grid, areas, placed keys, transitions, and passages, and each Dungeon with its entrance. An answer key and a synthetic map's answer fill both layers. A trace fills both too, and may add repairs and before_repair.

Cells are addressed as "x,y", with x the column from the west edge and y the row from the north edge of the grid, both 0-based, the same addresses the overrides contract uses. An edge is "x,y:side", the named side of that cell. Cell and edge readings are letter grids: one string per row, one letter per cell or edge, so a 50 by 50 level is readable in a text editor and small on disk.

Examples:

from osrforge.tracing.truth import EdgeGrids, parse_cell

grids = EdgeGrids(vertical=("wow",), horizontal=("ww", "ww"))
assert grids.at((0, 0), "east") == "o"
assert parse_cell("3,4") == (3, 4)

CELL_LETTERS module-attribute

CELL_LETTERS = '.#~'

The cell letters: . floor, # rock, ~ water.

EDGE_LETTERS module-attribute

EDGE_LETTERS = 'opwndls-'

The edge letters, in the order EdgeLetter lists them.

SYMBOL_KINDS module-attribute

SYMBOL_KINDS: tuple[str, ...] = get_args(SymbolKind)

The SymbolKind values, in vocabulary order.

EdgeLetter module-attribute

EdgeLetter = Literal['o', 'p', 'w', 'n', 'd', 'l', 's', '-']

One edge reading: open, printed open line, wall, window, door, locked door, secret door, or no reading.

- stands where neither side of the edge is floor or water. Every other position has a letter. Open and printed open line are the two passable readings.

PageSide module-attribute

PageSide = Literal['top', 'right', 'bottom', 'left']

A side of the printed page, for where a compass points and where an image edge cuts a region off.

Rotation module-attribute

Rotation = Literal[0, 90, 180, 270]

A quarter turn clockwise, in degrees.

Side module-attribute

Side = Literal['north', 'east', 'south', 'west']

A side of a cell, named for the grid's own directions: north is the top row of the grid.

Style module-attribute

Style = Literal[
    "tsr_blue", "black_white", "dark_rock", "cave", "hex", "isometric", "side_view", "outdoor", "town", "no_grid"
]

A map's drawing style.

The first four are plan views the stage traces. The rest are styles it refuses (hex, isometric, side_view, outdoor, town) or can't register (no_grid).

SymbolKind module-attribute

SymbolKind = Literal[
    "stairs",
    "ladder",
    "trapdoor",
    "hinged_floor",
    "chute",
    "slide",
    "pit",
    "cave_mouth",
    "pillar",
    "statue",
    "pool",
    "steps",
    "bridge",
    "footing",
    "locked_door",
]

The symbol vocabulary: what a map symbol or a legend entry can be.

cave_mouth stands on an edge. footing marks steps, footings, or bars drawn on one bank of water, and two footings facing each other across water make a crossing. steps is steps inside a level and never makes a crossing. locked_door is a legend entry only: a locked door on the map is the edge letter l.

Area

Bases: BaseModel

A keyed area of a level.

cells class-attribute instance-attribute

cells: tuple[str, ...] = Field(min_length=1)

synthesized class-attribute instance-attribute

synthesized: bool = False

True when the key's area was made on rock because the map prints no room for it.

Compass

Bases: BaseModel

Where north is on the page.

The level grid takes the map's north: panel placement turns each panel by the quarter turn that puts north at the top. A printed compass that isn't on a quarter turn records its angle, and north is the nearest quarter turn, which the report flags. Exactly halfway, the quarter turn counter-clockwise of the compass wins: 45 degrees is top, 135 right, 225 bottom, and 315 left.

north instance-attribute

north: PageSide

The page side the map's north points to, to the nearest quarter turn. top when the map prints no compass.

printed instance-attribute

printed: bool

True when the map prints a compass. When false, the report flags the default.

angle class-attribute instance-attribute

angle: float | None = None

The printed compass's direction in degrees clockwise from the top of the page, when it isn't on a quarter turn: 0 is the top, 90 the right edge. None when the compass points along a page side or the map prints none.

DamagedEdge

Bases: BaseModel

One edge a repair changed, with its readings before and after.

edge instance-attribute

edge: str

The edge, in the level's coordinates.

before instance-attribute

before: EdgeLetter

after instance-attribute

after: EdgeLetter

Dungeon

Bases: BaseModel

One dungeon: its levels and its entrance.

id instance-attribute

id: str

The survey's canonical dungeon id.

name instance-attribute

name: str

entrance class-attribute instance-attribute

entrance: Entrance | None = None

The entrance, or None when every level fell back.

levels class-attribute instance-attribute

levels: tuple[Level, ...] = Field(min_length=1)

EdgeGrids

Bases: BaseModel

The edge readings of a grid, as two letter grids.

vertical has one row per grid row and one letter per grid line that runs north to south, so each row is one letter longer than the grid is wide: letter j of row y is the west side of cell (j, y), and the last letter is the east frame. horizontal has one row per grid line that runs east to west, so it has one more row than the grid: letter x of row i is the north side of cell (x, i), and the last row is the south frame.

vertical instance-attribute

vertical: tuple[str, ...]

One row per grid row, width + 1 letters each.

horizontal instance-attribute

horizontal: tuple[str, ...]

height + 1 rows, width letters each.

width property

width: int

The grid's width in cells.

height property

height: int

The grid's height in cells.

at

at(cell: tuple[int, int], side: str) -> str

The letter on one side of a cell.

Parameters:

Name Type Description Default
cell tuple[int, int]

The (x, y) pair.

required
side str

Which side.

required

Returns:

Type Description
str

The edge letter.

with_letter

with_letter(cell: tuple[int, int], side: str, letter: str) -> EdgeGrids

A copy with one edge changed.

Parameters:

Name Type Description Default
cell tuple[int, int]

The (x, y) pair.

required
side str

Which side of it.

required
letter str

The new edge letter.

required

Returns:

Type Description
EdgeGrids

The new grids. This one is unchanged.

positions

positions() -> Iterable[tuple[tuple[int, int], str]]

Every edge once, as the cell and side that name it.

Each interior edge is named from its west or north cell. The east and south frame edges are named from the cell inside them.

Yields:

Type Description
Iterable[tuple[tuple[int, int], str]]

(cell, side) pairs in row-major order.

Entrance

Bases: BaseModel

Where the party arrives from town.

level class-attribute instance-attribute

level: int = Field(ge=1)

cell instance-attribute

cell: str

GeometryTruth

Bases: BaseModel

One module's maps and the levels made from them.

An answer key or a synthetic answer has no repairs and no before_repair. A trace has both when the checks repaired anything.

schema_version class-attribute instance-attribute

schema_version: int = 1

pages class-attribute instance-attribute

pages: tuple[Page, ...] = ()

regions class-attribute instance-attribute

regions: tuple[Region, ...] = ()

panels class-attribute instance-attribute

panels: tuple[Panel, ...] = ()

half_pairs class-attribute instance-attribute

half_pairs: tuple[HalfPair, ...] = ()

dungeons class-attribute instance-attribute

dungeons: tuple[Dungeon, ...] = Field(min_length=1)

repairs class-attribute instance-attribute

repairs: tuple[Repair, ...] = ()

before_repair class-attribute instance-attribute

before_repair: GeometryTruth | None = None

The same document as the rules left it before any repair, its panels the reading as read. A trace fills it when it made repairs, and the trace's own panels then carry the reading with each repair mapped back onto its panel.

north_in_force

north_in_force(region_id: str) -> PageSide

The page side a region's north points to, taking a half's partner's compass when the region prints none.

Parameters:

Name Type Description Default
region_id str

The region's id.

required

Returns:

Type Description
PageSide

The region's own compass.north when it prints a compass, else its half pair partner's when that

PageSide

prints one, else the region's recorded default.

region

region(region_id: str) -> Region

The region with an id.

Parameters:

Name Type Description Default
region_id str

The id.

required

Returns:

Type Description
Region

The region.

Raises:

Type Description
KeyError

If no region has that id.

panel

panel(panel_id: str) -> Panel

The panel with an id.

Parameters:

Name Type Description Default
panel_id str

The id.

required

Returns:

Type Description
Panel

The panel.

Raises:

Type Description
KeyError

If no panel has that id.

level

level(dungeon_id: str, number: int) -> Level

A level by dungeon id and number.

Parameters:

Name Type Description Default
dungeon_id str

The dungeon's id.

required
number int

The level number.

required

Returns:

Type Description
Level

The level.

Raises:

Type Description
KeyError

If the document has no such level.

HalfPair

Bases: BaseModel

Two regions that are halves of one map, and how the stage handled them.

regions instance-attribute

regions: tuple[str, str]

The two region ids, in page order.

joined instance-attribute

joined: bool

True when the halves became one panel, false when they stayed apart as two panels linked by passages.

rows instance-attribute

rows: int

The row shift: the second half's row 0 lies this many rows south of the first half's row 0.

columns class-attribute instance-attribute

columns: int | None = None

The whole-cell column offset of the second half from the first, when joined.

Legend

Bases: BaseModel

The legend in force for a region.

printed instance-attribute

printed: bool

True when the page prints its own legend.

from_page class-attribute instance-attribute

from_page: int | None = None

The page whose legend this region uses when it prints none.

symbols class-attribute instance-attribute

symbols: tuple[SymbolKind, ...] = ()

The vocabulary entries the legend in force explains.

Level

Bases: BaseModel

One level after resolution: its grid of 10-foot cells, its areas, and what stands on them.

A level's cells are floor only where the level owns them. Another level's floor and the outside are rock here. The grid has one cell of rock around the floor on every side, and the map's north is its top, so osrlib's north is the map's north.

number class-attribute instance-attribute

number: int = Field(ge=1)

verdict instance-attribute

verdict: Literal['traced', 'fallback']

Whether the level was traced from its map or fell back to synthesis.

reason class-attribute instance-attribute

reason: str | None = None

Why the level fell back, or None when traced.

panels class-attribute instance-attribute

panels: tuple[LevelPanel, ...] = ()

cells class-attribute instance-attribute

cells: tuple[str, ...] = ()

edges class-attribute instance-attribute

edges: EdgeGrids | None = None

areas class-attribute instance-attribute

areas: dict[str, Area] = {}

Areas by key, the survey's canonical key.

keys class-attribute instance-attribute

keys: tuple[PlacedKey, ...] = ()

transitions class-attribute instance-attribute

transitions: tuple[Transition, ...] = ()

passages class-attribute instance-attribute

passages: tuple[Passage, ...] = ()

locked_doors class-attribute instance-attribute

locked_doors: tuple[str, ...] = ()

The doors the prose locks, each as an edge address x,y:side of a cell of the level. The edge keeps the letter the reading gives, so a secret door the prose locks stays s and is listed here. A door read as l under a legend with the locked-door symbol is locked by its letter and isn't listed.

flags class-attribute instance-attribute

flags: tuple[str, ...] = ()

What the report flags on this level, one entry each.

width property

width: int

The grid's width in cells, 0 for a level that fell back.

height property

height: int

The grid's height in cells, 0 for a level that fell back.

LevelPanel

Bases: BaseModel

Where a panel sits on a level's grid, and how it was turned to put its north at the top.

panel instance-attribute

panel: str

origin instance-attribute

origin: tuple[int, int]

The level cell where the turned panel's north-west cell sits. Panel cell c lands on origin + rotate_cell(c, (panel.width, panel.height), rotation), with the panel's width and height those of the converted panel when the panel is a 5-foot one.

rotation class-attribute instance-attribute

rotation: Rotation = 0

The clockwise quarter turn that put the panel's north at the top: rotation_for of its first region's compass.

Mark

Bases: BaseModel

A label-sized mark printed on the map: a key, a letter, or a label.

text instance-attribute

text: str

The mark's text as printed. Keys stacked one above the other are one mark whose text is their labels from top to bottom joined by /.

cell instance-attribute

cell: str

The cell under the mark's centre, or the edge's own cell when the mark sits on a door.

edge class-attribute instance-attribute

edge: str | None = None

The door edge the mark is printed on, when it sits on one. Its cell is cell.

leader_to class-attribute instance-attribute

leader_to: str | None = None

The cell a leader line from the mark ends on.

Outline

Bases: BaseModel

One level's outline on a panel, from the whole-map reading.

dungeon instance-attribute

dungeon: str

level class-attribute instance-attribute

level: int = Field(ge=1)

rects class-attribute instance-attribute

rects: tuple[tuple[int, int, int, int], ...] = Field(min_length=1)

Rectangles [x, y, width, height] in panel cells. Their union is the outline.

seeds class-attribute instance-attribute

seeds: tuple[str, ...] = Field(min_length=1)

Cells well inside the level, where the partition starts.

open_ground class-attribute instance-attribute

open_ground: tuple[tuple[int, int, int, int], ...] = ()

Rectangles of open ground inside the outline, like yards and courtyards.

Page

Bases: BaseModel

One page of the module, as the tracing stage's first step sees it.

number class-attribute instance-attribute

number: int = Field(ge=1)

The 1-based page number.

images class-attribute instance-attribute

images: tuple[PageImage, ...] = ()

The embedded images, in drawing order.

blanked class-attribute instance-attribute

blanked: bool = False

True when the blank_page_renders setting blanks this page.

spread_with class-attribute instance-attribute

spread_with: int | None = None

The other page of a two-page spread that one image spans. The spread image is listed in images on both pages, and each page names the other here.

PageImage

Bases: BaseModel

One image embedded on a page.

file instance-attribute

file: str

The image file, relative to the document's directory. The same file on two pages is one image printed twice.

hidden class-attribute instance-attribute

hidden: bool = False

True when one later image on the page covers more than half of this image's placement rectangle, the rule HIDDEN_COVERAGE in osrforge.tracing.images states, so the page doesn't show it.

Panel

Bases: BaseModel

The reading of one panel: a registered region, or two halves joined into one.

The grid is in the panel's own squares: 5-foot squares on a 5-foot map until convert_five_foot makes 10-foot cells of them.

id instance-attribute

id: str

regions class-attribute instance-attribute

regions: tuple[PanelRegion, ...] = Field(min_length=1)

The region, or the two joined halves, with their origins on this grid.

scale_feet instance-attribute

scale_feet: Literal[5, 10]

Feet per square of this grid.

cells instance-attribute

cells: tuple[str, ...]

One string per row, one cell letter per column.

edges instance-attribute

edges: EdgeGrids

partial class-attribute instance-attribute

partial: tuple[str, ...] = ()

Cells that are partly floor: between a quarter and three quarters, or on a diagonal.

cave class-attribute instance-attribute

cave: tuple[str, ...] = ()

Cells whose walls are drawn off the grid. An edge touching one is a cave edge.

marks class-attribute instance-attribute

marks: tuple[Mark, ...] = ()

outlines class-attribute instance-attribute

outlines: tuple[Outline, ...] = ()

symbols class-attribute instance-attribute

symbols: tuple[Symbol, ...] = ()

width property

width: int

The grid's width in squares.

height property

height: int

The grid's height in squares.

PanelRegion

Bases: BaseModel

Where a region's grid sits on its panel's grid.

region instance-attribute

region: str

The region id.

origin instance-attribute

origin: tuple[int, int]

The panel cell where the region's cell (0, 0) sits.

Passage

Bases: BaseModel

A connection the party walks through: across one side of a cell to a cell elsewhere.

cell instance-attribute

cell: str

side instance-attribute

side: Side

The side the party crosses. It's a wall in the level's edges.

to_level class-attribute instance-attribute

to_level: int = Field(ge=1)

The destination level of the same dungeon, or this level when the passage links two panels.

to_cell instance-attribute

to_cell: str

PlacedKey

Bases: BaseModel

A printed key or letter after placement.

label instance-attribute

label: str

The text as printed.

cell instance-attribute

cell: str

The cell the key stands on after any move.

area instance-attribute

area: str

The area the label belongs to, by key.

moved class-attribute instance-attribute

moved: bool = False

True when the rules moved the key off the cell it's printed on.

Region

Bases: BaseModel

One framed drawing on a map image, with its registration and its verdicts.

id instance-attribute

id: str

A name unique within the document.

page class-attribute instance-attribute

page: int = Field(ge=1)

The page the region is on.

image instance-attribute

image: str

The image file the region is cut from.

style instance-attribute

style: Style

The drawing style.

columns class-attribute instance-attribute

columns: int = Field(ge=0)

The region's width in squares of its own scale, 0 when it has no grid.

rows class-attribute instance-attribute

rows: int = Field(ge=0)

The region's height in squares of its own scale, 0 when it has no grid.

scale instance-attribute

scale: Scale

compass instance-attribute

compass: Compass

legend instance-attribute

legend: Legend

cut_off class-attribute instance-attribute

cut_off: tuple[PageSide, ...] = ()

The image edges that cut the drawing off.

verdict instance-attribute

verdict: Literal['registered', 'unregistered', 'refused']

Whether the grid was fitted, the fit failed, or the style or scale is refused.

reason class-attribute instance-attribute

reason: str | None = None

Why the region is unregistered or refused, or None when registered.

registration class-attribute instance-attribute

registration: Registration | None = None

The fitted grid, present exactly when the verdict is registered.

Registration

Bases: BaseModel

Where each grid corner of a region lies on its image.

corners has rows + 1 rows of columns + 1 points, each the pixel position [x, y] of a grid corner, so corner [j][i] is the north-west corner of cell (i, j). Points record the fit exactly whatever the fit's model is: pitch, shear, and drift are all in the corners.

corners instance-attribute

corners: tuple[tuple[tuple[float, float], ...], ...]

The grid corners in pixels, row by row from the north-west.

columns property

columns: int

The registered grid's width in cells.

rows property

rows: int

The registered grid's height in cells.

pixel

pixel(point: tuple[float, float]) -> tuple[float, float]

The image position of a grid point.

Parameters:

Name Type Description Default
point tuple[float, float]

Grid coordinates (gx, gy), where cell (i, j) spans gx in [i, i + 1] and gy in [j, j + 1]. Points outside the grid extend the nearest cell.

required

Returns:

Type Description
tuple[float, float]

The pixel position, interpolated within the corner cell.

Repair

Bases: BaseModel

One repair the checks made on a level.

dungeon instance-attribute

dungeon: str

level class-attribute instance-attribute

level: int = Field(ge=1)

fault instance-attribute

fault: Literal['area_unreachable', 'floor_cut_off', 'door_without_floor']

edges class-attribute instance-attribute

edges: tuple[DamagedEdge, ...] = ()

cells class-attribute instance-attribute

cells: tuple[str, ...] = ()

Cells the repair changed, in the level's coordinates: floor made rock, or rock made floor.

cost class-attribute instance-attribute

cost: float = Field(ge=0.0)

Scale

Bases: BaseModel

A region's printed scale.

feet class-attribute instance-attribute

feet: int | None = None

Feet per square: 5 or 10 for a scale the stage accepts, None for any other.

printed instance-attribute

printed: bool

True when the map prints its scale. When false, feet is the default, 10, and the report flags it.

text class-attribute instance-attribute

text: str | None = None

The printed scale statement, when there is one.

Symbol

Bases: BaseModel

One map symbol.

kind instance-attribute

kind: SymbolKind

cells class-attribute instance-attribute

cells: tuple[str, ...] = ()

The cells the symbol covers. A cave mouth has none.

edge class-attribute instance-attribute

edge: str | None = None

The edge a cave mouth stands on.

direction class-attribute instance-attribute

direction: Literal['up', 'down'] | None = None

The way the map shows stairs, a ladder, a trapdoor, or a chute going, or None when it shows none.

Transition

Bases: BaseModel

Stairs, a trapdoor, or a chute on a cell, and where it leads.

cell instance-attribute

cell: str

kind instance-attribute

kind: Literal['stairs_up', 'stairs_down', 'trapdoor', 'chute']

to_dungeon class-attribute instance-attribute

to_dungeon: str | None = None

The destination dungeon when it isn't this one.

to_level class-attribute instance-attribute

to_level: int = Field(ge=1)

to_cell instance-attribute

to_cell: str

canonical_form

canonical_form(truth: GeometryTruth) -> GeometryTruth

The document with every list that has no meaningful order put in north-then-west order.

Two resolutions are the same when their canonical forms are equal, with flags left out of the comparison. save_geometry_truth writes this form.

Parameters:

Name Type Description Default
truth GeometryTruth

Any document.

required

Returns:

Type Description
GeometryTruth

A document equal to truth apart from the order of its area cells,

GeometryTruth

placed keys, transitions, passages, marks, symbols, partly-floor and

GeometryTruth

cave cells, and flags. A level's lists are ordered on the level grid,

GeometryTruth

and a panel's through the panel's compass in force.

cell_key

cell_key(cell: tuple[int, int]) -> str

Format a cell address.

Parameters:

Name Type Description Default
cell tuple[int, int]

The (x, y) pair.

required

Returns:

Type Description
str

The address, "x,y".

edge_key

edge_key(cell: tuple[int, int], side: str) -> str

Format an edge address.

Parameters:

Name Type Description Default
cell tuple[int, int]

The (x, y) pair.

required
side str

The side of that cell.

required

Returns:

Type Description
str

The address, "x,y:side".

load_geometry_truth

load_geometry_truth(path: Path) -> GeometryTruth

Load and validate a geometry truth document.

Parameters:

Name Type Description Default
path Path

The JSON file.

required

Returns:

Type Description
GeometryTruth

The document. An unknown key or a reference to a missing region, panel,

GeometryTruth

level, or cell fails loudly.

order_key

order_key(point: tuple[float, float], north: PageSide = 'top') -> tuple[float, float]

The sort key that puts points in north-then-west order.

The item farther north comes first, and of two equally far north, the one farther west. On a level's grid north is the top, so the key is (y, x). For a point on a panel still in page orientation, north is where the panel's compass points on the page, and the key gives the order the point has once the panel is rotated onto the level: with north at the left edge of the page, west is the bottom.

Parameters:

Name Type Description Default
point tuple[float, float]

A grid point, such as a cell's centre (x + 0.5, y + 0.5) or an edge's midpoint.

required
north PageSide

The page side the panel's north points to, top on a level grid.

'top'

Returns:

Type Description
tuple[float, float]

A pair that sorts ascending into north-then-west order.

parse_cell

parse_cell(text: str) -> tuple[int, int]

Parse a cell address.

Parameters:

Name Type Description Default
text str

The address, "x,y".

required

Returns:

Type Description
tuple[int, int]

The (x, y) pair.

Raises:

Type Description
ValueError

If the text isn't two non-negative integers joined by a comma.

parse_edge

parse_edge(text: str) -> tuple[tuple[int, int], str]

Parse an edge address.

Parameters:

Name Type Description Default
text str

The address, "x,y:side".

required

Returns:

Type Description
tuple[tuple[int, int], str]

The cell and the side.

Raises:

Type Description
ValueError

If the text isn't a cell address, a colon, and a side name.

rotate_cell

rotate_cell(cell: tuple[int, int], size: tuple[int, int], rotation: int) -> tuple[int, int]

Where a panel cell lands after the panel turns clockwise.

Parameters:

Name Type Description Default
cell tuple[int, int]

The cell (x, y) in page orientation.

required
size tuple[int, int]

The panel's (width, height) in page orientation.

required
rotation int

The quarter turn in degrees.

required

Returns:

Type Description
tuple[int, int]

The cell on the turned panel, whose own cell (0, 0) is its north-west corner.

rotate_side

rotate_side(side: str, rotation: int) -> str

Which side of a cell a side becomes after a clockwise quarter turn.

Parameters:

Name Type Description Default
side str

A side name.

required
rotation int

The quarter turn in degrees.

required

Returns:

Type Description
str

The side name on the turned panel: north becomes east under 90.

rotated_size

rotated_size(size: tuple[int, int], rotation: int) -> tuple[int, int]

A panel's (width, height) after a clockwise quarter turn.

Parameters:

Name Type Description Default
size tuple[int, int]

The size in page orientation.

required
rotation int

The quarter turn in degrees.

required

Returns:

Type Description
tuple[int, int]

The size, swapped under 90 and 270.

rotation_for

rotation_for(north: PageSide) -> Rotation

The clockwise quarter turn that puts a page side at the top.

Parameters:

Name Type Description Default
north PageSide

The page side a panel's north points to.

required

Returns:

Type Description
Rotation

0 for top, 90 for left, 180 for bottom, 270 for right.

save_geometry_truth

save_geometry_truth(path: Path, truth: GeometryTruth) -> None

Write a geometry truth document as sorted, indented JSON with a trailing newline.

The same document always writes the same bytes, so committed answers can be compared byte for byte.

Parameters:

Name Type Description Default
path Path

The JSON file to write.

required
truth GeometryTruth

The document.

required