/*
Game Design Document
Typst Design Template
by Jengamon 2024-04-21
Usage (after import):
#show: gdd.with(
title: [Game Title Here],
authors: (
(
name: "Game Designer 1",
url: "https://homepage.example.com",
),
(
name: "Game Designer 2"
),
)
)
NOTE: If only 1 author, make sure it looks like
(
(
name: "Author"
), <-- this comma is v important
)
*/
#let gdd(
title: none,
authors: (),
doc,
) = {
set text(font: "Iosevka")
set par(justify: true)
show link: it => { text(fill: blue)[#it] }
let join_authors(authors) = authors.join(", ", last: " & ")
set document(
title: (title, " Game Design Doc").join(),
author: join_authors(authors.map(d => d.name)),
)
let started = state("started", false)
set page(
numbering: "(i)",
header: context {
let headers = query(heading.where(level: 1))
let current = counter(page).get()
let page-here-or-before(m) = counter(page).at(m.location()) <= current
let has-header = headers.any(page-here-or-before)
let title = smallcaps(title)
if not has-header or not started.get() {
align(right, title)
} else {
let body = headers.rev().find(page-here-or-before).body
title + h(1fr) + emph(body)
}
}
)
// Document title and authors
align(center)[
#text(24pt, strong(title)) \
#text(15pt, smallcaps([*Game Design Document*])) \
_#text(13pt, smallcaps[by #join_authors(authors.map(d => if "url" in d {link(d.url, d.name)} else {d.name}))])_
]
line(length: 100%)
show outline.entry.where(
level: 1
): it => {
v(12pt, weak: true)
strong(it)
}
outline(title: [], indent: auto, depth: 2)
started.update(true)
set heading(numbering: "1-1.")
set page(numbering: "1 / 1")
counter(page).update(1)
show heading.where(level: 1): it => {
pagebreak(weak: true)
it
}
doc
}
#let small(body) = text(4pt)[#body]
#let code_term(term) = box(fill: silver, outset: 2.5pt, raw(term))
#let ymd(year, month, day) = datetime(year: year, month: month, day: day).display()
#let dev_timeline_event(
completed: false,
name: "",
date: "",
desc
) = (
if completed {sym.checkmark} else [], date, name, desc
)
#let dev_timeline(..events) = {
show table.cell.where(y: 0): set text(weight: "bold")
let frame(stroke) = (x, y) => (
left: if x > 0 and y < 0 { 0pt } else { stroke },
right: stroke,
top: if y < 2 { stroke } else { 0pt },
bottom: stroke,
)
set table(
stroke: frame(rgb("21222c"))
)
table(
columns: (0.1fr, 0.3fr, 0.6fr, 1fr),
table.header[][Date][Event][Description],
..events
)
}