2 Commits

Author SHA1 Message Date
6be297d6f8 Added posts and elements and components 2025-11-19 14:13:55 +01:00
b88532e089 Added WBArticle 2025-11-19 09:35:58 +01:00
39 changed files with 488 additions and 3 deletions

View File

@@ -8,5 +8,13 @@
"endOfLine": "lf",
"bracketSpacing": true,
"bracketSameLine": false,
"arrowParens": "always"
"arrowParens": "always",
"overrides": [
{
"files": ["*.mdoc"],
"options": {
"parser": "markdown"
}
}
]
}

View File

@@ -0,0 +1,3 @@
name: Dave Damage
avatar: /images/authors/dave-damage/avatar.png
description: Nothing nice 2 say

View File

@@ -0,0 +1,3 @@
{
"name": "Homebrew"
}

View File

@@ -0,0 +1,3 @@
{
"name": "Was ist was?"
}

View File

@@ -0,0 +1,15 @@
{
"title": "Aether",
"summary": "Represents the immaterial, magic, divine essence and spirits.",
"path": "elements/essences",
"cover": {
"showInHeader": false
},
"meta": {
"publicationDate": "2025-11-19T13:55",
"tags": [],
"author": "dave-damage"
},
"category": "essence",
"glyph": "𐲯"
}

View File

@@ -0,0 +1,15 @@
{
"title": "Air",
"summary": "Represents struggle, warfare, and violence",
"path": "elements/essences",
"cover": {
"showInHeader": false
},
"meta": {
"publicationDate": "2025-11-19T13:56",
"tags": [],
"author": "dave-damage"
},
"category": "essence",
"glyph": "𐲝"
}

View File

@@ -0,0 +1,15 @@
{
"title": "Anima",
"summary": "Represents sentience, spark of life, and the material world",
"path": "elements/essences",
"cover": {
"showInHeader": false
},
"meta": {
"publicationDate": "2025-11-19T13:58",
"tags": [],
"author": "dave-damage"
},
"category": "essence",
"glyph": "𐲕"
}

View File

@@ -0,0 +1,14 @@
{
"title": "Bloom",
"path": "elements/primal-forces",
"cover": {
"showInHeader": false
},
"meta": {
"publicationDate": "2025-11-19T13:44",
"tags": [],
"author": "dave-damage"
},
"category": "primal-force",
"glyph": "𐠁"
}

View File

@@ -0,0 +1,14 @@
{
"title": "Earth",
"summary": "Represents nourishment, wealth, and survival",
"path": "elements/essences",
"cover": {
"showInHeader": false
},
"meta": {
"publicationDate": "2025-11-19T13:59",
"tags": []
},
"category": "essence",
"glyph": "𐲏"
}

View File

@@ -0,0 +1,15 @@
{
"title": "Fire",
"summary": "Represents knowledge, clarity, and skill",
"path": "elements/essences",
"cover": {
"showInHeader": false
},
"meta": {
"publicationDate": "2025-11-19T14:00",
"tags": [],
"author": "dave-damage"
},
"category": "essence",
"glyph": "𐲠"
}

View File

@@ -0,0 +1,14 @@
{
"title": "Order",
"path": "elements/primal-forces",
"cover": {
"showInHeader": false
},
"meta": {
"publicationDate": "2025-11-19T13:45",
"tags": [],
"author": "dave-damage"
},
"category": "primal-force",
"glyph": "𐠞"
}

View File

@@ -0,0 +1,14 @@
{
"title": "Void",
"path": "elements/primal-forces",
"cover": {
"showInHeader": false
},
"meta": {
"publicationDate": "2025-11-19T13:46",
"tags": [],
"author": "dave-damage"
},
"category": "primal-force",
"glyph": "𐠎"
}

View File

