Initialize DELVE HOLD project

This commit is contained in:
Meta Vens 2026-08-25 17:56:31 +02:00
commit 755143528b
13 changed files with 339 additions and 0 deletions

5
.gitattributes vendored Normal file
View file

@ -0,0 +1,5 @@
* text=auto
*.ps1 text eol=crlf
*.yml text eol=lf
*.yaml text eol=lf

24
.github/workflows/deploy-quartz.yml vendored Normal file
View file

@ -0,0 +1,24 @@
name: Deploy Quartz
on:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: true
jobs:
deploy:
uses: GameCult/GameCult-Quartz/.github/workflows/quartz-pages.yml@main
with:
content-dir: Delvehold
overlay-dir: site
output-dir: quartz-site/public

13
.gitignore vendored Normal file
View file

@ -0,0 +1,13 @@
# Generated Quartz state
/.quartz-build/
/quartz-site/public/
/.npm-cache/
/.tools/
# Local editor and OS state
.DS_Store
Thumbs.db
.obsidian/workspace.json
.obsidian/workspace-mobile.json
.trash/

24
AGENTS.md Normal file
View file

@ -0,0 +1,24 @@
# Delvehold Agent Notes
## Project identity
- The title is **DELVE/HOLD** in presentation and `Delvehold` in repository, package, and path names.
- `DELVE` and `HOLD` are two projections of one persistent world, not separate games joined by a synchronization layer.
- Client presentation may weight either half of the title according to the active mode. The canonical project name does not change.
## Architecture
- CultMesh is the typed world-state and capability surface.
- Shared state belongs to world organs, not the Unity client, browser client, or documentation site.
- Unity projects dungeon expeditions. The browser projects cozy workshop and neighborhood play through Eve/CultUI.
- Commands cross authority boundaries as typed intents and produce typed receipts.
- Workshop shards are nodes in a persistent neighborhood graph. Shared edges require explicit ownership, capacity, provenance, and consent.
- Dungeon delving is part of a core's lifecycle. Industrial systems must remain legible to dungeon instinct as bounded, contested delving rather than direct tissue damage.
## Documentation
- `Delvehold/` contains the published Markdown source.
- `site/` contains only Delvehold-specific Quartz configuration and presentation.
- Shared Quartz machinery remains owned by `GameCult/GameCult-Quartz`; do not vendor it here.
- Generated output under `quartz-site/public/` is disposable and must not become source truth.

View file

@ -0,0 +1,23 @@
---
title: Authority map
description: The owners and projections of the first persistent-world slice.
---
# Authority map
## World authority
A world organ owns persistent workshops, graph edges, dungeon lifecycle pressure, contracts, expeditions, resources, and consequences. It accepts typed intents and emits typed receipts plus updated documents through CultMesh.
## Client projections
The Unity client projects an expedition. It may predict movement and presentation, but it does not own shared economic or dungeon-lifecycle truth.
The browser client projects the workshop and relevant neighborhood subgraph through Eve/CultUI. It does not own the world simply because its incremental simulation can continue while a player is absent.
## Contract handoff
A delving contract is the first shared object joining both experiences. Its canonical state includes issuer, objective, offered equipment, reward allocation, target region, accepted expedition, lifecycle status, and outcome references.
Factory and delver interfaces expose different projections of that state. Incomplete knowledge belongs in the projection; canonical state must not be falsified to manufacture mystery.

View file

@ -0,0 +1,30 @@
---
title: Core loop
description: The smallest exchange that proves DELVE and HOLD inhabit one world.
---
# Core loop
The first playable world contains one workshop, one dungeon core, one contract type, one expedition party, one extracted material, and one persistent expedition history.
## HOLD
The player begins with one mage doing useful work manually:
1. scry a viable dungeon entrance;
2. prepare supplies;
3. equip and publish a delving contract;
4. process returned material;
5. encode a repeated manual action into a rune;
6. compose runes into spell-engine automation.
Automation solves real inconveniences. It changes the mage from practitioner to systems engineer without making the original practice irrelevant.
## DELVE
Delvers accept a funded contract, enter a generated dungeon, encounter its current ecological response, and decide how much promised extraction is worth attempting. Their success, retreat, discoveries, injuries, and losses become persistent world events.
## The return stroke
A factory decision must alter a later expedition. The expedition's lived outcome must return through CultMesh and materially alter factory play. Both paths use typed intents, receipts, and world-owned state rather than client-owned synchronization.

