Initialize DELVE HOLD project
This commit is contained in:
commit
755143528b
13 changed files with 339 additions and 0 deletions
5
.gitattributes
vendored
Normal file
5
.gitattributes
vendored
Normal 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
24
.github/workflows/deploy-quartz.yml
vendored
Normal 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
13
.gitignore
vendored
Normal 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
24
AGENTS.md
Normal 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.
|
||||
|
||||
23
Delvehold/Design/Authority Map.md
Normal file
23
Delvehold/Design/Authority Map.md
Normal 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.
|
||||
|
||||
30
Delvehold/Design/Core Loop.md
Normal file
30
Delvehold/Design/Core Loop.md
Normal 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.
|
||||
|
||||
19
Delvehold/Design/World Graph.md
Normal file
19
Delvehold/Design/World Graph.md
Normal 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
30
Delvehold/index.md
Normal 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
21
README.md
Normal 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
32
scripts/quartz/quartz.ps1
Normal 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
82
site/quartz.config.ts
Normal 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
27
site/quartz.layout.ts
Normal 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: [],
|
||||
}
|
||||
|
||||
9
site/quartz/styles/custom.scss
Normal file
9
site/quartz/styles/custom.scss
Normal 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;
|
||||
}
|
||||
Loading…
Reference in a new issue