This file captures project context so a new agent can continue work without re-reading the full conversation history.
The Wedding is a custom Blood on the Clocktower script (25 characters: 11 homebrew + 14 official). The repo generates:
index.html— printable character sheet + First Night + Other Nights ST sheetsdata/script.json— BOTC Script Tool–compatible JSON
Design target: match the official Script Tool print layout (IBM Plex fonts, section headers with rules, 2-column character grid on print, icon + name + ability rows).
Repository: https://github.com/igelkotten90/botc_scripts
Local path (author machine): ~/Downloads/the-wedding-botc-script
| File | What it controls |
|---|---|
src/characters.mjs |
All 25 characters: names, teams, abilities, custom vs official, night wake indices, ST reminder text |
src/night-order.mjs |
FIRST_NIGHT_ORDER, OTHER_NIGHT_ORDER, NIGHT_LABELS, official-character night defaults |
styles/print.css |
Screen + print layout (A4 character sheet sizing, typography, night sheet styling) |
src/build.mjs |
HTML + script.json generation logic |
Do not edit index.html or data/script.json by hand — they are generated.
data/characters.csv was removed intentionally. There is no CSV import step.
cd ~/Downloads/the-wedding-botc-script # or clone from GitHub
# After character / night / CSS changes:
node src/build.mjs
# After custom icon source art changes:
node src/generate-icons.mjs # runs process-icons.py + fetch-official-icons.py
node src/build.mjsDependencies: Node.js (no npm packages), Python 3 + Pillow (pip3 install Pillow) for icon processing.
Print preview: Open index.html → Print / Save PDF. Settings: A4, no margins, backgrounds on, headers/footers off. Expected: 3 pages (character sheet, first night, other nights).
src/characters.mjs ──┐
src/night-order.mjs ─┼──► src/build.mjs ──► index.html
src/icons.mjs ───────┤ └──► data/script.json
styles/print.css ────┘
assets/icons/custom/ ◄── src/process-icons.py (from source PNGs)
assets/icons/official/ ◄── src/fetch-official-icons.py (CDN cache, recolored)
- Imports character roster and night orders from
.mjsmodules - Auto-fetches official icons on first build if cache missing (
assets/icons/official/virgin_g.pngmarker) - Renders character sheet in team sections (Townsfolk → Outsiders → Minions → Demons)
- Night sheets: every ID listed in
FIRST_NIGHT_ORDER/OTHER_NIGHT_ORDERis rendered, even if wake index is 0 — the order arrays are the ST-facing source of truth :reminder:in reminder strings becomes ⏺ in HTML- Title has no author line (
SCRIPT_META.authoris empty string)
- Custom (
custom: true): full JSON entry inscript.jsonwith local icon paths, night data, reminders - Official (
officialId: "..."): referenced by ID string inscript.json; night defaults inOFFICIAL_NIGHT_DEFAULTSinnight-order.mjsunless overridden incharacters.mjs
| ID | Name | Type |
|---|---|---|
emilybride |
Emily, The Bride | custom |
oskargroom |
Oskar, The Groom | custom — icon is a top hat (woodcut blue style) |
virgin |
Virgin | official |
priest |
Priest | custom |
chef |
Chef | official |
grandmother |
Grandmother | official |
bestman |
Best Man | custom |
maidofhonor |
Maid of Honor | custom — knows in-play Outsider and in-play Minion (or none) |
flowergirl |
Flowergirl | official |
photographer |
Photographer | custom |
cannibal |
Cannibal | official |
toastmaster |
Toastmaster | custom |
gossip |
Gossip | official |
| ID | Name | Type |
|---|---|---|
drunk |
Drunk | official |
weirduncle |
Weird Uncle | custom |
weddingcrasher |
Wedding Crasher | custom |
klutz |
Klutz | official |
| ID | Name | Type |
|---|---|---|
scarletwoman |
Scarlet Woman | official |
maliciousorganist |
Malicious Organist | custom |
badcaterer |
Bad Caterer | custom |
godfather |
Godfather | official |
| ID | Name | Type |
|---|---|---|
fanggu |
Fang Gu | official |
lleech |
Lleech | official (ID is lleech, display name Lleech) |
ojo |
Ojo | official |
imp |
Imp | official |
Full ability text and ST reminders: see src/characters.mjs.
These arrays in src/night-order.mjs define the printed order exactly.
Dusk → Minion Info → Demon Info → Wedding Crasher → Lleech → Bad Caterer → Godfather → Maid of Honor → Chef → Emily, The Bride → Oskar, The Groom → Best Man → Grandmother → Dawn
Dusk → Wedding Crasher → Bad Caterer → Scarlet Woman → Imp → Fang Gu → Ojo → Lleech → Godfather → Gossip → Weird Uncle → Grandmother → Malicious Organist → Priest → Emily, The Bride → Oskar, The Groom → Best Man → Flowergirl → Photographer → Dawn
Special labels (dusk, dawn, minioninfo, demoninfo) map via NIGHT_LABELS.
- Good (Townsfolk + Outsiders): blue
_gicons - Evil (Minions + Demons): red
_eicons - Each custom role has both
_gand_ePNG (flip variant for script.json)
| Character | Symbol |
|---|---|
| Emily, The Bride | Bridal bouquet |
| Oskar, The Groom | Top hat |
| Priest | Lit candle |
| Best Man | Open ring box |
| Maid of Honor | Ribbon sash bow |
| Photographer | Vintage camera |
| Toastmaster | Champagne flute |
| Weird Uncle | Spilled wine glass |
| Wedding Crasher | Party hat |
| Malicious Organist | Organ pipes |
| Bad Caterer | Serving cloche with skull |
Style: woodcut/stamped illustration, transparent background, no circular token border.
src/process-icons.py reads source PNGs from a hardcoded Cursor project path:
/Users/annika.dukek/.cursor/projects/.../assets/{char_id}_g.png
If that folder is missing, it falls back to existing files in assets/icons/custom/. Consider fixing this to use a repo-local assets/icons/source/ directory for portability.
Regenerate flow: place/replace source {id}_g.png → node src/generate-icons.mjs.
Official icons are downloaded from release.botc.app, normalized, and cached in assets/icons/official/.
- No player-count setup table on the character sheet (removed per user request)
- No author name on title
- Character sheet styled like official Script Tool (gray section headers with horizontal rules,
.itemrows) - Page 1: character sheet must fit exactly one A4 page (
210mm × 297mmbox, flex layout withjustify-content: space-betweenon team sections, 9.5px print root font, 2-column grid per team) - Footer on page 1: copyright bottom-left,
* Not the first nightbottom-right (print only) - Pages 2–3: First Night and Other Nights sheets (
page-break-before: always) - Screen view is a scroll preview; use print preview for accurate layout
Reference implementation studied: GarethOates/botc-script-tool styles.scss.
- Edit entry in
src/characters.mjs - Update
firstNightReminder/otherNightReminderif ST text should change node src/build.mjs
- Edit
FIRST_NIGHT_ORDER/OTHER_NIGHT_ORDERinsrc/night-order.mjs(use characteridstrings) node src/build.mjs
- Add full entry to
CHARACTERSinsrc/characters.mjs - Add source PNG, run icon pipeline, add to
TEAMSinprocess-icons.py - Insert into night order arrays if needed
node src/build.mjs
git add -A
git commit -m "Describe change"
git pushRemote: git@github.com:igelkotten90/botc_scripts.git, branch main.
- No npm/package.json — plain Node + Python scripts only
assets/icons/reference/contains download references; not used in build output- Script Tool import: run
node src/build.mjs, pastedata/script.jsonat script.bloodontheclocktower.com. Custom icons in JSON use GitHub raw URLs (GITHUB_RAW_BASEinsrc/icons.mjs); push tomainbefore importing so icons load. Localindex.htmlstill uses relative paths. process-icons.pySOURCE path is machine-specific (see Icons section)- Grandmother appears on Other Nights sheet per user order but has no other-night ST reminder (name-only row)
| Skill | When to use |
|---|---|
handoff |
End of session — refresh this file if major context changed |
create-rule |
User wants persistent Cursor rules for this repo |
write-a-skill |
Add repo-specific build/print workflow skill |
split-to-prs |
If repo grows to multiple scripts and needs PR splitting |
Full prior chat (design iterations, icon regeneration, layout tuning) is in the Cursor agent transcript if the user still has it. Search keywords: The Wedding, character sheet, A4, oskargroom, maidofhonor, night-order.