No description
  • TypeScript 83.9%
  • SCSS 7.4%
  • JavaScript 6.1%
  • CSS 2.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-05-31 12:02:54 +01:00
.github/workflows Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
quartz Use Sai package for Ink embeds 2026-05-27 14:34:43 +01:00
scripts Extract shared graph SPA 2026-05-24 03:01:36 +01:00
.gitattributes Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
.node-version Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
.npmrc Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
.prettierignore Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
.prettierrc Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
AGENTS.md Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
CODE_OF_CONDUCT.md Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
Dockerfile Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
globals.d.ts Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
index.d.ts Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
LICENSE.txt Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
package-lock.json Pin Sai graph target normalization 2026-05-31 12:02:54 +01:00
package.json Pin Sai graph target normalization 2026-05-31 12:02:54 +01:00
quartz.config.ts Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
quartz.layout.ts Extract shared GameCult-Quartz engine 2026-05-01 09:32:29 +01:00
README.md Use Sai package for Ink embeds 2026-05-27 14:34:43 +01:00
tsconfig.json Extract shared graph SPA 2026-05-24 03:01:36 +01:00

GameCult-Quartz

Shared Quartz engine, reusable GitHub Pages workflow, and the minimum amount of ceremony needed to keep gamecult-site and AetheriaLore from turning into two copy-pasted maintenance problems with different logos.

What Lives Here

  • Shared Quartz source, dependencies, and build tooling
  • scripts/build-site.mjs for staging a site repo against the shared engine
  • scripts/build-graph-spa.mjs for building the shared fullscreen graph SPA into a consumer site
  • Reusable Pages workflow at .github/workflows/quartz-pages.yml
  • Generic defaults only

Site-specific content, mastheads, sidebars, render hooks, and custom chrome stay in the consumer repos as overlays.

Consumer Repo Shape

Each site repo is expected to provide:

  • a content root such as GameCult/ or Aetheria/
  • a site/ overlay containing:
    • quartz.config.ts
    • quartz.layout.ts
    • optional site-specific quartz/components/*
    • optional site-specific quartz/styles/custom.scss
    • optional quartz/static/*

The build script stages the shared engine into .quartz-build/engine, hardlinks the site overlay on top, and writes output to the consumer repo's quartz-site/public.

Local Use

Install dependencies once in this repo:

npm ci

Then from a consumer repo, use its launcher script, or call the shared builder directly:

node ..\\GameCult-Quartz\\scripts\\build-site.mjs build --siteRoot E:\\Projects\\gamecult-site --contentDir GameCult --overlayDir site --outputDir quartz-site/public

Fullscreen Graph SPA

Consumer sites can render the shared graph surface with Component.GameCultGraphSpaShell(...). The component only owns the mount point and asset tags; the consumer overlay decides where it appears.

Build the static SPA assets into the consumer repo when its graph payload changes:

node ..\\GameCult-Quartz\\scripts\\build-graph-spa.mjs --siteRoot E:\\Projects\\Mimir --outputDir static/epiphany-graph

The SPA source lives in quartz/graph-spa. It currently imports the shared EpiphanyGraphViewer from a sibling EpiphanyGraph checkout during local builds, so generated assets should be committed by consumer sites until that viewer is packaged as a normal dependency.

Shared Interactive Embeds

Plugin.InkEmbedder

Use Plugin.InkEmbedder() in a consumer site's emitter list to enable reusable Ink embeds. The plugin copies Sai's packaged browser assets from @gamecult/sai into the built site's /static/interactive/ directory and injects the player CSS and script.

Authors embed stories with plain HTML:

<div
  class="sai-player"
  data-ink-format="visual-novel"
  data-ink-story="/static/interactive/example/story.ink.json"
  data-visual-manifest="/static/interactive/example/visual-manifest.json"
  data-scene-label="Scene Name"
></div>

Supported formats:

  • data-ink-format="raven" or omitted: cheap interactive-fiction transcript layout for Raven Collective-style Ink.
  • data-ink-format="visual-novel": fixed scene view with bottom dialogue bar, speaker avatar, and choices/continue controls inside the dialogue surface.
  • data-ink-format="cinematic": slide/deck layout with background plates, captions, and optional references.

The legacy data-ink-mode attribute still works. Future sprite staging should extend Sai rather than inventing another site-local player. Existing .aetheria-ink-player containers are still initialised by Sai as a migration bridge, but new embeds should use .sai-player.

Shared Components

AutoIndexFolder

Use Component.AutoIndexFolder(...) when a consumer site needs a folder landing page to render a newest-first card index from Markdown files under that folder. The shared engine owns the repeated mechanics:

  • find pages under rootSlug
  • exclude the folder index page
  • honor a site-chosen hide frontmatter flag
  • sort by published, created, then modified date
  • derive author labels from author or authors
  • render card markup with a site-chosen class prefix
  • build year-grouped sidebar data with buildAutoIndexSidebarData

Consumer overlays still own the site-specific decision to use the component, the display copy, the class prefix, and the CSS. If an index needs custom editorial behavior that only one site understands, keep that behavior in the site overlay.

Design Rule

If a change only makes sense for one site, it does not belong in this repo. Put it in that site's overlay and leave the engine sober.