@@ -0,0 +1,15 @@
{
"title": "Water",
"summary": "Represents intuition, passion, and sensuality",
"path": "elements/essences",
"cover": {
"showInHeader": false
},
"meta": {
"publicationDate": "2025-11-19T14:01",
"tags": [],
"author": "dave-damage"
},
"category": "essence",
"glyph": "𐲜"
}

View File

@@ -0,0 +1,146 @@
---
title: Introduction
summary: A short overview of the Worldburner project and it's key features
cover:
src: /image/covers/worldburner/posts/introduction/cover/src.png
alt: Landscape dominated by an active volcano
showInHeader: true
meta:
publicationDate: 2025-11-19T09:42:00.000Z
tags:
- homebrew
- how-and-what
author: dave-damage
---
So what's this about then? »Worldburner« is a somewhat extremely opionated but system-agnostic worldbuilding tool, which provides rules and tables for creating the various moving parts of fantasy settings. It specifically focus on the cultural, mythological, and economical aspects of the fantasy genre and as such most parts of it deal with these conditions.
It is a collection of shameless theft and the ugly bastard child of other TTRPG supplements and computer games:
- Worlds without Numbers
- AD&D
- Glorantha
- Burning Wheel
- Neoclassical Geek Revival
- Imperator: Rome
- Crusader Kings III
- Europa Universalis V
- Old World
## Conventions
There are visual or conceptional ideas repeatedly used throughout this document to denote options:
### Granularity of rules
Although the Burner Rules use the same concepts and terms, they were designed to offer three different levels of complexity:
{% GranularityList %}
{% GranularityItem category="essential" %}
This is the quick-and-easy option. Forget the math this one's all about storytelling or letting the dice take the wheel. Perfect for when you want to keep things moving and build big worlds fast.
{% /GranularityItem %}
{% GranularityItem category="intermediate" %}
A set of rules that favours a balanced approach by combining a level of control with random elements. It presents a good compromise and is fitting for most worldbuilding needs.
{% /GranularityItem %}
{% GranularityItem category="extended" %}
Here's where things get crunchy. If you love numbers, tables, and rollling a lot of die, this one's for you. Expect to make detailed choices and do some heavy lifting with calculations.
{% /GranularityItem %}
{% /GranularityList %}
When we don't specify a granularity, expect *intermediate* to be used, and it should go without saying, that you can (and should) mix and match the various levels of granularity.
### Elements
Elements are part of a simple elementalist system, giving you an easy visual shortcut to express big ideas or concepts. Now whether this system is a stroke of genius, total nonsense or something in-between in the game world that's up to you to decide. Feel free to swap out the symbols and names to better match your style.
#### Primal Forces
These are the raw forces that keep the universe ticking. Think of them as the cosmic building blocks responsible for shaping reality, sparking life, and keeping the wheels of creation turning. Each one plays a role in how worlds change, form, and and sometimes break down.
{% table %}
- Glyph
- Name
- Description
- Opposite
---
- **𐠁**
- [Bloom](/worldburner/elements/primal-forces/bloom)
- Embodiment of change, growth, and unpredictability, where form and structure are continously reshaped
- *Order, Void*
---
- **𐠞**
- [Order](/worldburner/elements/primal-forces/order)
- Embodies stasis, permanence, and consistency. This is the force that gives form, function, and purpose.
- *Bloom, Void*
---
- **𐠎**
- Void
- [Void](/worldburner/elements/primal-forces/void)
- Encompasses decay, entropy, and dissolution, leading to transformation and renewal. It often serves as balance between *Bloom* and *Order*
- *Bloom, Order*
{% /table %}
#### Essences
The essences are the stuff the world's made of whether it's the dirt under your feet or the spark that keeps your spirit going. Everything you see, touch, or feel is built from these. They are what makes reality work, from solid earth to mystical forces.
{% table %}
- Glyph
- Name
- Description
- Opposite
---
- **𐲯**
- Aether
- Represents the immaterial, magic, divine essence and spirits.
- *Anima*
---
- **𐲝**
- Air
- Represents struggle, warfare, and violence
- *Earth*
---
- **𐲕**
- Anima
- Represents sentience, the spark of life, and the material world
- *Aether*
---
- 𐲏
- Earh
- Represents nourishment, wealth, and survival
- *Air*
---
- **𐲠**
- Fire
- Represents knowledge, clarity, and skill
- *Water*
---
- **𐲜**
- Water
- Represents intuition, passion, and sensuality
- *Fire*
{% /table %}
### Roleplaying Systems
Like we said earlier, »Worldburner« works with almost any system, but that doesn't mean, we won'T sneak in a few tweaks and rules for our favourite ones, right?
{% RPGSystem system="ngr" %}
Rules and Systems for the **Neoclassical Geek Revival** system
{% /RPGSystem %}
{% RPGSystem system="bol" %}
Rules and systems for the **Barbarians of Lemuria** system
{% /RPGSystem %}
{% RPGSystem system="bw" %}
Rules and systems for the **Burning Wheel** system
{% /RPGSystem %}
{% RPGSystem system="qw" %}
Rules and systems for the **Questworlds** system
{% /RPGSystem %}
{% RPGSystem system="sotdl" %}
Rules and systems for the **Shadow of the Daemon Lord/Weird Wizard** systems
{% /RPGSystem %}