View file

@ -0,0 +1,19 @@
---
title: World graph
description: Private workshop shards joined by scarce, social infrastructure.
---
# World graph
Every factory player owns a private workshop shard. Shards are arranged as nodes in a persistent neighborhood graph rather than literal adjacent rooms in one Euclidean factory.
The graph contains three initial node kinds:
- **workshops**, owned by individual players;
- **commons**, such as mana wells, exchanges, junctions, and guild facilities;
- **dungeon cores**, ecological actors shared by several workshops and delving populations.
Edges carry typed relationships such as mana, materials, contracts, research, dungeon pressure, or visiting workers. They expose capacity, ownership, permission, and provenance. A neighbor may create useful pressure but cannot silently acquire authority inside another player's shard.
Workshop space is scarce. Players specialize, trade, and share infrastructure because no shard can efficiently contain every production chain. Arbitrary neighborhood placement creates local cultures without flattening the world into one global auction house.

30
Delvehold/index.md Normal file
View file

@ -0,0 +1,30 @@
---
title: DELVE/HOLD
description: One persistent world, experienced from opposite sides of the contract.
---
# DELVE/HOLD
**DELVE/HOLD** is a small persistent-world experiment about the relationship between living dungeons, the people who enter them, and the workshops that turn their spoils into an industrial civilization.
The title changes emphasis with the player's perspective:
- **DELVE** is a cooperative dungeon RPG. Delvers accept contracts, enter procedurally generated cores, survive their ecologies, and bring home materials and knowledge.
- **HOLD** is a cozy social incremental. A single mage performs useful work by hand, encodes those actions into runes, and gradually grows a workshop into a magical factory shared with a graph of neighboring players.
They are not separate worlds. CultMesh carries one typed world into two deliberately incomplete projections.
## The old bargain
Dungeon cores need to be delved. Intrusion is part of their lifecycle: it exercises defenses, circulates mana and matter, exposes mature growths, and gives the core the contest through which it learns and renews itself.
Industrial extraction must therefore remain legible to dungeon instinct as traditional delving. A drill driven directly into a crystal chamber reads as injury. Delvers entering through recognized boundaries, accepting danger, overcoming resistance, taking bounded rewards, and leaving again satisfy the older metabolic grammar.
The factory cannot replace adventurers. It can equip, schedule, measure, abstract, and increasingly misunderstand them.
## Start here
- [[Design/Core Loop|Core loop]]
- [[Design/World Graph|World graph]]
- [[Design/Authority Map|Authority map]]

21
README.md Normal file
View file