View File

@@ -1,6 +1,7 @@
import { config } from '@keystatic/core';
import taxonomyCollections from '@/keystatic/collections/taxonomy';
import worldburnerCollections from '@/keystatic/collections/worldburner';
export default config({
storage: {
@@ -8,5 +9,6 @@ export default config({
},
collections: {
...taxonomyCollections,
...worldburnerCollections,
},
});

View File

@@ -10,6 +10,7 @@
"format": "prettier --write ."
},
"dependencies": {
"@keystar/ui": "^0.7.19",
"@keystatic/core": "^0.5.48",
"@keystatic/next": "^5.0.4",
"@markdoc/markdoc": "^0.5.4",

3
pnpm-lock.yaml generated
View File

@@ -8,6 +8,9 @@ importers:
.:
dependencies:
'@keystar/ui':
specifier: ^0.7.19
version: 0.7.19(next@16.0.1(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
'@keystatic/core':
specifier: ^0.5.48
version: 0.5.48(next@16.0.1(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@@ -0,0 +1,38 @@
import { collection, fields } from '@keystatic/core';
import { createArticleField } from '@/keystatic/fields/general/article';
import { wbComponents } from '@/keystatic/components/worldburner';
export default collection({
label: 'WB Elements',
slugField: 'title',
path: 'content/worldburner/elements/*',
format: {
data: 'json',
},
columns: ['glyph', 'title', 'category'],
schema: {
...createArticleField('worldburner/elements', 'elements', wbComponents),
category: fields.select({
label: 'Category',
options: [
{
label: 'Primal Force',
value: 'primal-force',
},
{
label: 'Essence',
value: 'essence',
},
{
label: 'Aspect',
value: 'aspect',
},
],
defaultValue: 'primal-force',
}),
glyph: fields.text({
label: 'Glyph',
}),
},
});

View File

@@ -0,0 +1,9 @@
import posts from '@/keystatic/collections/worldburner/posts';
import elements from '@/keystatic/collections/worldburner/elements';
const wbCollections = {
wb_posts: posts,
wb_elements: elements,
};
export default wbCollections;

View File

@@ -0,0 +1,17 @@
import { collection } from '@keystatic/core';
import { createArticleField } from '@/keystatic/fields/general/article';
import { wbComponents } from '@/keystatic/components/worldburner';
export default collection({
label: 'WB Posts',
slugField: 'title',
path: 'content/worldburner/posts/*',
format: {
contentField: 'content',
},
entryLayout: 'content',
schema: {
...createArticleField('worldburner/posts', '', wbComponents),
},
});

View File

@@ -0,0 +1,38 @@
import { repeating, wrapper } from '@keystatic/core/content-components';
import { fields } from '@keystatic/core';
import { blocksIcon } from '@keystar/ui/icon/icons/blocksIcon';
const granularityComponents = {
GranularityList: repeating({
label: 'Rules Granularity',
icon: blocksIcon,
children: ['GranularityItem'],
schema: {},
}),
GranularityItem: wrapper({
label: 'GranularityItem',
forSpecificLocations: true,
schema: {
category: fields.select({
label: 'Granularity',
options: [
{
label: 'Essential',
value: 'essential',
},
{
label: 'Intermediate',
value: 'intermediate',
},
{
label: 'Extended',
value: 'extended',
},
],
defaultValue: 'intermediate',
}),
},
}),
};
export default granularityComponents;

View File

@@ -0,0 +1,7 @@
import granularityComponents from './granularity';
import rpgsystemComponent from './rpgsystems';
export const wbComponents = {
...granularityComponents,
...rpgsystemComponent,
};

View File

@@ -0,0 +1,44 @@
import { fields } from '@keystatic/core';
import { wrapper } from '@keystatic/core/content-components';
import { dicesIcon } from '@keystar/ui/icon/icons/dicesIcon';
const rpgsystemComponent = {
RPGSystem: wrapper({
label: 'RPG System',
icon: dicesIcon,
schema: {
system: fields.select({
label: 'System',
options: [
{
label: 'Non-specific',
value: 'none',
},
{
label: 'Neoclassical Geek Revival',
value: 'ngr',
},
{
label: 'Barbarians of Lemuria',
value: 'bol',
},
{
label: 'The Burning Wheel',
value: 'bw',
},
{
label: 'Questworlds',
value: 'qw',
},
{
label: 'Shadow of the Daemon Lord',
value: 'sotdl',
},
],
defaultValue: 'none',
}),
},
}),
};
export default rpgsystemComponent;

View File

@@ -1,4 +1,5 @@
import { ComponentSchema, fields } from '@keystatic/core';
import type { ContentComponent } from '@keystatic/core/content-components';
import { createContentField } from './content';
import { createPathField } from './path';
@@ -6,7 +7,8 @@ import { createMetaField } from './meta';
export const createArticleField = (
imageSubfolder: string,
defaultPath: string = ''
defaultPath: string = '',
additionalComponents?: Record<string, ContentComponent>
) => ({
title: fields.slug({ name: { label: 'Title' } }),
summary: fields.text({
@@ -31,5 +33,5 @@ export const createArticleField = (
}),
}),
meta: createMetaField(),
content: createContentField(imageSubfolder),
content: createContentField(imageSubfolder, additionalComponents),
});

View File

@@ -0,0 +1,9 @@
import { cache, reader } from '@/lib/readers/base';
export const getWBElements = cache(async () =>
reader.collections['wb_elements'].all()
);
export const getWBElementsBySlug = cache(async (slug: string) =>
reader.collections['wb_elements'].read(slug)
);

View File

@@ -0,0 +1,9 @@
import { cache, reader } from '@/lib/readers/base';
export const getWBPosts = cache(async () =>
reader.collections['wb_posts'].all()
);
export const getWBPostsBySlug = cache(async (slug: string) =>
reader.collections['wb_posts'].read(slug)
);

3
src/lib/types/content.ts Normal file
View File

@@ -0,0 +1,3 @@
import { WBContent } from '@/lib/types/worldburner';
export type ArticleContent = WBContent;

View File

@@ -0,0 +1,9 @@
import { Entry } from '@keystatic/core/reader';
import keystaticConfig from '~/keystatic.config';
export type WBPost = Entry<(typeof keystaticConfig.collections)['wb_posts']>;
export type WBElement = Entry<
(typeof keystaticConfig.collections)['wb_elements']
>;
export type WBContent = WBPost | WBElement;