@ -0,0 +1,21 @@
# DELVE/HOLD
`DELVE/HOLD` is a tiny persistent-world experiment built as a proving ground for CultMesh and the broader Aetheria architecture.
One shared world is projected through two modes:
- **DELVE** — a cooperative Unity RPG in which players enter procedurally generated living dungeons.
- **HOLD** — a cozy browser incremental about a mage's workshop growing into a networked magical factory.
The published project notes live in `Delvehold/`. The site is a thin consumer of the shared [`GameCult-Quartz`](https://github.com/GameCult/GameCult-Quartz) engine and deploys to [delvehold.gamecult.org](https://delvehold.gamecult.org).
## Local documentation build
The launcher expects `GameCult-Quartz` beside this repository or at `GAMECULT_QUARTZ_ROOT`.
```powershell
.\scripts\quartz\quartz.ps1 build
```
Generated output is written to `quartz-site/public/`.

32
scripts/quartz/quartz.ps1 Normal file
View file

@ -0,0 +1,32 @@
param(
[ValidateSet("build", "dev")]
[string]$Command = "dev"
)
$ErrorActionPreference = "Stop"
$repoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
$sharedQuartzRoot = if ($env:GAMECULT_QUARTZ_ROOT) {
$env:GAMECULT_QUARTZ_ROOT
} else {
Join-Path (Split-Path -Parent $repoRoot) "GameCult-Quartz"
}
$nodeCommand = Get-Command node -ErrorAction SilentlyContinue
if (-not $nodeCommand) {
throw "Node.js was not found. Install Node 22 or newer."
}
$env:npm_config_cache = Join-Path $repoRoot ".npm-cache"
$buildScript = Join-Path $sharedQuartzRoot "scripts\build-site.mjs"
if (-not (Test-Path $buildScript)) {
throw "GameCult-Quartz was not found at '$sharedQuartzRoot'. Clone it beside this repo or set GAMECULT_QUARTZ_ROOT."
}
& $nodeCommand.Source $buildScript $Command `
--siteRoot $repoRoot `
--overlayDir site `
--contentDir Delvehold `
--outputDir quartz-site/public

82
site/quartz.config.ts Normal file
View file

@ -0,0 +1,82 @@
import { QuartzConfig } from "./quartz/cfg"
import * as Plugin from "./quartz/plugins"
const config: QuartzConfig = {
configuration: {
pageTitle: "DELVE/HOLD",
pageTitleSuffix: "",
enableSPA: true,
enablePopovers: true,
analytics: null,
locale: "en-GB",
baseUrl: "delvehold.gamecult.org",
ignorePatterns: ["private", "templates", ".obsidian"],
defaultDateType: "modified",
theme: {
fontOrigin: "googleFonts",
cdnCaching: true,
typography: {
header: { name: "Montserrat", weights: [300, 400, 600, 700] },
title: { name: "Montserrat", weights: [300, 400, 600, 700] },
body: { name: "Ubuntu", weights: [300, 400, 500, 700], includeItalic: true },
code: "IBM Plex Mono",
},
colors: {
lightMode: {
light: "#f4eedf",
lightgray: "#ded3ba",
gray: "#857963",
darkgray: "#42392d",
dark: "#211b16",
secondary: "#9b4f2f",
tertiary: "#52705a",
highlight: "rgba(155, 79, 47, 0.14)",
textHighlight: "#d8a04b66",
},
darkMode: {
light: "#17130f",
lightgray: "#282117",
gray: "#877b65",
darkgray: "#d0c3a7",
dark: "#f3ead8",
secondary: "#e09555",
tertiary: "#8fbd91",
highlight: "rgba(224, 149, 85, 0.14)",
textHighlight: "#d8a04b55",
},
},
},
},
plugins: {
transformers: [
Plugin.FrontMatter(),
Plugin.CreatedModifiedDate({ priority: ["frontmatter", "git", "filesystem"] }),
Plugin.SyntaxHighlighting({
theme: { light: "github-light", dark: "github-dark" },
keepBackground: false,
}),
Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }),
Plugin.GitHubFlavoredMarkdown(),
Plugin.TableOfContents(),
Plugin.CrawlLinks({ markdownLinkResolution: "shortest" }),
Plugin.Description(),
Plugin.Latex({ renderEngine: "katex" }),
],
filters: [Plugin.RemoveDrafts()],
emitters: [
Plugin.AliasRedirects(),
Plugin.ComponentResources(),
Plugin.ContentPage(),
Plugin.FolderPage(),
Plugin.ContentIndex({ enableSiteMap: true, enableRSS: true }),
Plugin.Assets(),
Plugin.Static(),
Plugin.Favicon(),
Plugin.NotFoundPage(),
Plugin.CustomOgImages(),
],
},
}
export default config

27
site/quartz.layout.ts Normal file
View file

@ -0,0 +1,27 @@
import { PageLayout, SharedLayout } from "./quartz/cfg"
import * as Component from "./quartz/components"
export const sharedPageComponents: SharedLayout = {
head: Component.Head(),
header: [Component.PageTitle(), Component.Spacer(), Component.Search(), Component.Darkmode()],
afterBody: [],
footer: Component.Footer({
links: {
GameCult: "https://gamecult.org",
GitHub: "https://github.com/GameCult/Delvehold",
},
}),
}
export const defaultContentPageLayout: PageLayout = {
beforeBody: [Component.Breadcrumbs({ rootName: "DELVE/HOLD" }), Component.ArticleTitle(), Component.ContentMeta()],
left: [Component.DesktopOnly(Component.Explorer())],
right: [Component.DesktopOnly(Component.TableOfContents()), Component.Backlinks()],
}
export const defaultListPageLayout: PageLayout = {
beforeBody: [Component.Breadcrumbs({ rootName: "DELVE/HOLD" }), Component.ArticleTitle(), Component.ContentMeta()],
left: [Component.DesktopOnly(Component.Explorer())],
right: [],
}

View file

@ -0,0 +1,9 @@
body {
background-image:
radial-gradient(circle at 18% 8%, rgba(143, 189, 145, 0.08), transparent 30rem),
radial-gradient(circle at 82% 18%, rgba(224, 149, 85, 0.08), transparent 34rem);
}
.page-title a {
letter-spacing: 0.04em;
}